在设计表时,我养成了一个习惯,即有一个唯一的列,并将其作为主键。这可以通过三种方式实现,具体取决于需求:

自动递增的标识整数列。 唯一标识符(GUID) 短字符(x)或整数(或其他相对较小的数字类型)列,可作为行标识符列

数字3将用于相当小的查找,主要是读取表,这些表可能有一个唯一的静态长度字符串代码,或一个数值,如年或其他数字。

在大多数情况下,所有其他表都有一个自动递增的整数或唯一标识符主键。

问题:-)

我最近开始使用一些数据库,这些数据库没有一致的行标识符,而且主键目前聚集在各个列之间。一些例子:

datetime /字符 datetime /整数 datetime / varchar 字符/ nvarchar / nvarchar

这有有效的理由吗?我总是为这些情况定义一个标识符或唯一标识符列。

此外,还有许多根本没有主键的表。如果有的话,合理的理由是什么?

我试图理解为什么桌子被设计成这样,对我来说,它似乎是一个很大的混乱,但也许有很好的理由。

第三个问题在某种程度上帮助我解析答案:在使用多个列组成复合主键的情况下,与代理/人工键相比,这种方法是否有特定的优势?我主要考虑的是性能、维护、管理等方面。


当前回答

所有表都应该有一个主键。否则,您所拥有的就是一个HEAP——在某些情况下,这可能就是您想要的(当数据通过服务代理复制到另一个数据库或表时,会产生大量插入负载)。

对于行数较少的查找表,可以使用3 CHAR代码作为主键,因为这比INT占用的空间更少,但性能差异可以忽略不计。除此之外,我总是使用INT,除非您有一个引用表,它可能有一个由相关表的外键组成的复合主键。

其他回答

您应该使用由多个字段组成的“复合”或“复合”主键。

这是一个完全可以接受的解决方案,点击这里了解更多信息:)

我寻找自然主键,并尽可能地使用它们。

如果找不到自然的键,我更喜欢GUID而不是INT++,因为SQL Server使用树,总是在树的末尾添加键是不好的。

在多对多耦合的表上,我使用外键的复合主键。

因为我很幸运使用SQL Server,我可以用分析器和查询分析器研究执行计划和统计数据,并很容易地发现我的键是如何执行的。

从不同的字段中创建主键是没有问题的,这是一个自然键。

您可以使用Identity列(与候选字段上的唯一索引相关联)来创建代理键。

这是一个古老的讨论。在大多数情况下,我更喜欢代理键。

但是没有钥匙是没有理由的。

再保险:编辑

是的,关于这一点有很多争议:D

我没有看到任何明显的优势自然键,除了他们是自然的选择。你总是会用Name、SocialNumber或者类似的东西来思考,而不是idPerson。

代理键可以解决自然键存在的一些问题(例如传播更改)。

当你习惯了代理,它似乎更干净,更易于管理。

但最终,你会发现这只是一个品味或心态的问题。有些人用自然的钥匙能“更好地思考”,而其他人则不然。

我避免使用自然键的原因很简单——人为错误。虽然通常可以使用自然的唯一标识符(SSN、VIN、Account Number等),但它们需要人工正确输入。如果您使用ssn作为主键,有人在数据输入期间调换了几个数字,并且没有立即发现错误,那么您将面临更改主键的问题。

我的主键都是由数据库程序在后台处理的,用户永远不会知道它们。

我将坦率地说明我对自然键的偏好——在可能的情况下使用它们,因为它们将使您的数据库管理工作更加容易。我在公司建立了一个标准,所有的表格都有以下列:

行ID (GUID) 创造者(字符串;有一个默认的当前用户名(SUSER_SNAME()在T-SQL)) 创建(DateTime) 时间戳

行ID在每个表上都有一个唯一的键,并且在任何情况下都是每行自动生成的(并且权限阻止任何人编辑它),并且合理地保证在所有表和数据库中是唯一的。如果任何ORM系统都需要一个ID密钥,那么可以使用这个密钥。

同时,如果可能的话,实际的PK是一个自然的关键。我的内部规则是这样的:

人-使用代理键,例如INT。如果它是内部的,那么Active Directory用户GUID是一个可以接受的选择 查找表(例如StatusCodes) -使用短的CHAR代码;它比int更容易记住,在许多情况下,纸张表格和用户也会使用它来简洁(例如,Status = "E"表示"过期","A"表示"已批准","NADIS"表示"样品中未检测到石棉")。 链接表- fk的组合(例如EventId, AttendeeId)

因此,理想情况下,您最终会得到一个自然的、人类可读的和难忘的PK,以及一个orm友好的每个表一个id的GUID。

警告:我维护的数据库倾向于100,000条记录,而不是数百万或数十亿条记录,所以如果您有使用大型系统的经验,这不利于我的建议,请随意忽略我!