我的数据库中有许多类似枚举的字段。只是一个整数,它是另一个表的FK,可能包含一个显示名称或者一些额外的数据。问题是,这个数字是非常无意义的,并且在代码中使用起来并不是很好。此外,如果您尝试合并来自不同数据库的某些枚举,或者移动数据,或者如果它是自动增量,您可能会遇到某些名称/密钥冲突...
使用短字符串有什么缺点吗?有点像常数吗?而用它作为主键呢?一个int通常是4个字节,我认为我真的不需要超过10个字符,所以varchar(10)会做...我不怀疑磁盘使用确实是个问题。
答案 0 :(得分:3)
我个人的方法是使用文本键来处理需要更改或删除代码的项目。如果给定的项目是用户应该能够添加或删除的内容,那么我会坚持使用代理键。这允许您的代码使用更容易阅读的文本值。一个例子可能是"状态" (例如开/关,获得/待定/出售)。总是存在根据状态而行为不同的代码,因此代码需要查找特定的状态值。那些"州"不是任何人都可以简单地添加或删除甚至重命名的东西。代码依赖于它们。因此,对于这些,我使用字符串PK。但是,类似于"类别"用户应该可以随意添加或删除那些,并且在这些情况下,代理键(与适当的业务键相结合)更好。
答案 1 :(得分:1)
这取决于密钥的不可变性。
例如,如果我们谈论使用邮政编码作为关键链接到美国各州的表格,那就没有害处。例如,任何人都不可能将加利福尼亚州的邮政编码从CA更改为其他内容,因此将其作为密钥存储将是完全合理的。
另一方面,订单状态代码之类的东西可能会随着时间而改变。当您第一次构建应用程序时,您可能会有一些状态(即“Taken”,“Shipped”,“Complete”)。但随着时间的推移,企业可能会决定需要添加新状态并且需要修改现有状态 - 例如,他们可能希望采用“已发货”状态,并将其分解为“OnPallet”,“InTransit” ,和“InCustoms”。如果发生这种情况并且您依赖“已发货”作为密钥,那么您将对Order
表中具有“已发货”密钥的所有行进行一系列更新,否则您最终会有一堆订单没有那么有意义的关键。另一方面,如果您使用无意义的数字键,则只需更新Order_Status
表以插入新值并更新一个“已发货”行。