Уникальное ограничение с разницей Хэмминга в postgres - PullRequest
2 голосов
/ 16 июня 2020

Последний столбец image_hash содержит изображение ha sh файлов изображений (varchar).

Моя цель - создать уникальное ограничение для этого столбца, но оно должно соответствовать одному определенному условию c.

Например, если image_ha sh 1 и image_ha sh 2 одинаковы - тогда сходство равно 1

Если они полностью разные - сходство → 0

Для подобие, я думаю, разница Хэмминга должна подходить.

Условие:

Если разница сходства между image_ha sh 1 и image ha sh 2 меньше, чем X (например, 0,1), тогда хеши считаются одинаковыми, и это будет нарушением уникальности.

Если сходство больше, чем X, то ограничение уникальности не нарушается.

Я пробовал:

SELECT image_hash, similarity(image_hash, '00041dffff101800') AS sml
FROM   archives_imagemodel
WHERE id=431

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

Я плохо разбираюсь в Postgres, так что извините, если вопрос глупый или не соответствует действительности

Есть идеи?

Спасибо

* 103 0 *enter image description here

1 Ответ

1 голос
/ 17 июня 2020

В принципе это возможно, но для этого потребуется написать расширение в C, которое предоставляет:

  • Оператор подобия, реализующий расстояние Хэмминга. Он вернет TRUE, если аналогичным образом превысит порог.

  • Класс оператора GiST для text, который поддерживает оператор.

Затем вы можете создать ограничение исключения с помощью этого оператора, который будет делать именно то, что вы хотите. Но имейте в виду, что для этого вам придется погрузиться во внутренности PostgreSQL (но вам не придется изменять сервер).

Более приземленным подходом было бы использование триггера, но без индекса GiST, как описано выше, это означало бы последовательное сканирование для каждой модификации данных, что снизило бы производительность. Более того, если вы не используете уровень изоляции SERIALIZABLE, такие триггеры могут быть связаны с условиями гонки .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...