虽然我犯了这个罪,但在我看来,没有任何充分的理由让一张桌子没有身份字段的主键.
优点: - 无论您是否愿意,您现在可以唯一地识别表中您以前无法做到的每一行 - 如果没有主键,则无法执行sql复制
缺点: - 表格的每一行额外32位
例如,考虑需要在数据库的表中存储用户设置的情况.您有一个设置名称列和一个设置值列.不需要主键,但拥有整数标识列并将其用作主键似乎是您创建的任何表的最佳实践.
除了大小还有其他原因,每个表不应该只有一个整数标识字段吗?
当然,单数据库解决方案中的一个例子是,如果您有一个国家/地区表,使用ISO 3166-1-alpha-2国家/地区代码作为主键可能更有意义,因为这是一个国际标准,并使查询更具可读性(例如CountryCode = 'GB'
,相反CountryCode = 28
).类似的论点可以应用于ISO 4217货币代码.
在使用复制的SQL Server数据库解决方案中,UNIQUEIDENTIFIER
密钥更有意义,因为某些类型的复制需要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) );
这比使用代理" tag_id
"键有一些优点:
您可以确保标记是唯一的,而无需添加多余的UNIQUE
约束.
您可以防止两个不同的标记具有完全相同的拼写.
引用标记的从属表已经有标记文本; 他们不需要加入Tags
来获取文本.
每个表都应该有一个主键.它是一个整数,GUID还是"设置名称"列并不重要.类型取决于应用程序的要求.理想情况下,如果要将表连接到另一个表,最好使用GUID或整数作为主键.