Indexnamen in PostgreSQL
- Indexnamen sind in einem einzelnen Datenbankschema eindeutig.
- Indexnamen dürfen nicht mit anderen Indizes, (Fremd-) Tabellen, (materialisierten) Ansichten, Sequenzen oder benutzerdefinierten zusammengesetzten Typen im selben Schema identisch sein.
- Zwei Tabellen in demselben Schema dürfen keinen Index mit demselben Namen haben. (Folgt logisch.)
Wenn Sie sich nicht für den Namen des Indexes interessieren, lassen Sie Postgres diesen automatisch benennen:
CREATE INDEX ON tbl1 (col1);
ist (fast) dasselbe wie:
CREATE INDEX tbl1_col1_idx ON tbl1 USING btree (col1);
Mit der Ausnahme, dass Postgres Namenskollisionen vermeidet und automatisch den nächsten freien Namen auswählt:
tbl1_col1_idx
tbl1_col1_idx2
tbl1_col1_idx3
...
Probier es einfach. Offensichtlich möchten Sie jedoch nicht mehrere redundante Indizes erstellen. Es wäre also keine gute Idee, einfach blindlings ein neues zu erstellen.
Auf Existenz prüfen
Postgres 9.3 oder älter
Eine sehr einfache Möglichkeit zum Testen besteht darin, den schemaqualifizierten Namen in Folgendes umzuwandeln regclass
:
SELECT 'myschema.myname'::regclass;
Wenn es eine Ausnahme auslöst, ist der Name frei.
Oder, um dasselbe zu testen, ohne eine Ausnahme auszulösen, die in einer DO
Anweisung verwendet wird:
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
$$;
Dies funktioniert nicht CREATE INDEX CONCURRENTLY
, da diese Variante nicht in eine äußere Transaktion eingebunden werden kann. Siehe Kommentar von @Gregory unten.
Die DO
Aussage wurde mit Postgres 9.0 eingeleitet. In früheren Versionen müssen Sie eine Funktion erstellen , um dasselbe zu tun.
Details dazu pg_class
im Handbuch .
Grundlagen zu Indizes im Handbuch .
Postgres 9.4
Mit der neuen Funktion können Sie to_regclass()
prüfen, ohne eine Ausnahme auszulösen:
DO
$$
BEGIN
IF to_regclass('myschema.mytable_mycolumn_idx') IS NULL THEN
CREATE INDEX mytable_mycolumn_idx ON myschema.mytable (mycolumn);
END IF;
END
$$;
Gibt NULL zurück, wenn ein Index (oder ein anderes Objekt) dieses Namens nicht vorhanden ist. Sehen:
Postgres 9.5
Jetzt verfügbar:
CREATE INDEX IF NOT EXISTS ...
Das funktioniert auch für CREATE INDEX CONCURRENTLY IF NOT EXISTS
.
Das Handbuch warnt jedoch :
Beachten Sie, dass es keine Garantie dafür gibt, dass der vorhandene Index dem entspricht, der erstellt worden wäre.
Es ist eine einfache Überprüfung des Objektnamens. Gilt für alle Varianten hier.