Вставка записи нарушает два уникальных индекса в PostgreSQL. Какой из них проверяется первым? - PullRequest
2 голосов
/ 11 марта 2019

У меня есть таблица PostgreSQL с двумя уникальными индексами в разных полях (nickname и email). Я пытаюсь вставить запись, которая нарушает оба ограничения. Я хочу, чтобы nickname проверялся и сообщался первым.

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

1 Ответ

2 голосов
/ 13 марта 2019

PostgreSQL использует RelationGetIndexList для получения списка индексов, а в комментарии говорится:

/*
 * RelationGetIndexList -- get a list of OIDs of indexes on this relation
[...]
 *
 * The returned list is guaranteed to be sorted in order by OID.  This is
 * needed by the executor, since for index types that we obtain exclusive
 * locks on when updating the index, all backends must lock the indexes in
 * the same order or we will get deadlocks (see ExecOpenIndices()).  Any
 * consistent ordering would do, but ordering by OID is easy.
[...]
 */

OID (идентификаторы объекта) - это 4-байтовые целые числа без знака, которые подсчитываютсяпоэтому обычно более поздние объекты получат более высокие OID.Это соответствует тому, что вы наблюдаете.

Однако, как только диапазон OID исчерпан, они оборачиваются и начинают снова с FirstNormalObjectId (16384), поэтому нет гарантии, что индекс, который был создан первым, имеетнижний OID.

Вы можете использовать запрос типа:

SELECT 'indexname'::regclass::oid;

, чтобы найти OID каждого индекса.

Чтобы получить OID всех индексов в таблице, используйте

SELECT indexrelid AS oid, indexrelid::regclass
FROM pg_index
WHERE indrelid = 'tablename'::regclass;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...