Perché usare un int come chiave primaria di una tabella di ricerca?


30

Voglio sapere perché dovrei usare un int come chiave primaria di una tabella di ricerca invece di usare semplicemente il valore di ricerca come chiave primaria (che nella maggior parte dei casi sarebbe una stringa).

Capisco che l'uso di un nvarchar (50) anziché di un int utilizzerebbe molto più spazio se è collegato a una tabella con molti record.

D'altra parte, l'uso diretto del valore di ricerca ci salverebbe sostanzialmente facendo un join. Immagino che questo sarebbe un grande risparmio se il join è sempre necessario (stiamo lavorando su un'app Web quindi questo conta parecchio).

Quali sono i vantaggi dell'utilizzo di una chiave primaria int (in particolare per una tabella di ricerca) oltre a essere "la cosa standard da fare"?


4
Puoi trovare buone informazioni e forse anche la risposta necessaria in queste 2 domande precedenti: c'è qualche vantaggio in una chiave primaria che comprende tutte le colonne della tabella? e chiavi primarie Character vs Integer .
Marian,

Risposte:


23

La risposta alla tua domanda è logica, non fisica: il valore che cerchi potrebbe cambiare per motivi di lavoro. Ad esempio, se indicizzi i tuoi clienti per indirizzo e-mail, cosa succede quando un indirizzo e-mail cambia? Ovviamente questo non si applica a tutte le tue tabelle di ricerca, ma i vantaggi di farlo allo stesso modo nell'intera applicazione sono che semplifica il tuo codice. Se tutto è intero → relazioni intere internamente, sei coperto.

Leggi il tuo commento a Sandy - forse in questo caso quello che vuoi davvero è un vincolo di controllo , non una chiave esterna / tabella di ricerca, ad esempio:

create table icecream (flavour varchar(10))
go
alter table icecream add constraint ck_flavour check (flavour in ('Orange', 'Pista', 'Mango'))
go
insert into icecream (flavour) values ('Orange')
go
insert into icecream (flavour) values ('Vanilla')
go

Esegui questo e otterrai:

(1 row(s) affected)
Msg 547, Level 16, State 0, Line 1
The INSERT statement conflicted with the CHECK constraint "ck_flavour". The conflict occurred in database "GAIUSDB", table "dbo.icecream", column 'flavour'.
The statement has been terminated.

Si tratta di un metodo efficiente e ad alte prestazioni, ma lo svantaggio ovviamente è che l'aggiunta di un nuovo sapore comporta una modifica del codice. Vorrei sconsigliarmi di farlo nell'applicazione - perché quindi è necessario farlo in ogni app che si collega a questo DB, questo è il design più pulito possibile perché esiste un solo percorso di codice per eseguire la convalida.


@ Gaius- Buon esempio ... Preferisco non usare Controlla vincolo per questo tipo di scenario; motivo principale per cui non sarà mantenibile (l'hai segnalato come svantaggio).
CoderHawk,

1
@Sandy Dipende molto dai dati, dalla frequenza con cui cambieranno e da dove altro verranno utilizzati. Ad esempio, se il vincolo deve essere applicato dal DB, ma i valori potrebbero anche essere utilizzati per popolare un menu a discesa o in un report, una chiave esterna sarebbe più appropriata. Ad ogni modo, sconsiglio di farlo nella domanda.
Gaius,

7

"Utilizzo diretto del valore di ricerca": è un po 'contraddittorio rispetto allo scopo effettivo della tabella di ricerca. Perché stai tenendo un tavolo del genere? Se non è una ricerca.
Forse ho frainteso la tua domanda. Ecco una definizione della tabella di ricerca da msdn

Una tabella di ricerca viene utilizzata per visualizzare informazioni da una tabella in base al valore di un campo chiave esterna in un'altra tabella. Ad esempio, prendere in considerazione una tabella di ordini in un database di vendita. Ogni record nella tabella degli ordini include un ID cliente che indica quale cliente ha effettuato l'ordine. CustomerID è una chiave esterna che punta a un record cliente nella tabella Clienti. Quando si presenta un elenco di ordini (dalla tabella Ordini), è possibile che si desideri visualizzare il nome effettivo dei clienti, anziché ID cliente. Poiché il nome dei clienti si trova nella tabella dei clienti e si stanno presentando i dati dalla tabella degli ordini, è necessario creare una tabella di ricerca, che accetta il valore ID cliente nel record Ordini e utilizza tale valore per esplorare la relazione e restituire più leggibile, nome del cliente.

Puoi chiarire lo scopo della tua tabella di ricerca? viene utilizzato per memorizzare alcuni dati statici come il seguente e questi record non sono un input di altri record di tabelle?

Tavolo dei sapori

Orange  
Pista  
Mango

Se sopra è la tua situazione, allora vorrei raccomandare di non usare la tabella di ricerca; probabilmente codificare questi valori di elenco nell'applicazione Web. In questo modo è possibile evitare query di database non necessarie.


1
buon punto, lo scopo della mia tabella di ricerca è fondamentalmente solo quello di imporre i diversi valori che una colonna può avere tramite un vincolo di chiave esterna. Sono d'accordo che codificarlo nell'applicazione potrebbe essere un altro modo di gestirlo.
Jaco Brier,

@Jaco Brier - Vedi la risposta di Gaius ... usa Controlla vincolo ...
CoderHawk

7

Dal momento che hai qualificato la tua domanda con "specificamente per una tabella di ricerca", la risposta è probabilmente semplificata fino a "salva spazio".

Penso che se rimuovi quel qualificatore, la tua domanda diventa "Perché usare le chiavi surrogate rispetto alle chiavi naturali?" Ho scritto quanto segue a supporto delle chiavi surrogate:

"La migrazione di un valore intero anziché di una chiave composta più ampia offre numerosi vantaggi. Offre una buona coerenza in tutto il modello fisico, in generale consente di risparmiare più spazio di quanto costa e riduce l'I / O rispetto alla migrazione di chiavi composte; soprattutto in un pozzo modello normalizzato. Inoltre, semplificano la comprensione di un modello e dei join di query. "

Questo è in gran parte il motivo per cui è "diventata la cosa standard da fare". Lo sfortunato sottoprodotto è che le persone indossano una chiave surrogata e non pensano quali siano le chiavi candidate ... Ma ora stiamo uscendo dalla tua domanda :)


3

Uno dei motivi che uso sempre è che se qualcuno ha sbagliato a scrivere un valore nella tabella di ricerca, ad esempio Oraneg invece di Orange, è molto facile cambiare il valore nella tabella di ricerca.

La tabella di ricerca con una chiave primaria numerica richiede solo che il valore venga modificato nella tabella di ricerca.

La tabella di ricerca che utilizza i valori come chiave primaria dovrà essere modificata nella tabella di ricerca e in ogni record della tabella principale in cui è stata utilizzata.


2

Quando si definisce ID, è inoltre possibile garantire l'unicità. Ma quando prendi, ad esempio la posta elettronica, come identificativo univoco, trasferisci la responsabilità dell'unicità alla terza parte non attendibile.

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.