代码之家  ›  专栏  ›  技术社区  ›  Andreas Grech

SQL:对于许多表,是否需要自动递增的主键?

  •  14
  • Andreas Grech  · 技术社区  · 15 年前

    假设你有很多艺术家和粉丝之间的桌子。在设计表时,您是否按如下方式设计表:

    ArtistFans
        ArtistFanID (PK)
        ArtistID (FK)
        UserID (FK)
    
     (ArtistID and UserID will then be contrained with a Unique Constraint 
      to prevent duplicate data) 
    

    或者您构建时是否对两个相关字段使用复合pk:

    ArtistFans
        ArtistID (PK)
        UserID (PK)
    
    (The need for the separate unique constraint is removed because of the 
     compound PK)
    

    是否有任何优势(可能是索引?)使用以前的模式?

    7 回复  |  直到 10 年前
        1
  •  19
  •   gbn    12 年前
    ArtistFans
        ArtistID (PK)
        UserID (PK)
    

    使用自动增量pk在这里没有任何优势,即使父表具有这些优势。

    我还将在 (UserID, ArtistID) 同样:您将需要它,因为您将按两列查询表。

    自动编号/id列有它们的位置。在基于物理平台的正常化过程之后,您可以选择它们来改进某些东西。但不适用于链接表:如果你脑死的ORM坚持,那么改变ORM…

    编辑,OCT 2012

    需要注意的是,你仍然需要独一无二的 (用户ID,artistid) (ArtistID, UserID) 索引。添加自动增量只会占用不应该使用的更多空间(内存中,而不仅仅是磁盘上)

        2
  •  5
  •   Andomar    15 年前

    即使您创建了一个标识列,它也不必是主键。

    ArtistFans
        ArtistFanId
        ArtistId (PK)
        UserId (PK)
    

    标识列可用于将此关系与其他关系相关联。例如,如果有一个创建者表指定了创建艺术家用户关系的人,那么它可以在artistfanid上有一个外键,而不是复合artistid+userid主键。

    此外,还需要标识列(或大大改进某些ORM包的操作)。

        3
  •  5
  •   Isabelle Wedin    14 年前

    假设你已经是代孕钥匙的奉献者(你在一个很好的公司里),那么就有一个可以一直坚持下去的理由。

    有时被遗忘的一个关键点是关系本身可以有属性。通常说两件事是相关的还不够,你可能需要描述这种关系的性质。换句话说,一个关系表没有什么特别的地方可以说它只能有两列。

    如果这些表没有什么特别的地方,为什么不像其他表一样对待它并使用代理键呢?如果您最终不得不向表中添加属性,那么您将感谢幸运的表示层,您不必仅仅为了修改这些属性而传递复合键。

    我甚至不会称之为经验法则,更重要的是要考虑的事情。根据我的经验,一些很小的关系最终会携带额外的数据,基本上会成为他们自己的实体,相当于一个代理键。

    关键是在事后加上这些钥匙可能会很痛苦。附加列和索引的成本是否值得抢占这个头疼的问题,这取决于项目。

    至于我,一次被咬,两次害羞,“我从大门里找代理钥匙。

        4
  •  2
  •   Brian Campbell Dennis Williamson    15 年前

    我想不出任何理由使用你列出的第一张表格。复合主键很好,有一个单独的人工主键(加上您在外键上需要的唯一约束)只需要花费更多的时间来计算和存储空间。

        5
  •  1
  •   TheTXI    15 年前

    标准方法是使用复合主键。添加一个单独的autoincrement键只是创建一个使用您所拥有的内容已经存在的替代项。适当的数据库规范化模式会忽略使用自动增量。

        6
  •  0
  •   devio    15 年前

    有趣的是,所有的答案都支持变体2,所以我不得不反对并争辩变体1;)

    回答标题中的问题:不,你不需要。但是…

    每一个 表简化了数据模型,使您知道每个表总是有一个pk列。

    因此,从一个表到另一个表的每个关系(外键)总是由每个表的单个列组成。

    此外,如果您碰巧为窗体、列表、报表、日志记录等编写了一些应用程序框架,那么您只需要使用一个pk列来处理表,这就简化了框架的复杂性。

    另外,一个额外的id pk列在磁盘空间上不会花费太多(十亿记录加上表除外)。

    当然,我需要指出一个缺点:在祖父母-子女关系中,子女将丢失其祖父母信息并需要联接来检索它。

        7
  •  0
  •   Utku Özdemir    10 年前

    在我看来,纯SQL ID列是不必要的,不应该使用。但是对于像hibernate这样的ORM框架,使用复合键等管理多对多关系并不简单,特别是在join表有额外的列的情况下。

    因此,如果我要在数据库上使用ORM框架,我更喜欢将一个自动递增的ID列放在该表中,并将引用列的唯一约束放在一起。当然,如果需要的话,不是空约束。

    然后我像对待我项目中的其他表一样对待这个表。