我有一个非常大的表,包含20亿行50个属性。并非所有都填写完毕,它是一个稀疏矩阵。
我不喜欢从所有值构建查询,而且索引现在太大了。我失去了表现。
对于我的新方法,我想添加一个摘要列,其中包含特定行中所有属性的摘要。
这个哈希没有安全要求,所以即使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
我可以索引该列并从数据库中获得非常非常快的响应时间。如果发生任何碰撞,我不太可能得到很多。如果在5或1000万次中发生碰撞,那很好。
我非常感谢任何见解。
懒惰的方式:
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
。
我也不会费心去除空值。哈希函数并不关心。