Differenze tra INDEX, PRIMARY, UNIQUE, FULLTEXT in MySQL?


610

Quali sono le differenze tra PRIMARY, UNIQUE, INDEX e FULLTEXT durante la creazione di tabelle MySQL?

Come li userei?


3
Anche per chiunque sia curioso su SPATIAL: stackoverflow.com/questions/2256364/…
Leo,

Per un confronto di un indice primario con un indice secondario in Python, vedere questo post stackoverflow.com/questions/59918440/secondary-index-in-python
Athanassios

Risposte:


674

differenze

  • KEY o INDEX si riferisce a un normale indice non univoco. Sono consentiti valori non distinti per l'indice, quindi l'indice può contenere righe con valori identici in tutte le colonne dell'indice. Questi indici non impongono alcuna limitazione sui dati, quindi vengono utilizzati solo per l'accesso, per raggiungere rapidamente determinati intervalli di record senza eseguire la scansione di tutti i record.

  • UNIQUE si riferisce a un indice in cui tutte le righe dell'indice devono essere univoche. Cioè, la stessa riga potrebbe non avere valori identici non NULL per tutte le colonne di questo indice come un'altra riga. Oltre a essere utilizzati per raggiungere rapidamente determinati intervalli di record, gli indici UNIQUE possono essere utilizzati per imporre restrizioni sui dati, poiché il sistema di database non consente la violazione della regola dei valori distinti durante l'inserimento o l'aggiornamento dei dati.

    Il tuo sistema di database può consentire l'applicazione di un indice UNIQUE alle colonne che consentono valori NULL, nel qual caso due righe possono essere identiche se contengono entrambe un valore NULL (la logica è che NULL è considerato non uguale a se stesso). A seconda dell'applicazione, tuttavia, è possibile che ciò sia indesiderabile: se si desidera impedirlo, è necessario non consentire i valori NULL nelle colonne pertinenti.

  • PRIMARY si comporta esattamente come un indice UNICO, tranne per il fatto che è sempre chiamato "PRIMARY", e potrebbe essercene solo uno su una tabella (e dovrebbe essercene sempre uno; sebbene alcuni sistemi di database non lo applichino). Un indice PRIMARY è inteso come mezzo principale per identificare in modo univoco qualsiasi riga nella tabella, quindi a differenza di UNIQUE non dovrebbe essere usato su nessuna colonna che consenta valori NULL. L'indice PRIMARY dovrebbe trovarsi sul minor numero di colonne sufficienti per identificare in modo univoco una riga. Spesso, questa è solo una colonna che contiene un numero univoco auto-incrementato, ma se c'è qualcos'altro che può identificare in modo univoco una riga, come "countrycode" in un elenco di paesi, puoi invece usarlo.

    Alcuni sistemi di database (come InnoDB di MySQL) memorizzano i record di una tabella su disco nell'ordine in cui compaiono nell'indice PRIMARY.

  • Gli indici FULLTEXT sono diversi da tutto quanto sopra e il loro comportamento differisce significativamente tra i sistemi di database. Gli indici FULLTEXT sono utili solo per le ricerche full-text eseguite con la clausola MATCH () / AGAINST (), a differenza dei tre precedenti, che sono in genere implementati internamente utilizzando b-tree (consentendo di selezionare, ordinare o intervalli a partire dalla colonna più a sinistra) o tabelle hash (consentendo la selezione a partire dalla colonna più a sinistra).

    Laddove gli altri tipi di indice sono generici, un indice FULLTEXT è specializzato, in quanto ha uno scopo ristretto: viene utilizzato solo per una funzione di "ricerca full text".

