Rendere unico un campo lo rende indicizzato?


10

Se uniqueimposto un vincolo su un campo, devo anche creare un indice su quel campo per ottenere un tempo di inserimento scalabile? O è fatto per me (anche se l'indice che utilizza non è accessibile pubblicamente?)

In particolare, sto lavorando con Apache Derby per la prototipazione, anche se probabilmente lo sposterò su MySQL in un futuro semi-prossimo. Spero anche che ci possa essere qualcosa nello standard SQL che dice qualcosa al riguardo.

Non avrò mai bisogno di cercare in questo campo, quindi preferirei non fare un indice inutile. Ma preferirei avere un indice inutile che avere un O(n)tempo di inserimento.


2
Da quello che so è implementato un vincolo unico dietro l'utilizzo di un indice univoco. Puoi vedere alcune opinioni su questa situazione in questa domanda: quando usare un vincolo univoco invece di un indice univoco?
Marian,

@Marian grazie per quel link. È stato molto penetrante.
corsiKa

Risposte:


2

--MODIFICARE--

La mia risposta originale (sotto) probabilmente non ti è affatto utile perché non affronta la questione dei uniquevincoli. Come altri hanno già detto, questi vincoli sono generalmente implementati con un indice univoco implicito. In casi speciali questo potrebbe non essere vero (ad es. disable novalidatePer Oracle).

La domanda potrebbe essere: è possibile applicare l'unicità senza un indice? In generale, la risposta è no, sebbene in alcuni casi un indice cluster significhi che l'indice e la tabella sono lo stesso oggetto.

--END MODIFICA--

Hai detto "Preferirei avere un indice inutile che avere un tempo di inserimento O (n)", ma in generale i database non hanno un tempo di inserimento O (n). Vi sono due casi da considerare:

  1. Una tabella normale con o senza indici:

    Le nuove righe vengono scaricate nella parte superiore dell'heap. L'RDBMS probabilmente guarda solo 1 blocco, quindi non solo O (1) ma O (1) molto piccolo.

    Se la tabella ha indici, a ciascuno verrà aggiunto un puntatore alla riga. Generalmente si tratterà di un'operazione O (log (n)).

  2. Una tabella con una sorta di clustering in corso, ad esempio una tabella organizzata indice o un cluster per Oracle o un indice cluster per SQL Server e altri:

    Le nuove righe vengono inserite in un blocco particolare, il che può causare la divisione o l'overflow del blocco, ma qualunque cosa accada è ancora O (log (n)) o migliore , causato dall'albero b o da una struttura simile utilizzata per trovare il blocco.


Ma l'unicità senza un indice sarebbe O(n)come devi controllare l'intera tabella. Questo è quello che sto cercando di evitare.
corsiKa

Questa è davvero la migliore risposta a questa domanda !!! +1
RolandoMySQLDBA

@Trick - sì, all'inizio ho capito male. L'indice è il prezzo da pagare per il vincolo di unicità, temo. Puoi usare un indice cluster nel tuo caso?
Jack dice di provare topanswers.xyz

1
@JackPDougless Posso usare un "indice" standard e ottenere un O(lg n)tempo di inserimento. Non è un problema. La mia domanda è: il sistema, sapendo che hai bisogno di quell'indice per ottenere un tempo di inserimento decente, creerebbe un indice per me.
corsiKa

2

TASTO PRIMARIO> = UNICO> = INDICE == TASTO

I dati InnoDB sono ordinati dal PK. MyISAM PK si comporta come UNICO.

INSERT deve aggiungere una "riga" a ogni indice (di qualsiasi tipo) che possiedi. Questo richiede del tempo. (Di solito non c'è abbastanza tempo per contare.) Gli indici sono tutti memorizzati in formato BTree. I blocchi MyISAM BTree sono 1KB; InnoDB utilizza 16 KB.

L'inserimento in InnoDB aggiorna contemporaneamente PK e i dati.

L'inserimento in MyISAM di solito "accoda" i dati a .MYD. Separatamente, aggiunge una riga al PK (se presente).

INSERT deve prima verificare che non ci siano chiavi duplicate per nessuna chiave PRIMARIA o UNICA. Questo viene fatto utilizzando l'indice. E, quindi, perché i vincoli UNICI ed ESTERI costruiscono davvero indici. Questo è O (logN), ma di solito CPU, non I / O, perché se la cache è efficiente.


Hai una citazione nella specifica InnoDB che afferma che un UNIQUEvincolo creerà un indice senza che l'utente ne specifichi uno da effettuare?
corsiKa

Hmmm ... No, solo anni di esperienza.
Rick James,

Ed ecco un modo per testarlo ... CREARE una tabella senza indici secondari; MOSTRA STATO TABELLA - Index_length sarà 0. Quindi aggiungi un indice UNICO; STATO TABELLA ora mostrerà qualcosa. (Potrebbe essere necessario inserire una quantità non banale di dati nella tabella.)
Rick James,

1

Per rispondere alla domanda in grassetto: Sì, rendere un campo univoco lo indicizza come la chiave primaria. In effetti, ne avevo discusso in un'altra domanda riguardo alle chiavi primarie che avevano il proprio nome per distinguerlo dalle altre chiavi univoche (candidate) .

Per quanto riguarda i vincoli, gli indici vengono creati per te in modo che il paradigma del vincolo sia impostato. Dovresti essere in grado di rimuovere indici duplicati, anche chiavi UNIQUE, purché il vincolo che hai creato non faccia riferimento ad altre chiavi UNIQUE che hai creato personalmente a parte il paradigma del vincolo.

Potresti non dover mai cercare questo campo, ma MySQL dovrà sicuramente come percorso determinare la validità delle chiavi e determinare come eseguire le operazioni ON DELETE CASCADE e ON UPDATE CASCADE.

L'indice UNICO garantisce semplicemente l'unicità delle tuple (singleton, coppie, terzine, ..., n-tuple, ecc.) In ogni riga della tabella.

È a tua discrezione rimuovere tali indici duplicati, a condizione che tu non rompa il paradigma del vincolo che desideri avere nella tabella.


1
Questo non risponde alla mia domanda. La mia domanda è correlata al tempo di inserimento. Se hai un vincolo univoco, il sistema deve garantire l'univocità del campo prima di un inserimento - se non vi è alcun indice sul campo, dovrà cercare nell'intera tabella ( O(n)). Se esiste un indice, la ricerca sarà molto più veloce (probabilmente O(lg n)). Questo è il mio problema. Sono ben consapevole della meccanica di integrità referenziale, mi preoccupo solo (ai fini di questa domanda) delle prestazioni.
corsiKa
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.