Індексні імена в PostgreSQL
- Імена індексів унікальні для однієї схеми бази даних.
- Імена індексу не можуть бути такими ж, як будь-який інший індекс, (іноземна) таблиця, (матеріалізований) подання, послідовність або визначений користувачем композитний тип в тій же схемі.
- Дві таблиці в одній схемі не можуть мати однойменний індекс. (Дотримується логічно.)
Якщо ви не переймаєтесь назвою індексу, дозвольте Postgres автоматично назвати його:
CREATE INDEX ON tbl1 (col1);
(майже) те саме, що:
CREATE INDEX tbl1_col1_idx ON tbl1 USING btree (col1);
За винятком того, що Postgres уникне зіткнення імен та автоматично вибере наступне вільне ім’я:
tbl1_col1_idx
tbl1_col1_idx2
tbl1_col1_idx3
...
Просто спробуйте. Але, очевидно, ви б не хотіли створювати кілька зайвих індексів. Тому не було б гарною ідеєю просто сліпо створити нову.
Тест на існування
Постгреси 9.3 або новіші
Дуже простий спосіб тестування - це передати ім'я, відповідне схемі regclass
:
SELECT 'myschema.myname'::regclass;
Якщо він кидає виняток, ім'я вільне.
Або тестувати те ж саме, не викидаючи виняток, який використовується в DO
операторі:
DO
$$
BEGIN
IF NOT EXISTS (
SELECT
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relname = 'mytable_mycolumn_idx'
AND n.nspname = 'myschema'
) THEN
CREATE INDEX mytable_mycolumn_idx ON myschema.mytable (mycolumn);
END IF;
END
$$;
Це не працює CREATE INDEX CONCURRENTLY
, оскільки цей варіант не можна зафіксувати у зовнішній транзакції. Дивіться коментар @Gregory нижче.
DO
Заява була введено з Postgres 9.0. У попередніх версіях вам потрібно створити функцію, щоб зробити те саме.
Детальніше про це pg_class
в посібнику .
Основи щодо покажчиків у посібнику .
Постгрес 9.4
Ви можете використовувати нову функцію to_regclass()
для перевірки, не кидаючи виняток:
DO
$$
BEGIN
IF to_regclass('myschema.mytable_mycolumn_idx') IS NULL THEN
CREATE INDEX mytable_mycolumn_idx ON myschema.mytable (mycolumn);
END IF;
END
$$;
Повертає NULL, якщо індекс (або інший об’єкт) цього імені не існує. Побачити:
Постгрес 9.5
Зараз доступний:
CREATE INDEX IF NOT EXISTS ...
Це також працює для CREATE INDEX CONCURRENTLY IF NOT EXISTS
.
Однак посібник попереджає :
Зауважте, що немає гарантії, що існуючий індекс є чимось схожим на той, який був би створений.
Це звичайна перевірка назви об'єкта. Тут стосується всіх варіантів.