Somiglianze

  • Tutti questi indici possono contenere più di una colonna.

  • Ad eccezione di FULLTEXT, l'ordine delle colonne è significativo: affinché l'indice sia utile in una query, la query deve utilizzare le colonne dell'indice a partire da sinistra: non può utilizzare solo la seconda, terza o quarta parte di un indice, a meno che non utilizzi anche le colonne precedenti nell'indice per abbinare i valori statici. (Perché un indice FULLTEXT sia utile per una query, la query deve utilizzare tutte le colonne dell'indice.)


2
questo significa che un indice FULLTEXT è essenzialmente inutile e una vita di spazio se non usi MATCH () / AGAINST () nelle tue query?
user1397417,

5
Sì. Viene anche utilizzato solo per i database MyISAM su MySQL, non InnoDB. Altri server di database potrebbero avere funzionalità equivalenti che potrebbero funzionare in modo diverso.
thomasrutter,

"non dovrebbe essere usato su nessuna colonna che consenta valori NULL" -> Questo dovrebbe essere "non può essere usato". Le chiavi primarie sono necessariamente NOT NULL. MySQL segnalerà show columnsche una chiave univoca non NULL è una chiave primaria, se non ci sono altre chiavi primarie definite.
Gordon Linoff,

1
La logica qui è che NULL è considerato non uguale a se stesso .. Lol non lo dimenticherò
Hos Mercury

2
@thomasrutter MySQL supporta FULLTEXT in InnoDB dalla versione 5.6
Marek Skiba

151

Tutti questi sono tipi di indici.

primario: deve essere univoco, è un indice, è (probabilmente) l'indice fisico, può essere solo uno per tabella.

unico: come dice. Non puoi avere più di una riga con una tupla di questo valore. Si noti che poiché una chiave univoca può trovarsi su più di una colonna, ciò non significa necessariamente che ogni singola colonna dell'indice sia unica, ma che ogni combinazione di valori tra queste colonne sia unica.

indice: se non è primario o univoco, non vincola i valori inseriti nella tabella, ma consente di cercarli in modo più efficiente.

testo completo: una forma più specializzata di indicizzazione che consente la ricerca di testo completo. Pensalo come (essenzialmente) creando un "indice" per ogni "parola" nella colonna specificata.


32
Primarys può essere composito, cioè multi-chiave, in MySQL (e molti altri DB). Sono solo un indice speciale. Unico non è in realtà un indice, è un vincolo (che richiede un indice per essere applicato in un ragionevole lasso di tempo, quindi ne crea uno).
MBCook

19

Sento che questo è stato ben coperto, forse tranne per quanto segue:

  • Semplice KEY/ INDEX(o altrimenti chiamato SECONDARY INDEX) aumenta le prestazioni se la selettività è sufficiente. A tale proposito, la consueta raccomandazione è che se la quantità di record nel set di risultati su cui viene applicato un indice supera il 20% della quantità totale di record della tabella padre, l'indice sarà inefficace. In pratica ogni architettura differirà ma l'idea è ancora corretta.

  • Gli indici secondari (e questo è molto specifico per mysql) non dovrebbero essere visti come oggetti completamente separati e diversi dalla chiave primaria. In effetti, entrambi dovrebbero essere usati congiuntamente e, una volta conosciute queste informazioni, fornire uno strumento aggiuntivo al DBA mysql: in Mysql, gli indici incorporano la chiave primaria. Porta a significativi miglioramenti delle prestazioni, in particolare quando si costruiscono in modo intelligente indici di copertura impliciti come qui descritti

  • Se ritieni che i tuoi dati dovrebbero essere UNIQUE, utilizza un indice univoco. Potresti pensare che sia facoltativo (ad esempio, risolverlo a livello di applicazione) e che un indice normale funzionerà, ma in realtà rappresenta una garanzia per Mysql che ogni riga è unica, il che fornisce per inciso un vantaggio in termini di prestazioni.

  • Puoi utilizzare FULLTEXT(o altrimenti chiamato SEARCH INDEX) solo con Innodb (in MySQL 5.6.4 e versioni successive) e Myisam Engines

  • È possibile utilizzare solo FULLTEXTsu CHAR, VARCHARe TEXTtipi di colonna
  • FULLTEXTL'indice comporta MOLTO più della semplice creazione di un indice. Sono state create numerose tabelle di sistema, un sistema di memorizzazione nella cache completamente separato e sono state applicate alcune regole e ottimizzazioni specifiche. Vedi http://dev.mysql.com/doc/refman/5.7/en/fulltext-rest restrizioni.html e http://dev.mysql.com/doc/refman/5.7/en/innodb-fulltext-index.html
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.