在ruby中使用散列向mysql文本字段字符串添加唯一索引

pjngdqdw  于 2021-06-21  发布在  Mysql
关注(0)|答案(2)|浏览(493)

我有一个rails应用程序,它的模型(表)有1500000条记录,文本字段大小从50到8000个字符不等。
我需要确保文本字段是唯一的。因为我不能在文本字段上使用mysql唯一索引,所以我的解决方案是将我的文本字段转换成一个哈希(使用digest::sha256.hexdigest),并将这个哈希保存到一个名为“body\u hash”的varchar字段中。然后在该字段上添加唯一索引。
问题:
我想知道rails是否有内置的解决方案而不是我重新发明的车轮-到目前为止,我找不到任何东西。)
在这里使用另一个哈希算法比digest::sha256.hexdigest更好吗?

mspsb9vt

mspsb9vt1#

您可能需要考虑在db本身中生成这个校验和/摘要。这将比在ruby中处理更快速地为现有数据填充值。
结合mysql的 CREATE_DIGEST 填充 body_digest 列:

CREATE_DIGEST('SHA512', 'The quick brown fox');

https://dev.mysql.com/doc/refman/8.0/en/enterprise-encryption-functions.html#function_create-摘要
和一个 BEFORE INSERT / BEFORE UPDATE 设置此校验和值的触发器:
https://dev.mysql.com/doc/refman/8.0/en/trigger-syntax.html
值得一提的是,有一个ruby库用于在activerecord模型上声明数据库触发器:https://github.com/jenseng/hair_trigger

gxwragnw

gxwragnw2#

rails解决方案是 before_save 钩子。您也可以使用数据库触发器来实现这一点,但这样做会更加混乱和脆弱。
sha256在这里可能很好,因为它是基于sha2的。碰撞的可能性应该非常小。
使用一致长度的散列而不是唯一索引的文本实际上是一个很好的主意,因为mysql的索引对于较长的字符串会变大。对于索引引擎来说,短十六进制字符串更容易处理,并且仍然提供所需的唯一性约束。
mysql的独特约束实际上也提供了一种排序机制,这是这里的痛苦之源,但是如果您不关心排序,哈希解决方案是一个很好的选择。

相关问题