在设计表时,我养成了一个习惯,即有一个唯一的列,并将其作为主键。这可以通过三种方式实现,具体取决于需求:
自动递增的标识整数列。
唯一标识符(GUID)
短字符(x)或整数(或其他相对较小的数字类型)列,可作为行标识符列
数字3将用于相当小的查找,主要是读取表,这些表可能有一个唯一的静态长度字符串代码,或一个数值,如年或其他数字。
在大多数情况下,所有其他表都有一个自动递增的整数或唯一标识符主键。
问题:-)
我最近开始使用一些数据库,这些数据库没有一致的行标识符,而且主键目前聚集在各个列之间。一些例子:
datetime /字符
datetime /整数
datetime / varchar
字符/ nvarchar / nvarchar
这有有效的理由吗?我总是为这些情况定义一个标识符或唯一标识符列。
此外,还有许多根本没有主键的表。如果有的话,合理的理由是什么?
我试图理解为什么桌子被设计成这样,对我来说,它似乎是一个很大的混乱,但也许有很好的理由。
第三个问题在某种程度上帮助我解析答案:在使用多个列组成复合主键的情况下,与代理/人工键相比,这种方法是否有特定的优势?我主要考虑的是性能、维护、管理等方面。
从不同的字段中创建主键是没有问题的,这是一个自然键。
您可以使用Identity列(与候选字段上的唯一索引相关联)来创建代理键。
这是一个古老的讨论。在大多数情况下,我更喜欢代理键。
但是没有钥匙是没有理由的。
再保险:编辑
是的,关于这一点有很多争议:D
我没有看到任何明显的优势自然键,除了他们是自然的选择。你总是会用Name、SocialNumber或者类似的东西来思考,而不是idPerson。
代理键可以解决自然键存在的一些问题(例如传播更改)。
当你习惯了代理,它似乎更干净,更易于管理。
但最终,你会发现这只是一个品味或心态的问题。有些人用自然的钥匙能“更好地思考”,而其他人则不然。
自然键和人工键是数据库社区中的一种宗教争论——请参阅本文及其链接的其他文章。我既不赞成一直使用人工钥匙,也不赞成永远不使用。我会根据具体情况做出决定,例如:
美国各州:我会使用state_code(德克萨斯州的'TX'等),而不是德克萨斯州的state_id=1
员工:我通常会创建一个人工的employee_id,因为很难找到其他任何工作。SSN或同等的工作,但可能会有问题,如新加入谁还没有提供他/她的SSN。
员工薪资历史:(employee_id, start_date)。我不会创建一个人工的employee_salary_history_id。它能起到什么作用(除了“愚蠢的一致性”)
无论在哪里使用人工键,都应该始终在自然键上声明唯一的约束。例如,如果你必须使用state_id,但是你最好在state_code上声明一个唯一的约束,否则你最终肯定会得到:
state_id state_code state_name
137 TX Texas
... ... ...
249 TX Texas