Хранить адреса как хеш - PullRequest
       15

Хранить адреса как хеш

0 голосов
/ 14 апреля 2020

У меня около 1 миллиона адресов, и их будет больше. Для каждого адреса мне нужно знать местоположение (широта, долгота).

Некоторые адреса могут дублироваться. Например, две записи: «США, Нью-Йорк, Таймс-сквер» и «США, Нью-Йорк Таймс-сквер». Я нормализую эти адреса до "usa new york times square" и сохраняю их в таблице "cached_addresses", поэтому позже, когда мне понадобится узнать широту / долготу для адреса, я могу запросить эту таблицу.

Основной вопрос: может Вместо этого я сохраняю md5 / sha1 / sha256 га sh, чтобы повысить производительность и оптимизировать хранилище?

Вопрос: SELECT lat, lng FROM cached_addresses WHERE address = ?, параметр ? равен usa new york times square. Здесь адрес представляет собой нормализованную адресную строку.

Для ha sh это будет: SELECT lat, lng FROM cached_addresses WHERE address = ?, параметр ? равен hash_function('usa new york times square'). Здесь адрес представляет собой sh нормализованной адресной строки.

Я использую postgresql, но также можно использовать mysql, если это может дать некоторую оптимизацию производительности / хранения.

1 Ответ

2 голосов
/ 14 апреля 2020

Что касается MySQL, вы можете ожидать улучшения производительности, если у вас есть sh значений и сохраните их эффективным способом. Я почти уверен, что это относится и к postgress, так как это общая проблема, с которой сталкиваются администраторы и администраторы.

Когда вы сохраняете полный (нормализованный) адрес в столбце address, вам нужно, по крайней мере, N байт для каждой записи, где N - количество символов в адресе. Было бы 25 для вашего примера. Но когда в игру вступают наборы символов, все усложняется, и вам может понадобиться намного больше, чем N, возможно, 4 * N для utf8. И затем вам нужно проиндексировать это (больше места для хранения в зависимости от m * N), и ядру БД потребуется выполнить сравнение строк, используя параметры сортировки et c.

С другой стороны когда у вас есть sh адрес, например, с использованием 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. Это потребовало бы половины байтов, но вам нужно будет обработать возможные коллизии (два разных адреса производят одинаковое ха sh).

...