在创建数据库时,最好是散列每个表中的所有主键吗?

时间:2015-12-22 17:22:45

标签: mysql database database-design primary-key database-security

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

[只是为了澄清这个问题] 我主要想知道在数据库安全性的上下文中:使用字符串上的md5哈希加密主键是一种很好的做法[如在输入数据库表的主键之前使用md5]与在表中使用自动增量ID对于可能非常大的数据库。 我目前正在开发一个应用程序,其中数据库的设计方式是每个表的主键在保存之前都使用md5进行加密,并且想知道这是不是很好,或者只是不必要。

2 个答案:

答案 0 :(得分:3)

这是糟糕的想法。除了@blispr指出的,缩放是一个严重的问题。使用UUID和GUID时也会显示此信息。

当某个键(PRIMARY KEY或其他)是“随机”(如UUID,哈希等)时,“下一个”查找(对于INSERTSELECT)将会在索引(和/或表)中的某个“随机”位置。当表很大时,这意味着必要的块不可能在缓存中。在极端情况下(索引大小远大于缓存),缓存将被破坏,每次读取或写入操作需要大约一次磁盘命中。在常规驱动器上,每秒100次点击。这对于巨大的桌子来说是不够的。

那么,你读到某个地方“保持PRIMARY KEY小吗?在方便的时候做;不要偏离你的方式。例如,”国家代码“。少于256个国家,所以你可能会想要使用TINYINT UNSIGNED,这需要1个字节。我主张使用标准的2字母代码和CHAR(2) CHARACTER SET ascii,这需要2个字节。更简单,更易读,而且不够大物质

修改

AUTO_INCREMENT通常(但并非总是)更好,因为它是“按时间顺序排列”。也就是说,“旧”条目具有小的ID并且位于表/索引的一端; “新”条目位于另一端。在许多应用程序中,大多数活动都使用“新”条目,因此它们倾向于缓存,而“旧”条目保留在磁盘上,不受干扰。

无论我的行的PRIMARY KEY是'RickJames'还是12345或'827ccb0eea8a706c4c34a16891f84e7b',我都没有看到“安全性”有太大差异。不要混淆“默默无闻”和“安全”。

另一方面,如果我的id是12345,黑客可以轻易地假设12346和12347可能是有效ID,并且可能尝试获取他们的信息。如果 是您关注的问题,那么继续使用12345,但也有一些随机值(不能从12345派生)作为验证id未被黑客攻击的辅助值。将该值存储在db中以进行测试;你不需要索引它。 (因此,它不会影响我之前的评论。)此外,ID,安全代码等可能最好通过cookie传递,而不是网址。

答案 1 :(得分:0)

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

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

此外,一个表中的PK将是另一个引用/子表中的FK。您需要在其他位置传播这些哈希键。这也会使您的数据难以理解'在某种程度上。