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

0

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

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

Вопросы:

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

2 ответа

1

Вы можете захотеть создать эту контрольную сумму/дайджест в самой БД. Это будет быстрее возвращать значения заполнения для существующих данных, а не обрабатывать 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

1

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

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

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

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

  • 1
    before_save хука before_save является то, что он не защищает от вставок / обновлений, сделанных непосредственно в БД
  • 0
    @oldp Иногда это особенность, иногда ответственность. Когда вам нужно обойти это поведение, по крайней мере, у вас есть варианты, если это делается на прикладном уровне. Выполнение этого на уровне базы данных может быть намного сложнее обойти, если вам нужно.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню