Как PostgreSQL обеспечивает соблюдение ограничения UNIQUE / какой тип индекса он использует?

Я пытался разобраться в взаимосвязи между уникальным и индексом в Postgres после прочтения документы об уникальности индекса как детали реализации:

Предпочтительный способ добавления уникального ограничения к таблице - ALTER TABLE ... ADD CONSTRAINT. Использование индексов для обеспечения уникальных ограничений можно рассматривать как деталь реализации, к которой не следует обращаться напрямую. Однако следует помнить, что нет необходимости вручную создавать индексы для уникальных столбцов; это просто дублирует автоматически созданный индекс.

Итак, поверив документам, я собираюсь просто объявить вещи как уникальные и использовать неявный индекс - или - создать индекс, а не предполагать, что значения уникальны. Это ошибка?

Какой индекс я получу от unique? Учитывая, что только btree примет ограничение unique, а unique неявно создает индекс, верно ли, что UNIQUE создает индекс btree? Я не хочу непреднамеренно запускать диапазоны в хеш-индексе.


person Finn    schedule 30.01.2012    source источник
comment
Я не хочу непреднамеренно запускать диапазоны в хеш-индексе. Но еще раз: считайте это деталью реализации. Существуют ограничения для наложения / обеспечения модели данных, они не заботятся о производительности как таковой. Это логическая / семантическая разница. (Кстати: это это btree)   -  person wildplasser    schedule 30.01.2012
comment
Интересно, что указанное предпочтение исчезло из документации PostgreSQL, начиная с v9.5. См. postgresql.org/docs/9.5/static/indexes-unique.html   -  person Ethan    schedule 02.03.2017


Ответы (1)


или - создать индекс и не предполагать, что значения уникальны

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

Определение ограничения UNIQUE делает фактически то же самое (почти, см. Ниже), что и создание уникального индекса без указания типа индекса. И я цитирую руководство:

Возможные варианты: btree, hash, gist и gin. Метод по умолчанию - btree.

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

И нет, уникальное ограничение может быть реализовано только с базовым индексом btree во всех версиях до PostgreSQL 9.4 включительно. Я цитирую абзац «ADD table_constraint_using_index» в руководстве здесь:

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

Прочие отличия

  • Уникальные ограничения можно отложить. Это невозможно для уникальных индексов. Взгляните на команду SET CONSTRAINTS и перейдите по ссылкам для более.

- внешний ключ не может ссылаться на столбцы с только уникальным индексом. Руководство:

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

Последнее кажется устаревшим или недоразумением с самого начала. Видеть:

Связанный:

person Erwin Brandstetter    schedule 30.01.2012
comment
индексы btree по умолчанию ... это верно независимо от того, как этот индекс появился (например, INDEX vs UNIQUE) - person Finn; 30.01.2012
comment
Так можно ли заставить unique использовать хеш-индекс или индекс rtree для принуждения? - person Finn; 30.01.2012
comment
@Finn: Я добавил еще один бит к своему ответу, чтобы решить эту проблему. - person Erwin Brandstetter; 30.01.2012
comment
В v9.4.11 я могу добавить внешний ключ, который ссылается на столбец только с уникальным индексом, а не с уникальным ограничением. - person Ethan; 02.03.2017
comment
nvm, сегодня я узнал, что у PostgreSQL дерьмовая поддержка хешей blog.andrebarbosa.co/hash-indexes -on-postgres - person Evan Carroll; 02.06.2017
comment
@EvanCarroll: Это изменится на стр. 10: postgresql.org / docs / devel / static / - person Erwin Brandstetter; 02.06.2017
comment
@ErwinBrandstetter: Любая любовь - это хорошо, но эти журналы изменений (и документы), похоже, не подразумевают, что они будут использоваться в качестве уникальных индексов или что они получают сканирование только индекса (или, может быть, я его скучаю). - person Evan Carroll; 02.06.2017
comment
@Evan: Это правда, до сих пор нет уникального хеш-индекса. Только btree. Обходной путь - это индекс btree для хеш-выражения. Например, dba.stackexchange.com/a/115316/3684. Что касается сканирования только индекса: как может индекс hash когда-либо быть кандидатом? Исходное значение отсутствует в индексе. - person Erwin Brandstetter; 02.06.2017
comment
Ничто не мешает индексу читать таблицу в случае совпадения хэша. Это даст вам преимущество меньшего индекса вместе с более медленными вставками для проверки уникальности ... - person boatcoder; 25.07.2020
comment
@EvanCarroll. Хеш-индексы теперь классные: rhaas.blogspot. ru / 2017/09 / - person boatcoder; 25.07.2020