如何从 Ruby 2.4 中的散列生成可靠的摘要?

How can I generate a reliable digest from a hash in Ruby 2.4?

我有一个非常大的 table 包含 50 个属性的 20 亿行。没有全部填满,是一个稀疏矩阵。

我不喜欢必须根据所有值构建查询,而且索引现在太大了。我失去了性能。

对于我的新方法,我想添加一个摘要列,其中包含特定行中所有属性的摘要。

这个散列没有安全要求,所以即使是 MD5 也可以。

我是否最好构建一个包含所有键和值的表示形式的简单字符串?或者有更好的方法吗?

例如,给定哈希:

attr_hash = { attribute1: "Please",
              attribute2: nil,
              attribute3: "don't",
              attribute4: nil,
              attribute5: nil,
              attribute6: nil,
              attribute7: "immediately",
              attribute8: "",
              attribute9: "downvote",
              attribute10: "my",
              attribute11: nil,
              attribute12: "question" }

这会更好吗(我相信你会同意这很漂亮):

attr_str = attr_hash.select{|k,v| v!="" && !v.nil?}.keys.sort.map{|k| "#{k}=#{attr_hash[k]}" }.join("^^")
digest = Digest::MD5.hexdigest(attr_str)

这给出了一个漂亮的字符串:

790470349a791b9897afd52a336ab2bb

我可以为该列编制索引并从数据库中获得非常非常快的响应时间。而且我不太可能从中得到很多(如果有的话)碰撞。如果有五分之一或一千万次的碰撞,那也没关系。

我非常感谢任何见解。

懒惰的方式:

Digest::SHA2.hexdigest(attr_hash.inspect)

前提是您的物品具有相同的顺序。如果您需要先对项目进行排序:

Digest::SHA2.hexdigest(attr_hash.to_a.sort_by { |k, _v| k }.inspect)

如果我想要更便携的东西,比如非Ruby代码库,我会使用JSON.dump(x)而不是x.inspect

我也懒得去掉空值。哈希函数不关心。