一对多关系的数据库表,是用加字段实现还是增加记录行来实现? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
bbzt
V2EX    程序员

一对多关系的数据库表,是用加字段实现还是增加记录行来实现?

  •  
  •   bbzt 2018-06-06 13:36:00 +08:00 5272 次点击
    这是一个创建于 2741 天前的主题,其中的信息可能已经有所发展或是发生改变。

    角色 Character 与资源 Resource 的关系。

    管理员角色拥有查看订单、修改订单等等资源。

    那么把表设计成

    resource

    id | name | desc

    character

    id | name | resource_id_list | status

    还是通过插入多行记录的方式省略 resource_id_list (里面用英文逗号隔开资源 id 记录多个资源 id )这个字段?:

    resource

    id | name | desc

    character

    id | name | status

    19 条回复    2018-06-09 21:11:45 +08:00
    kslr
        1
    kslr  
       2018-06-06 13:49:33 +08:00
    再加一张表、表达之间的关系
    CFO
        2
    CFO  
       2018-06-06 13:52:00 +08:00 via Android
    来个关联表吧
    bbzt
        3
    bbzt  
    OP
       2018-06-06 13:58:43 +08:00
    @kslr @CFO

    加个表的理由是什么?
    silentstorm
        4
    silentstorm  
       2018-06-06 14:01:24 +08:00
    resource_character
    --------------------------------
    id | resource_id | character_id
    bbzt
        5
    bbzt  
    OP
       2018-06-06 14:07:44 +08:00
    @silentstorm

    加表的感觉就是增加了复杂度,对比加字段方式,本来查到角色就能直接知道他有哪些资源了,现在还要再查一次数据库;角色更新他资源的频率很低,每次更新都是直接覆盖替换,如果中间表的话还要先删再插入,代码量多出不少,能告诉我使用中间表的理由吗?
    bbzt
        6
    bbzt  
    OP
       2018-06-06 14:08:08 +08:00
    @silentstorm

    在什么场景下必须使用中间表?
    jianlu
        7
    jianlu  
       2018-06-06 14:11:24 +08:00
    你这个需求跟我现在这个权限控制模块好相似啊,我这边不同的角色具有不同的资源。区分领导啥的
    就是一张 role 角色表,role_id,role_name,status
    一张 resource 资源表,resource_id,resource_name, parent_id,order
    还有一张 role_resource 关联表,uuid,role_id,resource_id
    完全可以表达
    这样设计的好处就是改动方便,每次给一个角色新增资源,只需要在关联表里增加一行即可
    silentstorm
        8
    silentstorm  
       2018-06-06 14:11:55 +08:00
    @bbzt
    这个不算是中间表,只是关联表。SQL 只要用关联查询就行了,不用多次访问数据库。
    yulitian888
        9
    yulitian888  
       2018-06-06 14:12:33 +08:00
    “在什么场景下必须使用中间表?”
    这个问题很有意思
    应该反过来说,在什么场景下不使用中间表?这样问才对

    在关系型数据库里,逗号分隔这种事情,直接违反一范式了
    chenxytw
        10
    chenxytw  
       2018-06-06 14:13:33 +08:00
    如果你有要查询哪些角色有指定资源这种查询,最好还是用中间表.....
    不然你用字段,是需要解析这个字段的,或者用 like, 效率都没有用中间表+索引效率高
    imlinhanchao
        11
    imlinhanchao  
       2018-06-06 14:15:41 +08:00
    1. 这叫多对多;
    2. 多对多建议另外建表。
    remarrexxar
        12
    remarrexxar  
       2018-06-06 15:24:30 +08:00   1
    关联表比较好,这样的话无论是以左条件查右或者是以右条件查左都方便
    saulshao
        13
    saulshao  
       2018-06-06 15:44:30 +08:00
    通常用关联表合适,我挺奇怪怎么会认为表多了是坏事....
    并且我还发现有很多人持这种观点。
    zjsxwc
        14
    zjsxwc  
       2018-06-06 18:26:00 +08:00 via Android
    其实也是个演变的过程,你先用字段代替加关联表,等哪天碰到字段搞不定了(不如有快速右查的需求),加个关联表也很简单
    beginor
        15
    beginor  
       2018-06-06 20:18:14 +08:00 via Android
    PostgreSQL 的话可以用数组类型,不用加表
    lifespy
        16
    lifespy  
       2018-06-06 22:30:20 +08:00
    目前正在做一个多对多关系的业务,把人能绕死,还不能用主键关联。得用一个不唯一的外键去关联。。
    reself
        17
    reself  
       2018-06-06 22:34:08 +08:00 via Android
    无脑加表。加表更能应对需求变更。
    annielong
        18
    annielong  
       2018-06-07 09:10:33 +08:00
    一般加表,每个表数据最小化,
    pinews
        19
    pinews  
       2018-06-09 21:11:45 +08:00
    一般情况下加表,也可以两种方法一起用啊。
    理由么 增删改查方便点,比如可以加字段,权限生效时间,失效时间,上级批准人等,当然这些用一个字段 json 等格式存储也可以,这里并不是非 A 即 B 不可。
    比如这些年在网速越来越快的同时,花巨资搞 cdn,没有最快只有更快。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2531 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 11:16 PVG 19:16/a> LAX 03:16 JFK 06:16
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86