È necessario un indice per una chiave primaria in SQLite?


130

Quando una colonna intera è contrassegnata come chiave primaria in una tabella SQLite, è necessario creare esplicitamente anche un indice per essa? SQLite non sembra creare automaticamente un indice per una colonna chiave primaria, ma forse lo indicizza comunque, dato il suo scopo? (Cercherò sempre su quella colonna).

La situazione sarebbe diversa per una chiave primaria di stringa?

Risposte:


149

Lo fa per te.

A parte le colonne INTEGER PRIMARY KEY, i vincoli UNIQUE e PRIMARY KEY vengono implementati creando un indice nel database (come farebbe con un'istruzione "CREATE UNIQUE INDEX"). Tale indice viene utilizzato come qualsiasi altro indice nel database per ottimizzare le query. Di conseguenza, spesso non esiste alcun vantaggio (ma un notevole sovraccarico) nella creazione di un indice su un insieme di colonne che sono già collettivamente soggette a un vincolo UNIQUE o PRIMARY KEY.


8
Infatti, dice "L'attributo PRIMARY KEY crea normalmente un indice UNIQUE sulla colonna o sulle colonne specificate come PRIMARY KEY". Tuttavia, quell'indice non è visibile nelle applicazioni di gestione di SQLite, ecco perché l'ho chiesto.
Marek Jedliński,

1
È menzionato nella sqlite_mastertabella con un nome che inizia con sqlite_autoindex_.
dan04

2
In ritardo, ma @NicolasZozol sì, è necessario creare un UNIQUEindice (o un UNIQUEvincolo) sui campi padre / riferimento se non esiste; si raccomanda che il / i campo / i di riferimento / i abbiano un indice (che di solito non sarà unico): vedi qui
TripeHound

2
Hmm, la sezione SQL Data Constraints qui dice: Nella maggior parte dei casi , i vincoli UNIQUE e PRIMARY KEY vengono implementati creando un indice univoco nel database. (Le eccezioni sono INTEGER PRIMARY KEY e PRIMARY KEYs nelle tabelle WITHOUT ROWID.). Quindi la risposta non è sempre vera?
Curiosità giocosa,

3
Sembra che il rowid sia indicizzato ma implementato in modo diverso sqlite.org/lang_createtable.html#rowid I dati per le tabelle rowid sono memorizzati come una struttura B-Tree contenente una voce per ogni riga della tabella, usando il valore rowid come chiave ... per un record con un rowid specifico ... è circa due volte più veloce di una ricerca simile effettuata specificando qualsiasi altro PRIMARY KEY o valore indicizzato.
matreshkin,

15

Se una colonna è contrassegnata con INTEGER PRIMARY KEY, in realtà è circa due volte più veloce di una ricerca simile effettuata specificando qualsiasi altro PRIMARY KEY o valore indicizzato . Questo è perché:

... tutte le righe all'interno delle tabelle SQLite hanno una chiave intera con segno a 64 bit che identifica in modo univoco la riga all'interno della sua tabella ... La ricerca di un record con un rowid specifico o per tutti i record con rowid all'interno di un intervallo specificato è circa il doppio di veloce come una ricerca simile effettuata specificando qualsiasi altro PRIMARY KEY o valore indicizzato.

Con un'eccezione indicata di seguito, se una tabella rowid ha una chiave primaria che consiste in una singola colonna e il tipo dichiarato di quella colonna è "INTEGER" in qualsiasi combinazione di maiuscole e minuscole, la colonna diventa un alias per il rowid.

Tale colonna viene generalmente definita "chiave primaria intera". Una colonna PRIMARY KEY diventa una chiave primaria intera solo se il nome del tipo dichiarato è esattamente "INTEGER". Altri nomi di tipo intero come "INT" o "BIGINT" o "SHORT INTEGER" o "UNSIGNED INTEGER" fanno sì che la colonna chiave primaria si comporti come una normale colonna di tabella con affinità intera e un indice univoco, non come alias per il rowid.

Vedi: http://www.sqlite.org/lang_createtable.html#rowid


8

Un database creerà sempre silenziosamente un indice per una chiave primaria univoca in modo da poter verificare internamente che sia univoco in modo efficiente.

Avendolo creato, lo userà quando necessario.

Ovviamente non sarà sempre raggruppato e di solito si specifica nello schema se lo si desidera.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.