уникальный индекс или ограничение на ключ hstore

Я хотел бы создать уникальный индекс или ограничение для определенных ключей в столбце hstore, если этот ключ существует. Я надеялся, что ответ будет найден где-то в этом другом вопросе:

Практические ограничения индексов выражений в PostgreSQL

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

в настоящее время мой стол

hstore_table

поле hstore — hstore_value

и ключи, которые я хотел бы сделать уникальными, это «foo» и «bar», когда они существуют.

Моя версия PostgreSQL 8.4.13.


person trex005    schedule 07.03.2013    source источник


Ответы (1)


Если я правильно понял, о чем вы просите, вам нужен частичный уникальный функциональный индекс:

CREATE TABLE hstest ( x hstore not null );

CREATE UNIQUE INDEX hstest_key_k1_values_unique 
ON hstest((x -> 'k1'))
WHERE ( x ? 'k1' );

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

Если вам нужно несколько ключей, используйте два индекса, если вы хотите, чтобы они были независимыми, или индексируйте два выражения, если вы хотите связать их, чтобы ограничение уникальности допускало (1,2) и (1,3) или (2,2) но не другой (1,2), например:

CREATE UNIQUE INDEX hstest_key_k1k2_values_unique 
ON hstest ((x -> 'k1'), (x -> 'k2'));
person Craig Ringer    schedule 07.03.2013
comment
В документации указано, что каждый ключ в hstore уникален. Я не понимаю, зачем нам нужно добавлять тип индекса, который вы показываете. Я что-то пропустил? - person IamIC; 28.12.2016
comment
@IamIC Исходный автор хотел убедиться, что для двух разных строк A и B поле hstore «h» не может содержать один и тот же ключ «k» с одинаковым значением между двумя строками. то есть, если существует строка A.h{k=1}, запретить вставку строки B.h{k=1}, но разрешить вставку B.h{k=2} или B.h{x=1}. Подобно ограничению UNIQUE, но применяется к значению ключа hstore, а не к столбцу в целом. - person Craig Ringer; 30.12.2016
comment
@CraigRinger Спасибо. В этом есть смысл. Похоже, что нужно указать каждый ключ, который будет ограничен в определении индекса. Было бы непрактично для большого количества ключей. Я предполагаю, что в таких случаях сработает триггер перед upsert. - person IamIC; 31.12.2016
comment
@IamIC Поскольку в hstore есть оператор =, вы, вероятно, могли бы сделать это с оператором подмножества hstore hstore -> text[], но только если вы заинтересованы в фиксированном списке ключей и согласны с семантикой обработки нулей. Триггер перед вставкой НЕ будет работать из-за правил видимости MVCC; вы не можете правильно реализовать ограничение unique с помощью триггера. - person Craig Ringer; 01.01.2017