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

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

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

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

问题:-)

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

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

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

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

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

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


当前回答

我们做了很多连接,复合主键已经成为性能的累赘。简单的int或long即使引入第二个候选键也可以解决许多问题,但是在一个字段上连接比在三个字段上连接要容易得多,也更容易理解。

其他回答

我遵循一些规则:

Primary keys should be as small as necessary. Prefer a numeric type because numeric types are stored in a much more compact format than character formats. This is because most primary keys will be foreign keys in another table as well as used in multiple indexes. The smaller your key, the smaller the index, the less pages in the cache you will use. Primary keys should never change. Updating a primary key should always be out of the question. This is because it is most likely to be used in multiple indexes and used as a foreign key. Updating a single primary key could cause of ripple effect of changes. Do NOT use "your problem primary key" as your logic model primary key. For example passport number, social security number, or employee contract number as these "natural keys" can change in real world situations. Make sure to add UNIQUE constraints for these where necessary to enforce consistency.

关于代理键和自然键,我参考了上面的规则。如果自然键很小并且永远不会改变,则可以将其用作主键。如果自然键很大或可能改变,我使用代理键。如果没有主键,我仍然会创建一个代理键,因为经验表明,您总是会向模式添加表,并希望在适当的位置放置一个主键。

如果你真的想阅读关于这个古老争论的所有内容,可以在Stack Overflow上搜索“自然键”。你应该能拿到几页结果。

我们做了很多连接,复合主键已经成为性能的累赘。简单的int或long即使引入第二个候选键也可以解决许多问题,但是在一个字段上连接比在三个字段上连接要容易得多,也更容易理解。

我也总是使用数字ID列。在oracle中,我使用数字(18,0)没有真正的原因高于数字(12,0)(或任何int而不是long),也许我只是不想担心在db中获得数十亿行!

我还包括了一个用于基本跟踪的已创建和修改的列(类型时间戳),在这里它似乎很有用。

我不介意在其他列的组合上设置唯一的约束,但我非常喜欢我的id、创建和修改的基线需求。

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

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