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

Database 有没有什么好的理由让数据库表没有整数主键?,database,primary-key,Database,Primary Key,虽然我犯了这个罪,但在我看来,表没有标识字段主键是没有任何理由的 优点: -无论您是否愿意,现在都可以唯一地标识表中以前无法标识的每一行 -如果表上没有主键,则无法执行sql复制 缺点: -表的每一行额外增加32位 例如,考虑需要在数据库的表中存储用户设置的情况。设置名称有一列,设置值有一列。不需要主键,但是对于您创建的任何表来说,拥有一个整数标识列并将其用作主键似乎是一种最佳做法 除了大小之外,还有其他原因使每个表不应该只有一个整数标识字段吗?每个表都应该有一个主键。它是整数、GUID还是“设

虽然我犯了这个罪,但在我看来,表没有标识字段主键是没有任何理由的

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

缺点: -表的每一行额外增加32位

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


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

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

当然,单个数据库解决方案中的一个示例是,如果您有一个国家表,则使用作为主键可能更有意义,因为这是一个国际标准,并且使查询更具可读性(例如,
CountryCode='GB'
而不是
CountryCode=28
)。类似的参数可应用于


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

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


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

要成为一个正确规范化的表,每一行应该只有一个可识别的键。许多表已经有了自然键,比如一个唯一的发票号。我同意,特别是在存储非常便宜的情况下,使用自动编号的开销很小所有表上的er/identity键,但在本例中,哪个是真正的键

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

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

在这种情况下,将代码设为主键可确保不存在重复项,并且更易于阅读。

每个表都应该有一个主键。但它不需要是单个字段标识符。例如,在财务系统中,您可以将日记账表上的主键设为日记账ID和行号。这将产生一个唯一的组合每一行的日志ID(日志ID将是其自己表中的主键)


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

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

因此,您有一个类似于
users
的表和一个类似于
groups
(每个表都有主键)的表,还有第三个名为
users\u groups
的表,其中只有两个列(user和group),其中用户和组相互连接


例如,user=3且group=6的行将主键为3的用户链接到主键为6的组。

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


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

不需要代理键的表的最明显示例是多对多关系:

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)
);
这比使用代理“
标记id
”键有一些优势:

  • 您可以确保标记是唯一的,而无需添加多余的
    unique
    约束
  • 可以防止两个不同的标记具有完全相同的拼写
  • 引用标记的从属表已经具有标记文本;它们不需要加入到
    标记中来获取文本

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

自然主键和代理主键之间的关键区别(对不起)是,自然键的值包含信息,而代理键的值不包含信息

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

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

因此,我唯一认为代理键不合适的地方是在关联表中,该表只包含引用其他表(大多数多对多关系)中的行的列。该表唯一携带的信息是两(或更多)行之间的关联,并且