9

我想知道构建和存储 ID 的最佳实践是什么。几年前,一位教授以社会安全号码为例,向我讲述了构建不良的 ID 系统的危险。特别是,因为 SSN 没有任何错误检测功能……无法区分 9 位字符串和有效 SSN。现在政府机构需要诸如姓氏 + SSN 或生日 + SSN 之类的东西来跟踪您的数据并确保其验证。另外,根据您的出生地,您的社会安全号码在某种程度上是可以预测的。

现在我正在构建一个用户数据库......根据这个建议,“userid mediumint auto_increment”是不可接受的。特别是如果我打算将此 ID 用作用户的主要标识。(例如,如果我允许用​​户更改他们的用户名,那么用户名将比数字用户 ID 更难跟踪......需要级联外键等等。)电子邮件更改,用户名可以更改,密码更改.. . 但是用户标识应该永远保持不变。

显然,auto_increment 只为 surrogate_keys 设计。也就是说,仅当您已经拥有主要标识机制时,它才是有用的快捷方式,但不应将其用作数据的“固有标识符”。创建随机 UUID 看起来很有趣,但随机性让我很反感。

所以我问:创建“主键”标识号的最佳实践是什么?

4

7 回答 7

10

您将内部数据库功能与外部搜索条件混淆了。

自动增量代理键对于内部应用程序使用很有用。永远不要将这些传递给用户。识别业务对象,无论是用户还是发票,都是通过有关对象的唯一信息(如 SSN、CCN 或 DOB)来完成的。使用尽可能多的信息来唯一标识对象。

我强烈建议,如果您必须为每个客户提供一些新发明的 ID 值,那么它不是您链接所有客户数据表的字段。

于 2010-12-03T23:14:22.603 回答
3

最佳做法是使用自增整数。没有真正的理由不应该将其用作“先天标识符”。它将提供最紧凑的外键用法和最快的搜索。几乎任何其他值都可以更改并且不适合用作键。

于 2010-12-03T22:33:32.873 回答
1

根据我们上面评论中的对话,我将其发布为答案。似乎您相信为您的用户分配一个随机的、唯一的 ID 将为他们提供足够的安全性,您可以放弃正常的身份验证方法。

无论如何,我对您在用户表中安全数据和自动递增、基于整数的 ID 列之间的比较感到困惑。这两种类型的数据永远不应该混合在一起。您的信用卡公司不应将 CCN 用作数据库表中的主键,政府也不应将您的姓名或 SSN 用作其数据库表中的主键。

为什么您(或任何人)应该在了解某些安全数据的情况下对用户进行身份验证?不再允许公司根据他们的 SSN 对用户进行身份验证,而且我知道我的信用卡公司不会根据我的 CCN 来识别我(特别是因为我有不止一个,并且账户上的卡号已经更改了几次)。

即使您实现了一个 UUID 并生成了一些任意随机数,它仍然只是:一个数字。Active Directory 身份验证使用 GUID 作为其 ID,但还要求用户提供用户名和密码。使用更大或更小的数据类型作为 ID 列并不意味着我可以不用其他类型的身份验证或安全性。

于 2010-12-03T23:03:43.933 回答
1

将 SSN 与自动递增的整数进行比较是苹果和橘子。就个人而言,我避免使用 GUID/UUID/UID,除非表中的记录太多以至于使用整数变得低效或不合理。

很难找到真正的天然钥匙。今天看起来独特的东西明天可能会根据业务要求/法律而改变。

于 2010-12-03T22:39:36.740 回答
1

查看其他一些数据库如何公开 ID 可能会有所帮助。

Salesforce 使用前三个字符来确定对象,然后增加接下来的 12 个字符(区分大小写)。

因此 Salesforce 帐户从 001 开始,而 Salesforce 联系人从 003 开始​​。

因此,Salesforce 帐户可能看起来像 15 位区分大小写的 001000246abcABC。但是区分大小写的 ID 对 Excel 来说是个问题(排序、重复数据删除等),因此大多数人使用 Salesforce 的 18 位 ID,它们不区分大小写。有一个标准公式可以将它们从 15 转换为 18。

Stripe 在他们的 ID 前面加上 cus_ 代表客户或 pi_ 代表付款。因此,客户可能是 cus_abcdABCD123456(14 位),但付款可能是 pi_0123456789abcdeABCDE1234(24 位)。

联系人的 Xero ID 看起来像这样,abcd1234-ab12-12ab-9902-abcdef123456。

QuickBooks Online 做出了将其 ID 公开为公司特定增量整数的可疑决定。因此,您的发票将是 1、2、3 等。这也是一个问题,因为每个 QBO 公司的发票 ID 都为 1,如果您在一个地方有多个 QBO 公司的数据,数据库中的冲突将不可避免。

于 2021-08-22T17:28:23.273 回答
0

这就是设计要解决的序列。创建一个可以在每次插入时自动增加的对象。在一些自动递增整数的数据库中,在其他数据库中,它是一个序列对象,但想法是相同的,即创建一个不会冲突且唯一的键。

UUID 作为 ID 也很好,我以前因为特殊原因使用过它。为什么随机性会“让你失望”?几乎没有发生冲突的可能性。

于 2010-12-03T22:41:44.750 回答
0

归根结底,验证给​​定用户标识符是否有效的方法是系统本身。即,您的系统是这些标识符的权威来源。555-45-9999 是有效的 SSN 吗?唯一确定的方法是让社会保障局查找它并将其与声称拥有该号码的人的姓名相匹配。当然,我们可以使用 SSN 标识符方案来初步猜测它是否有效。但是,只有在他们的系统中查找才能确定地告诉我们。在高度分布式的系统中会出现对校验位的需求,例如,您可能希望允许其他人生成您的系统认可的号码(例如,让客户生成自己的跟踪号码的运输公司)。由于您的系统将以自动方式生成标识符,

于 2010-12-03T22:48:43.120 回答