V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
bbzt
V2EX  ›  程序员

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

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

    角色 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   ·   实用小工具   ·   3160 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 13:48 · PVG 21:48 · LAX 05:48 · JFK 08:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.