创建数据库时,最好对每个 table 中的所有主键进行哈希处理吗?

When creating a database, is it good practice to hash all primary keys in each table?

无论 table 重要性如何,散列每个主键通常是好的做法,还是应该在该决定中考虑存储的数据类型?

[只是为了澄清问题] 我主要想知道在数据库安全的上下文中:使用 md5 散列对字符串加密主键 [就像在将主键输入数据库 table 之前使用 md5] 与使用自动增量加密一样好吗table 中可能非常大的数据库的 ID。 我目前正在开发一个应用程序,其中数据库的设计方式是每个 table 的主键在保存之前都使用 md5 加密,我想知道这是否是好的做法,或者只是不必要的。

正如@juergen 回复的那样,当在关系 table 上指定主键时,它具有关联的唯一索引 - 这就是数据库引擎强制执行唯一性的方式。

在幕后,例如,如果您有一个字符串 PK,那么数据库可能已经对其进行哈希处理以存储在内部数据结构中。即使没有被数据库引擎散列,您也可能在创建行时创建 CPU 开销。

此外,一个 table 中的 PK 将是另一个引用/子 table 中的 FK。您将需要在其他地方传播这些散列键。这也使你的数据在某种程度上'unreadable'。

这是一个糟糕的想法。除了@blispr 指出的之外,缩放是一个严重的问题。这也会在使用 UUID 和 GUID 时出现。

当键(PRIMARY KEY 或其他)为 'random'(如 UUID、哈希等)时,'next' 查找(对于 INSERTSELECT) 将在索引中的某个 'random' 位置 (and/or table)。当 table 很大时,这意味着所需的块不太可能在缓存中。在极端情况下(索引大小远大于缓存),缓存将被颠簸,每次读取或写入操作需要大约一次磁盘命中。在传统驱动器上,大约是每秒 100 次点击。这对于巨大的 tables 是不够的。

所以,你在某处读到"keep the PRIMARY KEY small? Do it when convenient; don't go out of your way. Take, for example, "国家代码”。国家少于 256 个,所以你可能会想使用 TINYINT UNSIGNED,它占用 1 个字节。我主张使用标准的 2 字母代码和 CHAR(2) CHARACTER SET ascii,它占用 2 个字节。更简单,更易读,而且不够大。

编辑

AUTO_INCREMENT 通常(但不总是)更好,因为它是 "chronological"。也就是说,'old' 条目具有较小的 ID,并且位于 table/index 的一端; 'new' 条目在另一端。在许多应用程序中,大多数 activity 与 'new' 条目一起使用,因此它们往往被缓存,而 'old' 条目则保留在磁盘上,不受干扰。

无论 my 行的 PRIMARY KEY 是 'RickJames' 还是 12345 或 '827ccb0eea8a706c4c34a16891f84e7b',我都看不出 "security"。不要混淆 "obscurity" 和 "security".

另一方面,如果我的 ID 是 12345,黑客可以很容易地假设 12346 和 12347 可能是有效 ID,并可以尝试获取它们的信息。如果 that 是你的顾虑,那么继续使用 12345,但也有一些随机值(不能从 12345 派生)作为辅助值来验证 id 没有被黑客入侵。将该值存储在数据库中以进行测试;你不需要索引它。 (因此,它不会影响我之前的评论。)此外,ids、安全代码等可能最好通过 cookie 传递,而不是 url。