Chiavi esterne: collegamento tramite surrogato o chiave naturale?


14

Esiste una procedura ottimale per stabilire se una chiave esterna tra le tabelle deve essere collegata a una chiave naturale o una chiave surrogata? L'unica discussione che ho trovato (a meno che non manchi il mio google-fu) è la risposta di Jack Douglas in questa domanda , e il suo ragionamento mi sembra ragionevole. Sono consapevole della discussione al di là del fatto che le regole cambiano, ma questo sarebbe qualcosa che dovrebbe essere considerato in ogni situazione.

Il motivo principale per cui mi chiedo è che ho un'applicazione legacy che fa uso di FK con chiavi naturali, ma c'è una forte spinta da parte dei devlopers per passare a un OR / M (NHibernate nel nostro caso), e un fork ha già prodotto alcuni interrompendo le modifiche, quindi sto cercando di rimetterle in carreggiata utilizzando il tasto naturale o spostare l'app legacy per utilizzare i tasti surrogati per l'FK. Il mio istinto dice di ripristinare l'FK originale, ma sinceramente non sono sicuro che questa sia davvero la strada giusta da seguire.

La maggior parte delle nostre tabelle ha già sia una chiave surrogata che una chiave naturale già definite (sebbene vincolo univoco e PK), quindi dover aggiungere colonne extra non è un problema per noi in questa assicurazione. Stiamo usando SQL Server 2008, ma spero che sia abbastanza generico per qualsiasi DB.

Risposte:


15

Né SQL né il modello relazionale sono disturbati da chiavi esterne che fanno riferimento a una chiave naturale. In effetti, fare riferimento a chiavi naturali spesso migliora notevolmente le prestazioni. Saresti sorpreso di quanto spesso le informazioni di cui hai bisogno siano completamente contenute in una chiave naturale; facendo riferimento a tale chiave viene scambiato un join per una tabella più ampia (e di conseguenza riduce il numero di righe che è possibile memorizzare in una pagina).

Per definizione, le informazioni di cui hai bisogno sono sempre completamente contenute nella chiave naturale di ogni tabella "lookup". (Il termine tabella di ricerca è informale. Nel modello relazionale, tutte le tabelle sono solo tabelle. Una tabella di codici postali statunitensi potrebbe avere righe simili alle seguenti: {AK, Alaska}, {AL, Alabama}, {AZ, Arizona} , ecc. La maggior parte delle persone chiamerebbe questa tabella di ricerca.)

Sui sistemi di grandi dimensioni, non è insolito trovare tabelle con più chiavi candidate. Inoltre, non è insolito che le tabelle che servono una parte dell'azienda facciano riferimento a una chiave candidata e le tabelle che servono un'altra parte dell'azienda facciano riferimento a una chiave candidata diversa. Questo è uno dei punti di forza del modello relazionale ed è una parte del modello relazionale che SQL supporta abbastanza bene.

Incontrerai due problemi quando fai riferimento a chiavi naturali in tabelle che hanno anche una chiave surrogata.

Innanzitutto, sorprenderai le persone. Anche se di solito faccio pressioni per il Principio della minima sorpresa , questa è una situazione in cui non mi dispiace sorprendere le persone. Quando il problema è che gli sviluppatori sono sorpresi dall'uso logico di chiavi esterne, la soluzione è l'educazione, non la riprogettazione.

In secondo luogo, gli ORM non sono generalmente progettati attorno al modello relazionale e talvolta incarnano ipotesi che non riflettono le migliori pratiche. (In effetti, spesso sembrano essere progettati senza mai avere input da un professionista del database.) La richiesta di un numero ID in ogni tabella è una di quelle ipotesi. Un altro presuppone che l'applicazione ORM "possieda" il database. (Quindi è libero di creare, eliminare e rinominare tabelle e colonne.)

Ho lavorato su un sistema di database che ha fornito dati a centinaia di programmi applicativi scritti in almeno due dozzine di lingue per un periodo di 30 anni. Tale database appartiene all'azienda, non a un ORM.

Una forcella che introduce cambiamenti di rottura dovrebbe essere un punto fermo.

