代码之家  ›  专栏  ›  技术社区  ›  Michael Pryor

有没有什么好的理由让数据库表没有整数主键?

  •  4
  • Michael Pryor  · 技术社区  · 17 年前

    赞成的意见: -无论您是否愿意,现在都可以唯一地标识表中以前无法标识的每一行 -如果表上没有主键,则无法执行sql复制

    欺骗: -表的每一行额外增加32位

    例如,您需要在数据库中的表中存储用户设置的情况。设置名称有一列,设置值有一列。不需要主键,但是对于您创建的任何表来说,拥有一个整数标识列并将其用作主键似乎是一种最佳做法。

    除了大小之外,还有其他原因导致每个表不应该只有一个整数标识字段吗?

    11 回复  |  直到 17 年前
        1
  •  14
  •   Greg Beech    17 年前

    ISO 3166-1-alpha-2 country code 作为主键,因为这是一个国际标准,并使查询更具可读性(例如。 CountryCode = 'GB' 相对于 CountryCode = 28 ).类似的论点也适用于 ISO 4217 currency codes

    在使用复制的SQL Server数据库解决方案中 UNIQUEIDENTIFIER 键将更有意义,因为某些类型的复制需要guid(如果有多个源数据库,还可以更容易地避免键冲突!)。

        2
  •  10
  •   Bill Karwin    17 年前

    最明显的例子是 不

    CREATE TABLE Authorship (
      author_id INT NOT NULL,
      book_id   INT NOT NULL,
      PRIMARY KEY (author_id, book_id),
      FOREIGN KEY (author_id) REFERENCES Authors (author_id),
      FOREIGN KEY (book_id) REFERENCES Books (book_id)
    );
    

    在设计标签系统时,我也更喜欢自然键:

    CREATE TABLE Tags (
      tag VARCHAR(20) PRIMARY KEY
    );
    
    CREATE TABLE ArticlesTagged (
      article_id INT NOT NULL,
      tag        VARCHAR(20) NOT NULL,
      PRIMARY KEY (article_id, tag),
      FOREIGN KEY (article_id) REFERENCES Articles (article_id),
      FOREIGN KEY (tag) REFERENCES Tags (tag)
    );
    

    tag_id “关键:

    • UNIQUE
    • 可以防止两个不同的标记具有完全相同的拼写。
    • 引用标记的从属表已经具有标记文本;他们不需要加入 Tags 获取文本。
        3
  •  7
  •   Jesse Weigert    17 年前

    每个表都应该有一个主键。它是整数、GUID还是“设置名称”列并不重要。类型取决于应用程序的要求。理想情况下,如果要将表连接到另一个表,最好使用GUID或整数作为主键。

        4
  •  4
  •   BobbyShaftoe    17 年前

    是的,有很好的理由。您可以拥有语义上有意义的true键,而不是特定的标识键。另外,对于多表使用单独的自动递增主键也不是一个好主意。选择GUID可能有一些原因。

    也就是说,我通常对主键使用自动递增64位整数。

        5
  •  4
  •   Craig T    17 年前

    您的主键需要定义为如何将表链接到其他表。

        6
  •  2
  •   Koraktor    17 年前

    我不认为每个表都需要主键。有时您只想“连接”两个表的内容-通过 他们的

    你有一张像这样的桌子吗 users 还有一张桌子 groups users_groups 只有两个列(用户和组),其中用户和组相互连接。

        7
  •  2
  •   topchef    17 年前

    不将主键定义为标识的一个原因是将主键定义为guid或使用外部生成的值填充。

    一般来说,每个表本身有语义意义的表都应该有主键,而主键不应该有语义意义。实现多对多关系的联接表本身没有意义,因此它不需要这样的主键(通过其值已经有了主键)。

        8
  •  1
  •   MrTelly    17 年前

    要成为一个正确规范化的表,每一行应该只有一个可识别的键。许多表已经有了自然键,比如唯一的发票号。我同意这一点,尤其是在存储非常便宜的情况下,在所有表上都有一个自动编号/标识键几乎没有开销,但在本例中,哪个才是真正的键。

    另一个我个人不使用这种方法的领域,如果是参考数据,通常我们有一个描述和一个值

    Code, Description
    'L', 'Live'
    'O', 'Old'
    'P', 'Pending'
    

        9
  •  1
  •   Draemon    16 年前

    关键差异 (抱歉)在自然主键和代理主键之间,自然键的值包含信息,而代理键的值不包含信息。

    为什么这很重要?根据定义,一个自然主键是唯一的,但它的值是唯一的 不 通常保证保持不变。当它更改时,您必须在多个位置更新它。

    代理键的值没有实际意义,只是用于标识该行,因此它永远不需要更改。它是模型的一个特征,而不是域本身。

    因此,我要说的唯一不合适的地方是在关联表中,该表只包含引用其他表(大多数多对多关系)中的行的列。此表所携带的唯一信息是两行(或多行)之间的关联,并且它已经仅由代理键值组成。在这种情况下,我会选择一个复合主键。

        10
  •  0
  •   user210604 user210604    16 年前

    主键总是一个好主意。它允许非常快速和容易地连接表。它辅助可以读取系统表的外部工具进行连接,从而允许技能较低的人员通过拖放创建自己的查询。它还使引用完整性的实现变得轻而易举,这是一个好主意。

        11
  •  0
  •   Federico Razzoli    11 年前

    • 导入数据。这张桌子是临时的。插入和整个表扫描需要尽可能快。此外,我们需要接受重复记录。稍后我们将清理数据,但导入过程需要工作。
    • 数据库管理系统中的分析。识别一行是没有用的-如果我们需要这样做,它不是分析。我们只需要一个看起来像表的非关系、冗余、可怕的blob。我们将通过编写适当的SQL查询来构建摘要表或物化视图。

    请注意,这些案例有很好的理由不相关。但通常情况下,您的表应该是关系型的,所以。。。是的,他们需要一个主键。

    推荐文章