我想知道构建和存储ID的最佳做法是什么。几年前,一位教授告诉我使用社会安全号码作为例子,构建不良的身份证系统的危险性。特别是,因为SSN没有任何错误检测......不可能分辨出9位数字符串和有效SSN之间的区别。现在,政府机构需要使用Last Name + SSN或Birthday + SSN等内容来跟踪您的数据并确保其验证。另外,根据您的出生地点,您的社会安全号码可以预测。
现在我正在建立一个用户数据库......并且基于这个建议“userid mediumint auto_increment”将是不可接受的。特别是如果我打算使用此ID作为用户的主要标识。 (例如,如果我允许用户更改其用户名,那么用户名将比数字用户ID更难以跟踪...需要级联外键等等。)电子邮件更改,用户名可以更改,密码更改..但是用户ID应该永远保持不变。
显然,auto_increment仅适用于surrogate_keys。也就是说,只有当您已经拥有主要识别机制时,它才是有用的快捷方式,但它不应该用作数据的“先天标识符”。创建随机UUID看起来很有趣,但随机性让我失望。
所以我问:创建“主键”识别号码的最佳做法是什么?
答案 0 :(得分:7)
您将内部数据库功能与外部搜索条件混淆。
自动增量代理键对于内部应用程序使用很有用。永远不要将那些传递给用户。识别业务对象(无论是用户还是发票)都是使用有关对象的唯一信息(如SSN,CCN或DOB)完成的。根据需要使用尽可能多的信息来唯一标识对象。
我强烈建议,如果您必须向每位客户提供一些新发明的ID值,那么它不是您链接所有客户数据表的字段。
答案 1 :(得分:3)
最佳做法是使用自动增量整数。没有理由不应该将它用作“先天标识符”。它将提供外键和最快搜索中最紧凑的使用。几乎任何其他值都可能发生变化,并且不适合用作密钥。
答案 2 :(得分:1)
将SSN与自动递增的整数进行比较的是苹果和橙子。就个人而言,我避免使用GUID / UUID / UID,除非表中有这么多记录使得整数变得低效或不合理。
您很难找到真正的自然钥匙。今天看来独特的东西可能会根据业务要求/法律明天改变。
答案 3 :(得分:1)
根据我们在评论中的上述对话,我将此作为答案发布。您似乎认为为用户分配一个随机的唯一ID会为他们提供足够的安全性,您可以放弃正常的身份验证方法。
无论如何,我对用户表中安全数据和自动递增,基于整数的ID列之间的比较感到困惑。这两种类型的数据永远不应混杂在一起。您的信用卡公司不应将CCN用作数据库表中的主键,政府也不应将您的名称或SSN用作其数据库表中的主键。
为什么您(或任何人)使用 了解某些安全数据的用户进行身份验证?公司不再允许根据他们的SSN对用户进行身份验证,我知道我的信用卡公司不会根据我的CCN识别我(特别是因为我有多个,并且帐号上的卡号已经多次更改)。
即使您实现了UUID并生成了一些任意随机数,它仍然只是:数字。 Active Directory身份验证使用GUID作为其ID,但也要求用户提供用户名和密码。使用更大或更小的数据类型作为ID列并不意味着我可以洗手其他类型的身份验证或安全性。
答案 4 :(得分:0)
这就是设计解决的序列。创建一个每个插入可以原子增加的对象。在一些自动递增整数的DB中,在其他DB中它是一个序列对象,但想法是相同的,即创建一个不能冲突且唯一的密钥。
此外,作为ID的UUID很好,我之前因特殊原因使用过它。为什么随机性会“让你失望”?几乎没有发生冲突的可能性。
答案 5 :(得分:0)
在一天结束时,验证给定用户的标识符是否有效的方法是系统本身。即,您的系统是这些标识符的权威来源。 555-45-9999是否是有效的SSN?确切知道的唯一方法是让社会保障局查找并将其与声称拥有该号码的人的姓名相匹配。当然,我们可以使用SSN标识符方案来初步猜测它是否有效。但是,只有在他们的系统中查找才能确定。在高度分散的系统中需要检查数字,例如,您可能希望允许其他人生成您的系统所尊重的数字(例如,允许客户生成他们自己的跟踪号码的运输公司)。由于您的系统将以自动方式生成标识符,因此最适合您的校验位是以初步方式帮助验证数据输入或搜索。