我有大约100万个地址,还会有更多。对于每个地址,我都需要知道位置(纬度、经度(。
某些地址可能重复。例如,两张唱片:"美国,纽约,时代广场"one_answers"美国纽约时代广场"。我将这些地址规范化为"usa-newyorktimesquare",并将它们存储在表"cached_addresses"中,以便以后当我需要知道地址的纬度/经度时,我可以查询此表。
主要问题是:我可以存储md5/sha1/sha256哈希来获得一些性能提升/存储优化吗?
有问题的查询是:SELECT lat, lng FROM cached_addresses WHERE address = ?
,参数?
等于usa new york times square
。这里address表示规范化的地址字符串。
使用hash,它将是:SELECT lat, lng FROM cached_addresses WHERE address = ?
,参数?
等于hash_function('usa new york times square')
。这里address表示规范化地址字符串的散列。
我使用postgresql,但如果mysql可以提供一些性能/存储优化,那么也可以使用它。
就MySQL而言,如果您对值进行散列并以高效的方式存储它们,您可以期待性能的提高。我确信这也适用于postgress,因为这是DBA和开发人员面临的常见问题。
将完整(规范化(地址存储在列address
中时,每条记录至少需要N个字节,其中N是地址中的字符数。以你为例是25。但当角色集发挥作用时,事情会变得复杂,你可能需要比N多得多的东西,utf8
可能需要4*N。然后你需要对其进行索引(更多的存储空间取决于m*N(,DB引擎需要使用排序规则等执行字符串比较。
另一方面,当你对地址进行散列时,例如使用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
官方文件上有更多关于这方面的信息。
如果性能/存储是最重要的因素,并且您的应用程序可以容忍一些冲突,那么您甚至可以使用MD5
。这将需要一半的字节,但您需要处理可能的冲突(两个不同的地址产生相同的散列(。