Nomi degli indici in PostgreSQL
- I nomi degli indici sono univoci in un singolo schema di database.
- I nomi degli indici non possono essere gli stessi di qualsiasi altro indice, tabella (estranea), vista (materializzata), sequenza o tipo composito definito dall'utente nello stesso schema.
- Due tabelle nello stesso schema non possono avere un indice con lo stesso nome. (Segue logicamente.)
Se non ti interessa il nome dell'indice, fai in modo che Postgres lo assegni automaticamente:
CREATE INDEX ON tbl1 (col1);
è (quasi) lo stesso di:
CREATE INDEX tbl1_col1_idx ON tbl1 USING btree (col1);
Tranne che Postgres eviterà una collisione di denominazione e sceglierà automaticamente il prossimo nome gratuito:
tbl1_col1_idx
tbl1_col1_idx2
tbl1_col1_idx3
...
Provalo e basta. Ma, ovviamente, non vorresti creare più indici ridondanti. Quindi non sarebbe una buona idea crearne uno alla cieca.
Test per l'esistenza
Postgres 9.3 o precedente
Un modo molto semplice per testare è quello di trasmettere il nome qualificato da schema a regclass
:
SELECT 'myschema.myname'::regclass;
Se genera un'eccezione, il nome è gratuito.
Oppure, per testare lo stesso senza generare un'eccezione, utilizzato in DO
un'istruzione:
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
$$;
Questo non funziona CREATE INDEX CONCURRENTLY
, dal momento che quella variante non può essere racchiusa in una transazione esterna. Vedi il commento di @Gregory di seguito.
La DO
dichiarazione è stata introdotta con Postgres 9.0. Nelle versioni precedenti devi creare una funzione per fare lo stesso.
Dettagli pg_class
nel manuale .
Nozioni di base sugli indici nel manuale .
Postgres 9.4
È possibile utilizzare la nuova funzione to_regclass()
per verificare senza generare un'eccezione:
DO
$$
BEGIN
IF to_regclass('myschema.mytable_mycolumn_idx') IS NULL THEN
CREATE INDEX mytable_mycolumn_idx ON myschema.mytable (mycolumn);
END IF;
END
$$;
Restituisce NULL se non esiste un indice (o un altro oggetto) con quel nome. Vedere:
Postgres 9.5
Ora disponibili:
CREATE INDEX IF NOT EXISTS ...
Questo funziona anche per CREATE INDEX CONCURRENTLY IF NOT EXISTS
.
Tuttavia, il manuale avverte :
Si noti che non esiste alcuna garanzia che l'indice esistente sia simile a quello che sarebbe stato creato.
È un semplice controllo per il nome dell'oggetto. Si applica a tutte le varianti qui.