V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
Visitor233
V2EX  ›  程序员

请教大佬们一个数据库的查询问题

  •  
  •   Visitor233 · 2020-06-03 18:11:35 +08:00 · 1776 次点击
    这是一个创建于 1668 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现开发过半的表结构

    表 A AId AName 表 B BId BName AId 表 C CID CName BId 表 D DID DName CID

    问题点

    例如:我现在查个 D 表数据,但需要额外显示 BName 的信息,就得 join 两次。 可实际上一个 select 得做四五次这样的 join,项目现有的查询一大半都是这种,重复度颇高, 而且来来回回就是那六张表。

    结语

    我今天和项目负责人说了,他也觉得这种设计整个查询麻烦,但他也想不出什么办法。 V 友们说说看,怎么整好些

    业务场景:学校。 这几个表就是查询,增删改很少 PS:想过 sql CTE,没写出来

    14 条回复    2020-06-04 18:36:10 +08:00
    aragakiyuii
        1
    aragakiyuii  
       2020-06-03 18:33:50 +08:00 via Android
    join ;查一个表再 byIds 去查另一个表;把 a,b,c 表的字段冗余到 d 中;改需求😂
    aguesuka
        2
    aguesuka  
       2020-06-03 18:56:32 +08:00
    create view GOD select * from a join b join c join d join d join e join f;

    我司现状
    luckyx
        3
    luckyx  
       2020-06-03 21:23:29 +08:00
    人生苦短, 我用 neo4j (不是
    akira
        4
    akira  
       2020-06-03 21:32:25 +08:00
    新建一个表,叫 ABCD, 字段是 aid,bid,cid,did,aname,bname,cname,dname.
    这个表的数据从 a b c d 定时或者实时更新进来。
    打完 收工
    PopRain
        5
    PopRain  
       2020-06-03 21:37:14 +08:00
    也不一定非要用数据库范式,现在存储根本不是问题,主表数据写入从表也是一个办法( NAME 写入时一起写到子表)
    JunoNin
        6
    JunoNin  
       2020-06-03 21:41:32 +08:00 via Android
    同五楼,多写入一次 name 到查询较多的表
    chanchan
        7
    chanchan  
       2020-06-03 21:53:38 +08:00
    是一对多的话就应该这样,在这种地方偷懒,肯定会在另外一个地方带来麻烦
    hsk9044
        8
    hsk9044  
       2020-06-04 09:40:09 +08:00
    其实这也根本不是问题, 就像 5 楼说的, 仅是增加几个字段就能解决的事情, 考虑的太复杂以后反而不好拓展. 单前提是热点字段才可以这样冗余, 如果整 B 表都是热点数据, 那你除了查询时做关联没比较好的办法. 或者就是业务层分开查询了
    taogen
        9
    taogen  
       2020-06-04 11:53:30 +08:00
    除了 1. denormalization (如 5 楼),2. 增加 cache table (如 4 楼),3. 还可以考虑添加索引 + SQL 优化:

    如下:

    Index:

    D 表 index(c_id, dname)

    C 表 index(b_id, cname)

    B 表 index(a_id, bname)

    SQL:

    select D.*, B2.bname from D

    join (select cid, cname, b_id from C) as C2 on D.c_id = C2.cid

    join (select bid, bname from B) as B2 on C2.b_id = B2.bid;
    Visitor233
        10
    Visitor233  
    OP
       2020-06-04 18:24:28 +08:00
    @aguesuka 视图也行
    Visitor233
        11
    Visitor233  
    OP
       2020-06-04 18:26:00 +08:00
    @akira 数据量多,你这法子可以考虑,我忘了补充,这 6 张表加起来的数据才 1000 来条
    Visitor233
        12
    Visitor233  
    OP
       2020-06-04 18:30:08 +08:00
    @PopRain 反范式这个好像可以考虑下,经常用但数据量少的 A B C 三表加起来也不过 100 条
    Visitor233
        13
    Visitor233  
    OP
       2020-06-04 18:32:27 +08:00
    @taogen 谢谢,一时还没看懂你的 sql 语句,不过我觉得会派上用场的
    akira
        14
    akira  
       2020-06-04 18:36:10 +08:00
    @Visitor233 其实吧,个人建议是,做数据库设计的时候,第一步就是把三范式给忘掉。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2797 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 07:43 · PVG 15:43 · LAX 23:43 · JFK 02:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.