让我们说我有一个表,我想记录用户名。该表至少应包含两列:UserID
和Name
。通常情况下,我会看到人们在UserID
开启自动递增的主键,然后调用它。
然而,这对我来说似乎不对,键不应该是两列之间的复合键吗?因为我们不希望重复用户名。我们还希望保留UserID
,以便在名称更改时不会破坏对特定用户的现有引用。
我得到的是,似乎许多人默认使用带有PK的ID列,而不是确保密钥在其他列上强制执行唯一性。
说到这一点,我是否正确地指出一个表应该始终有一个用于引用的ID列,但使用复合主键同样重要?
答案 0 :(得分:6)
不,你不希望它作为复合键;这意味着组合是主键,因此您可以在同一ID上使用不同的名称,并在同一名称上使用不同的ID。
即:
UserID Name
-----------------
1 BobaFett
2 JarJar
1 JarJar
2 BobaFett
在没有任何其他限制的情况下,使主键成为(UserID, Name)
的组合将使以前的数据完全合法。
您的UserID
列是代理键;我将再次讨论使用代理键与自然键(你的Name
列是一个自然的候选键)的智慧,但如果你想保持你的设计现在的方式,那么您应该将UserID
作为主键,但也要在Name
上添加唯一约束。这样可以防止将同一名称附加到多个记录中。
答案 1 :(得分:1)
你应该将UserID作为密钥并命名为密钥,这与制作复合密钥不同(复合密钥表示一个密钥,而不是两个密钥)。
你是对的,有些人会天真或粗心地只为表格分配一个代理键,而不必考虑需要什么样的自然键。至少这是你可以从许多提倡代理人的人那里得到的印象,因为某种方式是替代自然键的“更好”。显然他们不是那种。代理人根本不可替代,因为他们完全不同。
重要的是,表应该具有数据完整性所需的密钥,以确保表准确地表示它所支持的业务规则。不要误以为一把钥匙总是你所需要的。
答案 2 :(得分:0)
如果您希望Name是唯一的,请为其创建单独的约束。这是一个不同的问题。有你的关键是两者的结合没有优势,只有缺点。这意味着可以重复UserID和Name。这是你想要的吗?
主键不仅用于唯一性。它对于索引性能也很有用。通常,你认为你的自然键将是独一无二的,但后来会发生变化。一个自然的关键可能是一个很好的举动。另一个可辩护的选择是使用GUID。为你的主键。
有很多关于using autonumber numeric or natural keys的好信息,以及多列密钥的优点。许多人(包括我)认为自动编号通常是最好的,尽管有good opinions the other way。当然,您应该了解这些因素,并最终在不同情况下使用不同的策略。