V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yodhcn
V2EX  ›  数据库

数据库中间表要不要用联合主键?

  •  1
     
  •   yodhcn · 220 天前 · 1818 次点击
    这是一个创建于 220 天前的主题,其中的信息可能已经有所发展或是发生改变。

    很多 ORM 的官方文档对于 many-to-many 关系,在其给出的例子中,中间表总是创建联合主键,例如:

    export const usersToGroups = pgTable(
      'users_to_groups',
      {
        userId: integer('user_id')
          .notNull()
          .references(() => users.id),
        groupId: integer('group_id')
          .notNull()
          .references(() => groups.id),
      },
      (t) => ({
        pk: primaryKey({ columns: [t.userId, t.groupId] }),
      }),
    );
    

    但这种习惯真的好吗?为了避免页分裂,不是应该推荐主键自增吗?

    各位建表时,中间表是以什么样的结构建的?对于支持 row_id 的数据库,主键是不是都没有必要了,只用一个联合 unique 索引就可以了?

    5 条回复    2024-05-16 11:50:49 +08:00
    yuanmomo
        1
    yuanmomo  
       220 天前 via iPhone
    我印象非业务主键,id 没有任何意义,就是自增的。然后其他键都是用的 unique 就够了。
    lt0136
        2
    lt0136  
       220 天前 via Android   ❤️ 3
    使用自增主键的话,为了查询,user_id+group_id 还是要建索引,更新记录的时候,这个索引也可能会页分裂。
    所以直接用联合主键就好了,用自增 id 多此一举
    wxf666
        3
    wxf666  
       220 天前
    你用自增主键,表本身是不会页分裂。

    但联合索引呢?你也严格按 (userId, groupId) 递增顺序,插入到表里吗?

    你的业务请求,挺有规律啊。。
    waytodelay
        4
    waytodelay  
       220 天前
    @lt0136 一个页 16K ,存索引分裂的情况是不是小一点,毕竟索引字段少占内存肯定也小啊?
    wxf666
        5
    wxf666  
       220 天前
    @waytodelay #4

    如果中间表字段少(比如就存 user_id 、group_id ),存索引不是还多一个自增字段吗?

    如果中间表字段多,存索引的话,会不会大概率经常回表,查其他字段呢?

    另外,索引相当于乱序插入了,页分裂肯定很频繁呀。。

    (除非你严格按照 user_id 、group_id 自增顺序插入。那你的业务,是没有回头客啥的吗?)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2648 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 11:14 · PVG 19:14 · LAX 03:14 · JFK 06:14
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.