Ho misurato le prestazioni con chiavi sia naturali sia surrogate presso un'azienda in cui lavoravo. C'è un punto di non ritorno in cui le chiavi surrogate iniziano a sovraperformare le chiavi naturali. (Supponendo che nessuno sforzo aggiuntivo per mantenere elevate le prestazioni delle chiavi naturali, come il partizionamento, gli indici parziali, gli indici basati su funzioni, i tablespace aggiuntivi, l'utilizzo di dischi a stato solido, ecc.) Secondo le mie stime per quella società, raggiungeranno quel punto di svolta in circa 2045. Nel frattempo, ottengono prestazioni migliori con tasti naturali.

Altre risposte pertinenti: In Confusione dello schema del database


5

Il motivo principale per cui sostengo le chiavi surrogate è che le chiavi naturali sono spesso soggette a modifiche e ciò significa che tutte le tabelle correlate devono essere aggiornate, il che può caricare molto il server.

Inoltre negli ultimi 30 anni ho usato una varietà di database su molti argomenti, la vera chiave naturale è spesso abbastanza rara. Le cose presumibilmente uniche (SSN) non lo sono, cose che sono uniche in un determinato momento possono diventare non univoci in seguito e alcune cose come indirizzi e-mail e numeri di telefono possono essere univoci, ma possono essere riutilizzate per persone diverse in un secondo momento Data. Naturalmente alcune cose semplicemente non hanno un buon identificatore univoco come i nomi di persone e società.

Come evitare i join usando una chiave naturale. Sì, ciò può accelerare le istruzioni selezionate che non necessitano dei join, ma farà sì che i punti in cui sono ancora necessari i join siano più lenti poiché i join int sono generalmente più veloci. Probabilmente rallenterà anche inserimenti ed eliminazioni e causerà problemi di prestazioni sugli aggiornamenti quando la chiave cambia. Le query complesse (che sono comunque più lente) saranno anche più lente. Quindi le query semplici sono più veloci ma la creazione di report e query complesse e molte azioni sul database possono essere più lente. È un atto di bilanciamento, che può ribaltarsi in un modo o nell'altro a seconda di come viene interrogato il database.

Quindi non esiste una risposta a taglia unica. Dipende dal database e da come verrà eseguita la query e dal tipo di informazioni archiviate al suo interno. Potrebbe essere necessario eseguire alcuni test per scoprire cosa funziona meglio nel proprio ambiente.


1
"... le chiavi naturali sono spesso soggette a modifiche ..." - quindi non sono chiavi molto buone! Se un attributo cambia spesso, non usarlo come chiave (ovviamente per varie definizioni di "spesso"). Fabian Pascal ha sostenuto che ci sono quattro criteri per scegliere una chiave: familiarità, irriducibilità, stabilità e semplicità. A volte si scambiano questi per la semplicità di una chiave surrogata. Come diceva HLGEM, "Quindi non esiste una risposta per tutte le dimensioni".
Greenstone Walker

1
@GreenstoneWalker, sono d'accordo che non dovresti sceglierlo come chiave allora, ma spesso non hai una chiave che si adatta a tutti e quattro i criteri e devi andare con ciò che è unico. E quando l'unicità è una chiave copmposita, il problema può essere ancora maggiore in termini di prestazioni quando è necessario disporre dei join.
HLGEM,

-4

Se non conosci la risposta, vai con il surrogato. Ecco perché: se vengono fatte ipotesi sulle regole aziendali e tali ipotesi sono false o le regole cambiano, i tuoi dati sono spazzatura. Ecco un esempio:

Persona, ruolo, ruolo personale

l'attuale regola aziendale afferma che una persona ha un ruolo. Si crea una tabella che collega Person e Role in cui PersonRole (PersonName, PersonBirthDate, PersonMotherMaidenName, ..., RoleCode)

Ora sei un vero purista quando si tratta di Natural Keys! Ma seriamente, cosa succede se l'organizzazione decide che una persona può ora assumere più ruoli? Quali sono gli effetti a valle del supporto al cambiamento delle esigenze aziendali?


2
E non hai questi problemi con le chiavi surrogate? Per favore, mostraci come.
Colin 't Hart,

4
L'esempio fornito non sembra dimostrare nulla di rilevante per la discussione.
Mustaccio,
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.