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

数据库用多对多关系处理一对多关系,这样可以?

  •  
  •   sfree2005 · 2020-05-15 20:57:47 +08:00 · 2702 次点击
    这是一个创建于 1413 天前的主题,其中的信息可能已经有所发展或是发生改变。

    例如在订单表( orders ),里面有

    • 客户
    • 商家
    • 订单订阅者(subscriber,可以是会计,可以是库存管理员)

    他们都是 users 表里的用户

    关系需求:

    • 一个客户有多个订单( 1:n )
    • 一个商家有多个订单( 1:n )
    • 每个订单有多个订单订阅者( n:n )
    • 查询客户和商家的次数多余订单订阅者的次数

    但在数据库设计的时候技术部老大和我说只要有一个关系 就是 users 和 orders 是多对多关系。也就是说我在查询订单的唯一客户或者商家的时候还要跑去多对多的中间表格( pivot table )查,我知道技术上可行,但查询复杂度增大,性能降低, 这合理?

    orders 和 users 同时存在 1:n 和 n:n 关系很正常呀,老大说就只要 n:n, 我不服,在和他辩论中。我还是觉得要同时存在多种关系, 我错了?不对吧,这是数据库设计很基本的要求呀。

    10 条回复    2020-05-16 14:18:23 +08:00
    yeqizhang
        1
    yeqizhang  
       2020-05-15 21:13:11 +08:00 via Android   ❤️ 1
    赞同你的,一对多的没必要中间表,多对多的存进去就行。主要考虑中间表数据量会很大的问题
    notejava
        2
    notejava  
       2020-05-15 21:49:46 +08:00
    坚持自己的,一对多如果用中间表来表达很容易让人理解成多对多
    mmdsun
        3
    mmdsun  
       2020-05-16 00:10:31 +08:00 via Android
    说一下你们老大的加中间表的好处。虽然一对多加个字段就够了。但是后面关联多了 你那个表就得加很多外键字段。有遇到复杂业务半表字段全是关联字段。

    还有就是方便做保留数据的删除。用户删除了订单,可以只删除用户订单那个中间表。订单数据还能留一份。忘了问 OLTP 还是 OLAP 。拆出中间表也是一种垂直分割表的思想。
    还有就是你没办法保证这个业务永远是一对多吧。中间表后面完全不用担心突然变成多对多的业务。比如以后要加一起拼单,联合下单那种。到时候还是要改关系。当然中间表坏处也很多
    wushigejiajia01
        4
    wushigejiajia01  
       2020-05-16 00:54:21 +08:00 via Android
    加中间表扩展性好,但是查询不直接

    各有各的好吧,根据实际情况取舍就行了吧
    jzmws
        5
    jzmws  
       2020-05-16 00:55:03 +08:00
    中间表的坏处 加大了开发难度(多一个表,维护,查询都是几何级的复杂)
    好处 方便后期扩张,扩展超级灵活
    newtype0092
        6
    newtype0092  
       2020-05-16 01:00:13 +08:00
    我觉得你说得有一定道理,但你没说你和老大是怎么辩论的啊,他的理由是什么?
    sfree2005
        7
    sfree2005  
    OP
       2020-05-16 07:10:02 +08:00
    @mmdsun 但我觉得 如果外键字段多更需要一对多的,而不是多对多。 获得每个外键的信息的多对多查询更复杂,每个外键都更复杂一点,那更多的外键不是让查询变得更复杂, 性能更低了吗?

    业务没有让用户删除订单的功能,只能是归档。毕竟都是钱的东西,怎么也要多方留个底。

    的确不能保证某个外键永远一对多, 但 orders 表里用户相关的外键肯定有永远一对多的,例如 created_by 这样的外键。 我的意思是不能允许 orders 和 users 只能是多对多, 一对多的也可以同时存在。
    sfree2005
        8
    sfree2005  
    OP
       2020-05-16 07:13:15 +08:00
    @newtype0092 他的理由和楼上的说的差不多,就是扩展性好之类的,但我觉得有点设计过度,可以一对多的时候就一对多。而且有些关系永远是一对多的,例如 created_by, 多对多我感觉就是需要的时候再用。
    xuanbg
        9
    xuanbg  
       2020-05-16 08:57:19 +08:00
    订单里面没有客户的用户 id ?为啥还要用关系表去存?这里没明白你们是个什么操作
    leoskey
        10
    leoskey  
       2020-05-16 14:18:23 +08:00
    根据实际需求来吧,实在不行,推翻重写。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2621 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 15:51 · PVG 23:51 · LAX 08:51 · JFK 11:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.