【问题标题】:Store addresses as hash将地址存储为哈希
【发布时间】:2020-07-27 14:29:33
【问题描述】:

我有大约 100 万个地址,而且还会更多。对于每个地址,我需要知道位置(纬度、经度)。

某些地址可能重复。例如,两条记录:“USA, New York, Times Square”和“USA New York Times Square”。我将这些地址标准化为“美国纽约时代广场”并将它们存储在表“cached_addresses”中,以便稍后当我需要知道地址的纬度/经度时,我可以查询此表。

主要问题是:我可以存储 md5/sha1/sha256 哈希来获得一些性能提升/存储优化吗?

有问题的查询是:SELECT lat, lng FROM cached_addresses WHERE address = ?,参数? 等于usa new york times square。这里的address表示规范化的地址字符串。

使用哈希将是:SELECT lat, lng FROM cached_addresses WHERE address = ?,参数? 等于hash_function('usa new york times square')。这里的address表示标准化地址字符串的hash。

我用的是postgresql,但是如果mysql可以提供一些性能/存储优化,也可以使用。

【问题讨论】:

  • 看来您已经知道可以存储地址字段的哈希以及如何查询它。您的问题是关于“我可以”还是“我应该……优化查询”?
  • 你可以吗?找出答案的一种方法:对其进行基准测试。
  • 附带说明,将解析后的地址保存为文本(并保存在多个字段中)可能很有用,这样对标准化程序的任何更改都可以应用于地址缓存。地址变更也是如此(街道名称变更、城市合并、邮政编码变更等)

标签: mysql postgresql hash geolocation


【解决方案1】:

就 MySQL 而言,如果您对值进行哈希处理并以有效的方式存储它们,则可以预期性能会有所提高。我很确定这也适用于 postgress,因为这是 DBA 和开发人员面临的常见问题。

当您将完整(规范化)地址存储在address 列中时,每条记录需要至少 N 个字节,其中 N 是地址中的字符数。对于您的示例,它将是 25。但是,当字符集开始发挥作用时,事情会变得复杂,您可能需要的不仅仅是 N,对于utf8,可能需要 4*N。然后您需要对其进行索引(更多存储空间取决于 m*N),并且数据库引擎将需要使用 collat​​ions 等执行字符串比较。

另一方面,当您对地址进行哈希处理时,例如使用 SHA-256,无论地址有多长,您都只需要存储 32 个字节。此外,您可以将字节存储在BINARY(32) 列(数据和索引的固定存储)中,并在查询时执行二进制比较

例子:

ALTER TABLE t ADD COLUMN address_hash BINARY(32);
UPDATE t SET address_hash = unhex(sha2(address,256)));
SELECT c1, c2 FROM t WHERE address_hash = ?;
-- ? would be the SHA-256 hash of the address

更多关于official docs的信息。

如果性能/存储是最重要的因素并且您的应用程序可以容忍一些冲突,您甚至可以使用MD5。这将需要一半的字节,但您需要处理可能的冲突(两个不同的地址产生相同的哈希)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-13
    • 1970-01-01
    • 2012-11-13
    • 1970-01-01
    • 2017-09-01
    • 1970-01-01
    相关资源
    最近更新 更多