Это невозможно с вашей несколько устаревшей версией 9.4
Postgres 9.5 представил другой тип JSON с именем jsonb
, который поддерживает оператор равенства. Так что если вам это действительно нужно, вам придется перейти на более новую версию (например, 10 или 11)
Тип данных json
сохраняет порядок входного значения и, таким образом, делает сравнение действительно сложным (по крайней мере, неэффективным).
Тип jsonb
нормализует ключ / значения и сохраняет данные в двоичном виде.
формат, который позволяет эффективную проверку равенства.
например.
'{"foo": 42, "bar": "value"}'::jsonb = '{"bar": "value", "foo": 42}'::jsonb
возвращает true
. То же выражение с приведением к json
приводит к ошибке.
Так работает следующий DDL:
create table data
(
id serial primary key,
payload jsonb,
unique (payload)
);
Однако существует ограничение на допустимый размер записи индекса (около 2000 байт). Так что может случиться так, что вставка данных в такую таблицу завершится неудачей не из-за нарушения ограничения уникальности, а из-за слишком большого значения JSON.
Один из вариантов Postgres 9.4 - создать уникальный индекс для хеша MD5 значения JSON.
create unique index on data ( md5(payload::text) );
Но это будет только , если вы всегда будете указывать ключи внутри JSON в одинаковом порядке. Поскольку хэш md5 '{"foo": 42, "bar": "value"}'
отличается от хеша для '{"bar": "value"}, "foo": 42'
Некоторые вопросы с решениями для индексации больших текстовых значений: