好吧,既然您在问,这是一种很好的做法,但在少数情况下(不需要连接数据),它可能不是绝对需要的。但最大的问题是你永远不知道需求是否会改变,所以你现在真的想要一个,所以你不会在事后向 10m 记录表添加一个......
除了主键(顺便说一句,它可以跨越多个列)之外,我认为拥有一个作为单个字段的辅助候选键是一种很好的做法。这使得连接更容易。
首先是一些理论。您可能还记得 HS 或大学代数中对函数的定义是,y = f(x)
其中 f 是一个函数当且仅当对于每个 x 都恰好有一个 y。在这种情况下,在关系数学中,我们会说 yfunctionally dependent
在这种情况下位于 x 上。
您的数据也是如此。假设我们正在存储支票号码、支票帐号和金额。假设我们可能有多个支票账户,并且每个支票账户不允许有重复的支票号码,那么金额在功能上取决于 (account, check_number)。通常,您希望将功能上依赖于同一事物的数据存储在一起,而没有传递依赖。主键通常是您指定为主键的功能依赖项。然后,这会识别该行中的其余数据(因为它与该标识符相关联)。认为这是natural primary key.
在可能的情况下(即不使用 MySQL),我喜欢将主键声明为自然键,即使它跨越列。这有时会变得复杂,因为您可能有多个可互换的候选键。例如,考虑:
CREATE TABLE country (
id serial not null unique,
name text primary key,
short_name text not null unique
);
这个表真的可以有任何列作为主键。这三个都是完全可以接受的候选键。假设我们有一个国家记录(232,'United States','US')。这些字段中的每一个都唯一地标识记录,因此如果我们知道一个,我们就可以知道其他的。每一个都可以定义为主键。
我还建议使用第二个人工候选键,它只是用于连接连接的机器标识符。在上面的例子中 country.id 就是这样做的。这对于将其他记录链接到国家/地区表很有用。
需要候选键的一个例外可能是确实可能出现重复记录。例如,假设我们正在跟踪发票。我们可能会遇到这样一种情况,即有人为两个项目单独开具发票,两个项目中的每一个都显示一个。这些可能是相同的。在这种情况下,您可能想要添加一个人工主键,因为它允许您稍后将事物加入该记录。您现在可能不需要这样做,但将来可能!