Nazwy indeksów w PostgreSQL
- Nazwy indeksów są unikalne w jednym schemacie bazy danych.
- Nazwy indeksów nie mogą być takie same jak jakikolwiek inny indeks, (obca) tabela, (zmaterializowany) widok, sekwencja lub typ złożony zdefiniowany przez użytkownika w tym samym schemacie.
- Dwie tabele w tym samym schemacie nie mogą mieć indeksu o tej samej nazwie. (Podąża logicznie.)
Jeśli nie obchodzi Cię nazwa indeksu, poproś o automatyczne nadanie mu nazwy Postgres:
CREATE INDEX ON tbl1 (col1);
jest (prawie) taki sam jak:
CREATE INDEX tbl1_col1_idx ON tbl1 USING btree (col1);
Tyle że Postgres uniknie kolizji nazw i automatycznie wybierze następną darmową nazwę:
tbl1_col1_idx
tbl1_col1_idx2
tbl1_col1_idx3
...
Po prostu spróbuj. Ale oczywiście nie chcesz tworzyć wielu nadmiarowych indeksów. Więc nie byłoby dobrym pomysłem po prostu tworzenie na ślepo nowego.
Test na istnienie
Postgres 9.3 lub starszy
Bardzo prostym sposobem na przetestowanie jest rzutowanie nazwy kwalifikowanej do schematu na regclass
:
SELECT 'myschema.myname'::regclass;
Jeśli zgłosi wyjątek, nazwa jest bezpłatna.
Lub, aby przetestować to samo bez zgłaszania wyjątku, użyte w DO
instrukcji:
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
$$;
To nie działa CREATE INDEX CONCURRENTLY
, ponieważ ten wariant nie może być zawarty w zewnętrznej transakcji. Zobacz komentarz @Gregory poniżej.
DO
Oświadczenie zostało wprowadzone z PostgreSQL 9.0. We wcześniejszych wersjach musisz utworzyć funkcję, aby zrobić to samo.
Szczegóły na temat pg_class
instrukcji .
Podstawy indeksów w instrukcji .
Postgres 9.4
Możesz użyć nowej funkcji to_regclass()
do sprawdzenia bez zgłaszania wyjątku:
DO
$$
BEGIN
IF to_regclass('myschema.mytable_mycolumn_idx') IS NULL THEN
CREATE INDEX mytable_mycolumn_idx ON myschema.mytable (mycolumn);
END IF;
END
$$;
Zwraca NULL, jeśli indeks (lub inny obiekt) o tej nazwie nie istnieje. Widzieć:
Postgres 9.5
Już dostępny:
CREATE INDEX IF NOT EXISTS ...
To też działa CREATE INDEX CONCURRENTLY IF NOT EXISTS
.
Jednak instrukcja ostrzega :
Należy pamiętać, że nie ma gwarancji, że istniejący indeks jest podobny do tego, który zostałby utworzony.
Jest to zwykłe sprawdzenie nazwy obiektu. Dotyczy wszystkich wariantów tutaj.