Domanda

Ho una serie di domande su chiavi, indici e vincoli in SQL, SQL 2005 in particolare. Lavoro con SQL da circa 4 anni ma non sono mai stato in grado di ottenere risposte definitive su questo argomento e ci sono sempre informazioni contraddittorie sui post del blog, ecc. La maggior parte delle tabelle temporali che creo e utilizzo hanno solo una colonna Identità che è una chiave primaria e altre tabelle puntano ad essa tramite una chiave esterna.

Con le tabelle di join non ho identità e creo una chiave primaria composita sulle colonne chiave esterna. Quella che segue è una serie di affermazioni delle mie attuali convinzioni, che potrebbero essere errate, per favore correggimi in caso affermativo e altre domande.

Quindi ecco qui:

A quanto ho capito, la differenza tra un indice cluster e non cluster (indipendentemente dal fatto che sia univoco o meno) è che l'indice cluster influisce sull'ordinamento fisico dei dati in una tabella (quindi è possibile averne solo uno in una tabella ), mentre un indice non cluster crea una struttura di dati ad albero. Quando si creano gli indici, perché dovrei preoccuparmi di Clustered vs Non Clustered? Quando dovrei usare l'uno o l'altro? Mi è stato detto che l'inserimento e l'eliminazione sono lenti con gli indici non cluster poiché l'albero deve essere "ricostruito". Presumo che gli indici cluster non influiscano sulle prestazioni in questo modo?

Vedo che le chiavi primarie sono in realtà solo indici cluster che sono univoci (devono essere raggruppati?). Che cosa c'è di speciale in una chiave primaria rispetto a un indice univoco cluster?

Ho visto anche i Vincoli, ma non li ho mai usati né li ho guardati davvero. Mi è stato detto che lo scopo dei vincoli è quello di far rispettare l'integrità dei dati, mentre gli indici sono finalizzati alla performance. Ho anche letto che i vincoli sono comunque implementati come indici in modo da essere "uguali". Questo non suona bene per me. In che modo i vincoli sono diversi dagli indici?

È stato utile?

Soluzione

Indici cluster sono, come dici correttamente, i definizione del modo in cui i dati di una tabella vengono archiviati fisicamente, ovvero si dispone di un albero B ordinato mediante la chiave di clustering e i dati sono a livello foglia.

Indici non cluster su d'altra parte sono strutture ad albero separate che a livello foglia hanno solo la chiave di clustering (o un RID se la tabella è un heap), il che significa che quando si utilizza un indice non cluster, è necessario utilizzare l'indice cluster per ottenere le altre colonne (a meno che la tua richiesta non sia completamente coperta dall'indice non cluster, il che può accadere se richiedi solo le colonne, che costituiscono le colonne chiave dell'indice non cluster).

Quando dovresti usare l'uno o l'altro? Bene, poiché puoi avere un solo indice cluster, definiscilo sulle colonne che ha più senso, cioè quando cerchi i clienti per ID la maggior parte delle volte, definisci un indice cluster sull'ID. Gli indici non cluster dovrebbero essere definiti su colonne utilizzate meno frequentemente.

Per quanto riguarda le prestazioni, gli inserimenti o gli aggiornamenti che cambiano la chiave dell'indice sono sempre dolorosi, indipendentemente dal fatto che sia un cluster confuso su un indice non cluster, poiché possono verificarsi divisioni di pagina, che forza lo spostamento dei dati tra le pagine (spostando le pagine di un indice cluster fa più male, poiché hai più dati a livello foglia). Pertanto, la regola generale è quella di evitare di modificare la chiave di indice e di inserire nuovi valori in modo che siano sequenziali. Altrimenti incontrerai frammentazione e dovrai ricostruire il tuo indice su base regolare.

Infine, per quanto riguarda i vincoli, per definizione, non hanno nulla a che fare con gli indici, tuttavia SQL Server ha scelto di implementarli usando gli indici. Per esempio. attualmente un vincolo unico è implementato come indice, tuttavia ciò può cambiare in una versione futura (anche se dubito che accadrà). Il tipo di indice (cluster o no) dipende da te, ricorda solo che puoi avere un solo indice cluster.

Se hai altre domande di questo tipo, ti consiglio vivamente di leggere questo libro , che tratta in modo approfondito questi argomenti.

Altri suggerimenti

Il tuo presupposto sul cluster vs non cluster è abbastanza buono

Sembra anche che la chiave primaria imponga l'univoca non nulla, mentre l'indice univoco non impone non null primario vs unico

La chiave primaria è un concetto logico nella teoria dei database relazionali: è una chiave (e in genere anche un indice) progettata per identificare in modo univoco una delle tue righe. Pertanto deve essere unico e non può essere NULL.

La chiave di clustering è specificamente un concetto di memoria di SQL Server. È un indice speciale che non viene utilizzato solo per le ricerche, ecc., Ma definisce anche la struttura fisica dei dati nella tabella. In una rubrica stampata nella cultura dell'Europa occidentale (tranne forse per l'Islanda), l'indice raggruppato sarebbe "LastName, FirstName".

Poiché l'indice del clustering definisce il layout dei dati fisici, puoi sempre e solo avere uno di questi (o nessuno - non raccomandato, tuttavia).

