您对代表某人(例如客户,用户,客户,员工等)的表中的主键有何选择?我的第一选择是社会安全号码(SSN)。但是,由于隐私问题和不同的法规,不鼓励使用SSN。 SSN可以在人的一生中改变,因此这是另一个原因。
我认为精心挑选的自然主键的功能之一是避免重复。我不希望一个人在数据库中注册两次。某些代理或生成的主键无助于避免重复条目。解决这个问题的最佳方式是什么?
保证个人实体应用程序唯一性的最佳方法是什么?这可以在数据库级别使用主键或唯一性约束进行处理吗?
答案 0 :(得分:7)
我不知道您使用的是哪个数据库引擎,但(至少使用MySQL - 请参阅7.4.1. Make Your Data as Small as Possible),使用整数,尽可能短,通常被认为是最佳的用于表演和记忆要求。
我会为该主键使用整数auto_increment
。
这个想法是:
然后,在另一列上设置UNIQUE
索引 - 确定单一性的列 - 如果可能和/或必要的话。
编辑:以下是您可能感兴趣的其他几个问题/答案:
答案 1 :(得分:3)
如上所述,使用自动增量作为主键。但我不相信这是你真正的问题。
您真正的问题是如何避免重复输入。从理论上讲,没有办法 - 两个人可以在同一天出生,名字相同,住在同一个家庭,而且没有一个社会保险号可用于其中一个。 (一个人可能是访问该国的外国人)。
但是,全名,生日,地址和电话号码的组合通常足以避免重复。请注意,地址可能以不同方式输入,人们可能有多个电话号码,人们可能会选择省略其中间名或使用初始名称。这取决于避免重复条目的重要性,以及您的用户群有多大(从而发生冲突的可能性)。
当然,如果你能获得SSN / SIN,那么就用它来确定唯一性。
答案 2 :(得分:3)
您可以使用哪些属性?您的应用关注哪些?例如,在完全相同的位置,没有两个人可以在完全相同的秒内出生,但您可能无法以该准确度访问该数据!因此,您需要根据您打算进行建模的属性来确定哪些足以提供可接受的数据完整性级别。无论您选择什么,您都可以专注于选择的数据完整性方面(防止为同一个人插入多行)。
对于其他表中的Joins / Foreign Keys,最好使用代理键。
我已经开始考虑使用 Primary Key 这个词作为用词不当,或者至多令人困惑。任何密钥,无论您将其标记为主键,备用密钥,唯一密钥,还是唯一索引,仍然是一个Key,并要求表中的每一行都包含键中属性的唯一值。从这个意义上讲,所有键都是等效的。更重要的是(大多数),它们是自然键(取决于有意义的实域模型数据属性)还是代理(不依赖于实际数据属性)
其次,重要的是你使用密钥是什么..代理键是狭窄而简单的,永远不会改变(没有理由 - 它们没有任何意义)因此它们是连接或外键的更好选择在其他从属表中。
但是为了确保数据的完整性,并防止为同一个域实体插入多行,它们完全无用......为此你需要某种 Natural Key ,从你的数据中选择可用,以及您的应用程序为某些目的建模。
密钥不必是100%不可变的。例如,如果(例如),您使用姓名和电话号码以及出生日期,即使某人更改了姓名或电话号码,您也可以只更改表格中的值。只要没有其他行已经在其键属性中具有新值,您就可以了。
即使您选择的密钥仅在99.9%的情况下起作用(假设您不幸遇到两个姓名和电话号码相同的人,并且恰巧在同一天出生),那么,至少99.9您的数据的百分比将保证准确和一致 - 例如,您可以只为其生日添加时间以使其独一无二,或者为关键字添加一些其他属性以区分它们。只要您不必因为更改而在整个数据库中更新外键中的数据值,(因为您没有在其他地方使用此密钥作为FK),您不会遇到任何重大问题。
答案 3 :(得分:1)
使用自动生成的整数主键,然后对您认为应该唯一的任何内容添加唯一约束。但是SSN在现实世界中不是唯一的,所以在这个专栏上加上唯一性约束是个坏主意,除非你认为因为你的数据库不接受它而拒绝客户是一个很好的商业模式
答案 4 :(得分:1)
我更喜欢自然键,但表person
是丢失的情况。 SSN并不是唯一的,并不是每个人都有。
答案 5 :(得分:1)
我建议使用代理键。添加其他候选键所需的所有索引,但保持业务逻辑不在键中是我的建议。
答案 6 :(得分:1)
我更喜欢自然键,当他们可以信任时。
除非您经营银行或类似的东西,否则您的客户和用户没有理由为您提供有效的SSN,或者甚至必须拥有一个。因此,出于商业原因,在您概述的情况下,您被迫不信任SSN。类似的论证将适用于“人”的任何给定的自然键。
你别无选择,只能分配一个人工(读“代理”)键。它也可能是一个整数。确保它足够大整数,所以你不需要尽快扩展它。
答案 7 :(得分:0)
要添加到@Mark和@Pascal(自动增量整数是最好的选择) - SSN是有用的,应该正确建模。安全问题是应用程序逻辑的一部分。您可以将它们标准化为单独的表,并且可以通过提供日期发布的字段使它们唯一。
对于那些不同意“应用程序中的安全性”点的人来说,企业数据库将具有粒度ACL模型;所以这不是一个棘手的问题。