Добавление уникального индекса в строку текстового поля MySQL с использованием хеширования в Ruby - PullRequest
0 голосов
/ 02 мая 2018

У меня есть приложение Rails с моделью (таблицей), которая имеет 1 500 000 записей, с размером текстового поля от 50 до 8 000 символов.

Мне нужно убедиться, что текстовое поле уникально. Поскольку я не могу использовать уникальный индекс MySQL для текстового поля, мое решение состоит в том, чтобы преобразовать мое текстовое поле в хеш (используя Digest :: SHA256.hexdigest) и сохранить этот хеш в поле varchar, называемом «body_hash». Затем добавьте уникальный индекс в этом поле.

Вопросы:

  • Мне было интересно, есть ли в Rails встроенное решение для этого? (Вместо того, чтобы заново изобретать колесо - пока я ничего не смог найти.)
  • Для этого лучше использовать другой алгоритм хеширования, чем Digest :: SHA256.hexdigest?

Ответы [ 2 ]

0 голосов
/ 02 мая 2018

Вы можете рассмотреть возможность создания этой контрольной суммы / дайджеста в самой БД. Это будет быстрее для заполнения значений для существующих данных, чем для обработки в Ruby.

Объединение MySQL CREATE_DIGEST для заполнения столбца body_digest:

CREATE_DIGEST('SHA512', 'The quick brown fox');

https://dev.mysql.com/doc/refman/8.0/en/enterprise-encryption-functions.html#function_create-digest

И триггер BEFORE INSERT / BEFORE UPDATE для установки значения контрольной суммы:

https://dev.mysql.com/doc/refman/8.0/en/trigger-syntax.html

Стоит отметить, что есть библиотека Ruby для объявления триггеров базы данных на моделях ActiveRecord: https://github.com/jenseng/hair_trigger

0 голосов
/ 02 мая 2018

Решение Rails - это before_save hook. Вы также можете сделать это с помощью триггера базы данных, но это намного более грязно и хрупко.

SHA256, вероятно, здесь хорошо, так как он основан на SHA2. Вероятность столкновения должна быть исчезающе мала.

Использование хеша согласованной длины вместо текста для уникального индекса на самом деле является отличной идеей, поскольку индексы MySQL увеличиваются для более длинных строк. Короткая шестнадцатеричная строка намного легче обрабатывается механизмом индексирования и все же обеспечивает требуемое ограничение уникальности.

Уникальные ограничения MySQL на самом деле также предоставляют механизм упорядочения, и это является источником боли, но если вы не заинтересованы в упорядочивании хеш-решения, это отличная альтернатива.

...