I requisiti per una chiave di clustering sono:

  • deve essere univoco (in caso contrario, SQL Server aggiungerà un "unificatore" a 4 byte ")
  • dovrebbe essere stabile (senza mai cambiare)
  • dovrebbe essere il più piccolo possibile (INT è il migliore)
  • dovrebbe essere sempre crescente (pensa: IDENTITÀ)

SQL Server rende la chiave primaria la chiave di cluster per impostazione predefinita, ma è possibile modificarla se necessario. Inoltre, attenzione: le colonne che compongono la chiave di clustering verranno aggiunte a ciascuna voce di ogni indice non cluster sulla tabella, in modo da mantenere la chiave di clustering il più piccola possibile. Questo perché la chiave di clustering verrà utilizzata per eseguire la ricerca " segnalibro " - se hai trovato una voce in un indice non cluster (ad es. una persona tramite il suo numero di previdenza sociale) e ora devi prendere l'intera riga di dati per ottenere maggiori dettagli, devi fare una ricerca e, per questo, il viene utilizzata la chiave di clustering.

C'è un grande dibattito su ciò che rende un clustering buono / utile e / o chiave primaria - ecco alcuni post di blog eccellenti da leggere al riguardo:

Marc

Hai diverse domande. Ne spiegherò alcuni:

Quando si creano gli indici, perché dovrei preoccuparmi di Clustered vs Non Clustered?

A volte ti interessa come sono organizzate le righe. Dipende dai tuoi dati e da come li userai. Ad esempio, se la tua chiave primaria è un uniqueidentifier , potresti non voler che sia CLUSTERED , poiché i valori GUID sono essenzialmente casuali. Ciò farà sì che SQL inserisca le righe in modo casuale in tutta la tabella, causando divisioni di pagina che compromettono le prestazioni. Se il valore della chiave primaria aumenterà sempre in modo sequenziale (ad esempio int IDENTITY ), allora probabilmente vorrai che sia CLUSTERED , quindi la tua tabella crescerà sempre alla fine.

Una chiave primaria è CLUSTERED per impostazione predefinita e la maggior parte delle volte non devi preoccuparti.

Mi è stato detto che l'inserimento e l'eliminazione sono lenti con gli indici non cluster poiché l'albero deve essere "ricostruito". Suppongo che gli indici cluster non influiscano sulle prestazioni in questo modo?

In realtà, può essere vero il contrario. Gli indici NONCLUSTERED sono mantenuti come una struttura di dati separata, ma la struttura è progettata per consentire alcune modifiche senza la necessità di essere "ricostruita". Quando l'indice viene inizialmente creato, è possibile specificare FILLFACTOR , che specifica la quantità di spazio libero da lasciare su ciascuna pagina dell'indice. Ciò consente all'indice di tollerare alcune modifiche prima che sia necessaria una divisione della pagina. Anche quando deve verificarsi una divisione di pagina, influisce solo sulle pagine vicine, non sull'intero indice.

Lo stesso comportamento si applica agli indici CLUSTERED , ma poiché gli indici CLUSTERED memorizzano i dati effettivi della tabella, le operazioni di divisione delle pagine sull'indice possono essere molto più costose perché l'intera riga potrebbe essere necessario spostarlo (rispetto solo alle colonne chiave e al ROWID in un indice NONCLUSTERED )

La seguente pagina MSDN parla di FILLFACTOR e delle suddivisioni di pagina: http://msdn.microsoft.com/en-us /library/aa933139(SQL.80).aspx

Qual è la particolarità di una chiave primaria rispetto a un indice univoco raggruppato? In che modo i vincoli sono diversi dagli indici?

Per entrambi penso che si tratti più di dichiarare le tue intenzioni. Quando chiami qualcosa un PRIMARY KEY stai dichiarando che è il metodo principale per identificare una determinata riga. Un PRIMARY KEY è fisicamente diverso da un CLUSTERED UNIQUE INDEX ? Non ne sono sicuro. Il comportamento è essenzialmente lo stesso, ma le tue intenzioni potrebbero non essere chiare a qualcuno che lavora con il tuo database.

Per quanto riguarda i vincoli, esistono molti tipi di vincoli. Per un UNIQUE CONSTRAINT , non c'è davvero alcuna differenza tra questo e un UNIQUE INDEX , oltre a dichiarare la tua intenzione. Esistono altri tipi di vincoli che non si associano direttamente a un tipo di indice, come i vincoli CHECK , i vincoli DEFAULT e i vincoli FOREIGN KEY .

Non ho tempo di rispondere in modo approfondito, quindi ecco alcune informazioni in cima alla mia testa:

Hai ragione sugli indici cluster. Riorganizzano i dati fisici in base all'ordinamento dell'indice cluster. Puoi utilizzare gli indici cluster in modo specifico per le query con intervallo (ad es. Tra le date).

I PK sono raggruppati per impostazione predefinita, ma non devono esserlo. Questa è solo un'impostazione predefinita. Il PK dovrebbe essere un UID per la riga.

I vincoli possono essere implementati come indici (ad esempio, vincoli univoci), ma possono anche essere implementati come valori predefiniti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top