Surrogate vs. chiavi naturali / aziendali [chiuso]


174

Eccoci di nuovo, la vecchia discussione sorge ancora ...

Avremmo meglio avere una chiave aziendale come chiave primaria o preferiremmo avere un ID surrogato (ovvero un'identità di SQL Server) con un vincolo univoco sul campo della chiave aziendale?

Fornisci esempi o prove a supporto della tua teoria.


24
@Joachim Sauer: Una discussione sul fatto che una cosa sia soggettiva può essere essa stessa soggettiva, senza che ciò si riferisca in alcun modo all'oggettività o alla soggettività della cosa in questione. A meno che tu non sia disposto a dichiarare i criteri oggettivi esatti che rendono qualcosa di oggettivo. Ci sono cose chiamate "concetti aperti" come quanti peli ci vogliono per farsi la barba. Si può obiettivamente affermare che una persona senza peli del mento non ha la barba, e una con 5.000 capelli di un pollice di lunghezza ha la barba, ma da qualche parte nel giudizio soggettivo intermedio è necessaria una decisione oggettiva.
ErikE,

@Manrico: devi solo chiederti questo: se non uso una chiave surrogata, la mia chiave primaria sarà ancora immutabile? Se la risposta è no, allora dovresti prendere seriamente in considerazione l'uso di una chiave surrogata. Inoltre, se la chiave primaria è composta anche parzialmente da input dell'utente, dovresti considerare l'utilizzo di una chiave surrogata. Perché? A causa del pericolo di anomalie dei dati.
code4life

@TylerRick Ma questa non è una domanda perfettamente valida. Chiede una soluzione che sia generalmente applicabile a tutte le situazioni, quando chiaramente non ce n'è una, come dimostrato dalla "guerra religiosa" di cui l'interlocutore è perfettamente consapevole (citazione: "Eccoci di nuovo, sorge ancora la vecchia argomentazione. .. "). Invece di chiedersi se il mondo è cambiato e, infine, è stata fornita una ragione convincente per scegliere un lato tutte le volte, è meglio continuare a porre questa domanda più e più volte per ogni situazione concreta e pubblicare su SO quando non si è sicuri . Questo suscita solo dogmatismo.
MarioDS,

Risposte:


97

Tutti e due. Prendi la tua torta e mangiala.

Ricorda che non c'è nulla di speciale in una chiave primaria, tranne che è etichettata come tale. Non è altro che un vincolo NOT NULL UNIQUE e una tabella può avere più di uno.

Se si utilizza una chiave surrogata, si desidera comunque una chiave aziendale per garantire l'univocità in base alle regole aziendali.


7
Se hai più chiavi "candidate" (campi o raccolte di campi della stessa dimensione che NON SONO UNICHE NULL) allora probabilmente stai violando il modulo normale di Boyce-Codd. BCNF è oltre 3NF, quindi non molte persone se ne preoccupano. Ci sono situazioni, tuttavia, in cui essere in BCNF è molto utile.
Alan,

2
Concordato. La vera domanda dovrebbe essere: devo aggiungere una chiave surrogata unica alle mie tabelle? Un'intera altra domanda è cosa usare per una chiave primaria logica. Entrambi sono essenzialmente solo vincoli di indice univoci non nulli.
dkretz,

1
"Ogni problema è risolto con un altro livello di riferimento indiretto" ... Le chiavi surrogate sono proprio questo: un altro livello di riferimento indiretto
Steve Schnepp,

5
Trovo strano che molti commenti sembrino affermare che non è possibile impostare una relazione senza una chiave surrogata. In molti casi, la chiave surrogata è superflua. Perché aggiungere qualcosa che non porta valore ma aggiunge debito tecnico (e in alcuni casi, fa sì che un risultato altrimenti unico diventi improvvisamente non unico).
Wil Moore III,

2
È più del vincolo NOT NULL UNIQUE. La chiave primaria viene utilizzata come indice cluster che determina l'ordine fisico dei dati. In generale, Integer è facile da bilanciare poiché aumenta in sequenza e i dati verranno aggiunti all'EOF su disco. Se usi meno dati sequenziali come testo o GUID (UUID), ci saranno molti più IO sul disco e sforzi per bilanciare l'indice, penso che sia una specie di grande differenza
Jin

124

Solo alcuni motivi per usare le chiavi surrogate:

  1. Stabilità : la modifica di una chiave a causa di un'attività o di un'esigenza naturale influirà negativamente sulle tabelle correlate. Le chiavi surrogate raramente, se mai, devono essere modificate perché non vi è alcun significato legato al valore.

  2. Convenzione : consente di disporre di una convenzione standardizzata di denominazione delle colonne della chiave primaria anziché dover pensare a come unire le tabelle con vari nomi per i loro PK.

  3. Velocità : a seconda del valore e del tipo PK, una chiave surrogata di un numero intero può essere più piccola, più veloce da indicizzare e cercare.


2
Ora, dopo aver letto molto su chiavi surrogate e chiavi naturali, penso che usare le chiavi surrogate sia meglio. Ma, nel mio database, le chiavi naturali (una NVARCHAR (20)) devono essere uniche. Non capisco come posso ottenere più velocità se devo controllare tutti i dati su quella colonna per non ripetere alcun valore (usando un vincolo NOT NULL UNIQUE) su ogni inserto.
VansFannel,

70

Sembra che nessuno abbia ancora detto nulla a sostegno di chiavi non surrogate (esito a dire "naturale"). Quindi ecco qui ...

Uno svantaggio delle chiavi surrogate è che sono insignificanti (citate come vantaggio da alcuni, ma ...). Questo a volte ti costringe a unire molte più tabelle alla tua query di quanto dovrebbe essere realmente necessario. Confrontare:

select sum(t.hours)
from timesheets t
where t.dept_code = 'HR'
and t.status = 'VALID'
and t.project_code = 'MYPROJECT'
and t.task = 'BUILD';

contro:

select sum(t.hours)
from timesheets t
     join departents d on d.dept_id = t.dept_id
     join timesheet_statuses s on s.status_id = t.status_id
     join projects p on p.project_id = t.project_id
     join tasks k on k.task_id = t.task_id
where d.dept_code = 'HR'
and s.status = 'VALID'
and p.project_code = 'MYPROJECT'
and k.task_code = 'BUILD';

A meno che qualcuno non pensi seriamente che sia una buona idea:

select sum(t.hours)
from timesheets t
where t.dept_id = 34394
and t.status_id = 89    
and t.project_id = 1253
and t.task_id = 77;

"Ma" qualcuno dirà "cosa succede quando il codice per MYPROJECT o VALID o HR cambia?" Al che la mia risposta sarebbe: "perché si ha bisogno di cambiarlo?" Queste non sono chiavi "naturali", nel senso che qualche ente esterno sta per legiferare che d'ora in poi "VALID" dovrebbe essere ricodificato come "BUONO". Solo una piccola percentuale di chiavi "naturali" rientra davvero in quella categoria - SSN e codice postale sono i soliti esempi. Utilizzerei sicuramente un tasto numerico insignificante per tabelle come Persona, Indirizzo - ma non per tutto , che per qualche motivo la maggior parte delle persone qui sembrano sostenere.

Vedi anche: la mia risposta a un'altra domanda


14
-1 Le chiavi naturali come chiave primaria hanno il problema che per ogni tabella figlio devi aggiungere la chiave del genitore che può essere composta da più di un campo (invece di uno solo nel caso di una chiave surrogata) e anche il figlio chiave. Quindi immagina quanto segue a partire da TABLEA la relazione è 1-0 .. *: TABLEA PK: ID_A TABLEB PK: ID_A ID_B TABLEC PK: ID_A ID_B ID_C TABLED PK: ID_A ID_B ID_C ID_C ID_C. Vedi il problema? La chiave padre viene propagata nelle tabelle figlio. Cosa succederebbe se cambiasse la chiave primaria di TABLEA? Ora dovresti rifattare anche tutti i tavoli secondari PK.
Alfredo Osorio,

9
@Alfredo: sì, certo, c'è un compromesso. Tuttavia, nei miei oltre 20 anni di esperienza, raramente ho visto la definizione di cambiamento di PK di una tabella. Se succedesse regolarmente, probabilmente eviterei anche le chiavi naturali. In realtà, nelle occasioni estremamente rare che ciò accade, sono pronto a prendere il colpo dell'impatto esteso.
Tony Andrews,

10
Non sono d'accordo. È spesso il caso in cui un ente esterno (il cliente) legifichi che una chiave naturale debba essere modificata e quindi propagata in tutto il sistema. Vedo che questo accade regolarmente. L'unico modo in cui puoi essere sicuro che la chiave non dovrà mai cambiare è quando è per definizione insignificante. Inoltre, i database moderni gestiscono i join interni in modo estremamente efficiente, quindi i guadagni di spazio potenzialmente grandi derivanti dall'utilizzo di surrogati in genere superano il vantaggio di non dover fare altrettanti join interni.
TTT,

8
@TTT: Quindi il design era debole all'inizio. Ancora una volta, è lì che gli uomini si separano dai ragazzi: fare la scelta giusta su quando usare la chiave naturale e quando usare un surrogato. Lo decidi in base alla tabella, non come dogma generale.
DanMan,

7
Ho anche più di 20 anni di esperienza e secondo la tua opinione. Una volta ho creato un datawarehouse oracle con chiavi surrogate e la manutenzione dei dati è stata un inferno. Semplicemente non puoi mai accedere direttamente ai tuoi dati. devi sempre scrivere query per tutto, e questo rende le chiavi surrogate semplicemente terribili da gestire.
SQL Police,

31

La chiave surrogata non avrà MAI un motivo per cambiare. Non posso dire lo stesso delle chiavi naturali. Cognome, e-mail, nubmers ISBN: tutti possono cambiare un giorno.


31

Le chiavi surrogate (in genere numeri interi) hanno il valore aggiunto di rendere più veloci le relazioni tra tabelle e una maggiore velocità di archiviazione e velocità di aggiornamento (ancora meglio, le chiavi esterne non devono essere aggiornate quando si utilizzano chiavi surrogate, a differenza dei campi chiave aziendale, che cambiano di tanto in tanto).

La chiave primaria di una tabella deve essere utilizzata per identificare in modo univoco la riga, principalmente per scopi di join. Pensa a una tabella Persone: i nomi possono cambiare e non sono garantiti univoci.

Pensa alle aziende: sei una felice azienda Merkin che fa affari con altre società in Merkia. Sei abbastanza intelligente da non usare il nome dell'azienda come chiave primaria, quindi usi l'ID azienda univoco del governo Merkia in tutti i suoi 10 caratteri alfanumerici. Quindi Merkia cambia gli ID dell'azienda perché pensava che sarebbe stata una buona idea. Va bene, usi la funzionalità di aggiornamento in cascata del tuo motore db, per una modifica che non dovrebbe coinvolgerti in primo luogo. Successivamente, la tua attività si espande e ora lavori con un'azienda in Freedonia. L'ID società freedonian ha un massimo di 16 caratteri. È necessario ingrandire la chiave primaria dell'ID società (anche i campi della chiave esterna in Ordini, Problemi, Trasferimenti di denaro, ecc.), Aggiungendo un campo Paese nella chiave primaria (anche nelle chiavi esterne). Ahia! Guerra civile in Freedonia, e ' s diviso in tre paesi. Il nome del paese del tuo associato dovrebbe essere cambiato in quello nuovo; aggiornamenti in cascata per il salvataggio. A proposito, qual è la tua chiave primaria? (Paese, ID azienda) o (ID azienda, Paese)? Il secondo aiuta ad aderire, il primo evita un altro indice (o forse molti, se vuoi che anche i tuoi ordini vengano raggruppati per paese).

Tutti questi non sono una prova, ma un'indicazione che una chiave surrogata per identificare in modo univoco una riga per tutti gli usi, comprese le operazioni di join, è preferibile a una chiave aziendale.


Vinci tutti gli internet con il nome utente più bello!
Iain Holder,

1
Questo è praticamente ciò che un downvote è: "Non sono d'accordo con questo".
jcollum,

5
La descrizione della freccia giù dice "Questa risposta non è utile", non "Non sono d'accordo con questo". Forse in questa risposta specifica i significati sono vicini, ma generalmente non sono gli stessi.
Tzot

1
Se qualcuno pensa che la tua risposta sia sbagliata, allora anche lui / lei penserà che condurrà l'interrogante nella direzione sbagliata (opposta alla giusta direzione) e quindi giudicherà la tua risposta come addirittura peggiore di "inutile", giustificando nella sua mente un voto negativo.
Erwin Smout,

1
Sì, le chiavi surrogate sono una malattia. Uno perde nel selvaggio e lo usi come una chiave, quindi ora hai bisogno della tua chiave surrogata. Quindi la tua chiave perde in natura (diciamo attraverso un url) e la malattia si diffonde.
Samuel Danielson,

25

Odio le chiavi surrogate in generale. Dovrebbero essere utilizzati solo quando non è disponibile una chiave naturale di qualità. È piuttosto assurdo quando ci pensi, pensare che l'aggiunta di dati insignificanti alla tua tabella possa migliorare le cose.

Ecco i miei motivi:

  1. Quando si usano le chiavi naturali, le tabelle sono raggruppate nel modo in cui vengono spesso cercate, rendendo le query più veloci.

  2. Quando si utilizzano chiavi surrogate è necessario aggiungere indici univoci su colonne di chiavi logiche. È ancora necessario impedire dati duplicati logici. Ad esempio, non è possibile consentire a due organizzazioni con lo stesso nome nella tabella Organizzazione anche se pk è una colonna ID surrogata.

  3. Quando le chiavi surrogate vengono utilizzate come chiave primaria, è molto meno chiaro quali siano le chiavi primarie naturali. Durante lo sviluppo, vuoi sapere quale set di colonne rende unica la tabella.

  4. In una o più catene di relazioni, le catene chiave logiche. Ad esempio, le organizzazioni hanno molti account e gli account hanno molte fatture. Quindi la chiave logica dell'organizzazione è OrgName. La chiave logica di Account è OrgName, AccountID. La chiave logica di Invoice è OrgName, AccountID, InvoiceNumber.

    Quando vengono utilizzate chiavi surrogate, le catene chiave vengono troncate avendo solo una chiave esterna per il genitore immediato. Ad esempio, la tabella delle fatture non ha una colonna OrgName. Ha solo una colonna per AccountID. Se desideri cercare fatture per una determinata organizzazione, dovrai unirti alle tabelle Organizzazione, Account e Fattura. Se si utilizzano chiavi logiche, è possibile eseguire una query direttamente nella tabella Organizzazione.

  5. La memorizzazione di valori chiave surrogati delle tabelle di ricerca provoca il riempimento di tabelle con numeri interi senza significato. Per visualizzare i dati, è necessario creare viste complesse che si uniscano a tutte le tabelle di ricerca. Una tabella di ricerca deve contenere un set di valori accettabili per una colonna. Non dovrebbe essere codificato memorizzando invece una chiave surrogata intera. Non c'è nulla nelle regole di normalizzazione che suggeriscono che è necessario memorizzare un numero intero surrogato invece del valore stesso.

  6. Ho tre diversi libri di database. Nessuno di loro mostra l'uso di chiavi surrogate.


7
Odio le chiavi surrogate, tranne quando sono necessarie. Sono necessari quando l'impresa utilizza una chiave naturale soggetta a molti errori e non sono disposti a tollerare un database che è interessato da tali errori.
Walter Mitty,

26
-1: ho scritto e mantenuto dozzine di applicazioni. Quelli con i maggiori problemi relativi ai dati erano quelli che utilizzavano le chiavi naturali.
Falcon,

6
Alcuni dei tuoi punti presumono che la chiave surrogata debba essere la PK o debba essere la colonna raggruppata - non vera. I tuoi punti 1 e 5 ignorano il fatto che i numeri interi sono 4 byte e le chiavi naturali sono quasi sempre molti, molti più byte. Inoltre, ogni indice non cluster deve ripetere i byte di quelle chiavi naturali che si trovano nell'indice cluster, quindi le tabelle e gli indici nel database delle chiavi naturali avranno molte, molte meno righe per pagina, il che si traduce in prestazioni di lettura molto peggiori , che rende le query più lente , non più veloci.
ErikE,

3
Un altro motivo contro le chiavi naturali (esempi: numeri atomici, VIN, ecc.), Può cambiare la logica aziendale che aumenta il tipo di dati. Ad esempio: Prima: tracciare le cariche di atomi, dopo: tenere traccia delle cariche di atomi e composti. Prima: monitoraggio dei veicoli a motore per la capacità di carico. Dopo: aggiunta di aerei, barche, biciclette e persone per la capacità di carico.
forforf,

3
Suppongo che non ci siano tabelle in cui la chiave primaria è composta anche parzialmente da 1) qualsiasi attributo che può e cambierà), o 2) dall'input dell'utente (ad es. Elenchi di ricerca generati dinamicamente). Se non è possibile garantire l'immutabilità delle chiavi, sarà necessario aggiornare tutte queste relazioni tra entità mediante codice o script di "correzione" manuali. Se non hai mai dovuto farlo ... Immagino che il tuo database sia sia surrogato senza chiave sia ... insolito.
code4life

18

Voglio condividere la mia esperienza con te in questa guerra infinita: D sul dilemma chiave naturale vs surrogato. Penso che sia le chiavi surrogate (quelle generate automaticamente artificiali) sia le chiavi naturali (composte da colonne con significato di dominio) hanno pro e contro . Quindi, a seconda della situazione, potrebbe essere più pertinente scegliere un metodo o l'altro.

Dato che molte persone presentano chiavi surrogate come la soluzione quasi perfetta e chiavi naturali come la peste, mi concentrerò sugli argomenti dell'altro punto di vista:

Svantaggi delle chiavi surrogate

Le chiavi surrogate sono:

  1. Fonte di problemi di prestazioni:
    • Di solito sono implementati usando colonne auto-incrementate che significano:
      • Un viaggio di andata e ritorno nel database ogni volta che si desidera ottenere un nuovo ID (so che questo può essere migliorato utilizzando la cache o algoritmi simili [seq] hilo ma comunque questi metodi hanno i loro svantaggi).
      • Se un giorno dovessi spostare i tuoi dati da uno schema all'altro (succede almeno abbastanza regolarmente nella mia azienda), potresti riscontrare problemi di collisione dell'ID. E sì, lo so che puoi usare gli UUID, ma questi ultimi richiedono 32 cifre esadecimali! (Se ti interessa la dimensione del database, può trattarsi di un problema).
      • Se stai usando una sequenza per tutte le tue chiavi surrogate, allora - sicuramente - finirai con una contesa sul tuo database.
  2. Incline a errori. Una sequenza ha un limite max_value quindi - come sviluppatore - devi porre attenzione ai seguenti punti:
    • È necessario scorrere la sequenza (quando viene raggiunto il valore massimo, torna a 1,2, ...).
    • Se si utilizza la sequenza come ordine (nel tempo) dei dati, è necessario gestire il caso del ciclo (la colonna con ID 1 potrebbe essere più recente della riga con valore massimo ID - 1).
    • Assicurati che il tuo codice (e anche le tue interfacce client che non dovrebbero accadere come dovrebbe essere un ID interno) supporta numeri interi 32b / 64b che hai usato per memorizzare i valori della sequenza.
  3. Non garantiscono dati non duplicati. Puoi sempre avere 2 righe con tutti gli stessi valori di colonna ma con un valore generato diverso. Per me questo è IL problema delle chiavi surrogate dal punto di vista della progettazione del database.
  4. Altro su Wikipedia ...

Miti su chiavi naturali

  1. Le chiavi composite sono meno inefficienti delle chiavi surrogate. No! Dipende dal motore di database utilizzato:
  2. Le chiavi naturali non esistono nella vita reale. Scusa ma esistono! Nel settore del trasporto aereo, per esempio, il seguente tuple sarà sempre unico per quanto riguarda una data programmata di volo (compagnia aerea, departureDate, numero di volo, operationalSuffix). Più in generale, quando un insieme di dati aziendali è garantito come unico da un determinato standard, questo insieme di dati è un candidato chiave [buono] naturale.
  3. Le chiavi naturali "inquinano lo schema" delle tabelle figlio. Per me questo è più un sentimento che un vero problema. Avere una chiave primaria a 4 colonne di 2 byte ciascuna potrebbe essere più efficiente di una singola colonna di 11 byte. Inoltre, le 4 colonne possono essere utilizzate per interrogare direttamente la tabella figlio (usando le 4 colonne in una clausola where) senza unirsi alla tabella padre.

Conclusione

Usa le chiavi naturali quando è importante farlo e usa le chiavi surrogate quando è meglio usarle.

Spero che questo abbia aiutato qualcuno!


3
Cosa succede quando la data di partenza del volo programmato viene riprogrammata? È necessario rintracciare tutte le entità correlate ed eliminare le chiavi o aggiornare effettivamente tutte le chiavi nelle entità correlate? O hai a che fare con un tavolo semplice e singolare (forse nemmeno 3NF)?
code4life

Eccellente punto @ code4life
volontà

@ code4life: È qui che interviene il suffisso operativo. Per mantenere lo stesso flightNumber in modo da evitare la confusione del cliente, aggiungiamo solo un suffisso (ad esempio "D").
Mwnsiri,

"Puoi sempre avere 2 righe con tutti gli stessi valori di colonna ma con un valore generato diverso", quindi aggiungi un vincolo univoco o univoco composito alle tue colonne.
wha7ever,

15

Utilizzare sempre una chiave che non ha significato commerciale. È solo una buona pratica.

EDIT: stavo cercando di trovare un link online, ma non ci sono riuscito. Tuttavia in "Patterns of Enterprise Archtecture" [Fowler] ha una buona spiegazione del perché non dovresti usare nient'altro che una chiave senza altro significato che essere una chiave. Si riduce al fatto che dovrebbe avere un solo lavoro e un solo lavoro.


22
Martin Fowler potrebbe essere molte cose, ma non è un'autorità nella progettazione di database.
Tony Andrews,

Penso che dovresti fornire alcuni ragionamenti prima di giungere alla conclusione.
Arne Evertsson,

4
@ArneEvertsoon Il motivo è lì. "Si riduce al fatto che dovrebbe avere un solo lavoro e un solo lavoro." Responsabilità unica.
Iain Holder,

10

Le chiavi surrogate sono molto utili se si prevede di utilizzare uno strumento ORM per gestire / generare le classi di dati. Mentre puoi usare chiavi composite con alcuni dei mappatori più avanzati (leggi: ibernazione), aggiunge una certa complessità al tuo codice.

(Naturalmente, i puristi del database sostengono che anche l'idea di una chiave surrogata è un abominio.)

Sono un fan dell'uso degli uid per le chiavi surrogate quando è adatto. La principale vittoria con loro è che conosci la chiave in anticipo, ad esempio puoi creare un'istanza di una classe con l'ID già impostato e garantito come univoco mentre con, diciamo, una chiave intera dovrai impostare come predefinito 0 o - 1 e aggiorna ad un valore appropriato quando salvi / aggiorni.

Gli UID hanno penalità in termini di ricerca e velocità di join, quindi dipende dall'applicazione in questione se sono desiderabili.


6

L'utilizzo di una chiave surrogata è migliore secondo me in quanto non vi è alcuna possibilità che cambi. Quasi tutto ciò a cui riesco a pensare che potresti usare come chiave naturale potrebbe cambiare (disclaimer: non sempre vero, ma comunemente).

Un esempio potrebbe essere un DB di auto: a prima vista, potresti pensare che la targa possa essere utilizzata come chiave. Ma questi potrebbero essere cambiati in modo che sarebbe una cattiva idea. Non vorrai davvero scoprirlo dopo aver rilasciato l'app, quando qualcuno viene da te per sapere perché non può cambiare la sua targa con la sua nuova brillante personalizzata.


1
Purtroppo le auto hanno una chiave naturale che non cambia: il VIN (almeno in America ...)
jcollum

@jcollum Sì ok, questo è un punto giusto. La mia opinione è ancora valida, il mio esempio non è stato necessariamente buono come potrebbe essere.
Mark Embling,

2
Un elenco di lingue sarebbe un esempio per una chiave naturale, quando la basi su codici ISO. Quindi, se poi si desidera caricare il contenuto di una tabella in una determinata lingua, non è necessario unirsi alla languagestabella poiché il codice della lingua (ID) è già presente nella textstabella.
DanMan,

@DanMan Devo essere d'accordo con te lì. Ci saranno sempre alcuni esempi che funzionano meglio con una chiave naturale. Le regole o gli approcci comuni non sono mai assoluti, e questo è un esempio che vorrei seguire al 100% con il tuo approccio :-)
Mark Embling,

5

Utilizzare sempre una singola colonna, chiave surrogata, se possibile. Ciò rende i join, nonché gli inserti / gli aggiornamenti / le eliminazioni molto più puliti perché sei responsabile solo di tenere traccia di una singola informazione per mantenere il record.

Quindi, se necessario, impila le chiavi della tua azienda come contorni o indici univoci. Ciò manterrà l'integrità dei dati intatta.

Le chiavi business logic / natural possono cambiare, ma la chiave fisica di una tabella non dovrebbe MAI cambiare.


4

In uno scenario di datawarehouse credo sia meglio seguire il percorso chiave surrogato. Due motivi:

  • Sei indipendente dal sistema di origine e le modifiche lì, ad esempio una modifica del tipo di dati, non ti influenzeranno.
  • Il tuo DW avrà bisogno di meno spazio fisico poiché utilizzerai solo tipi di dati interi per le tue chiavi surrogate. Anche i tuoi indici funzioneranno meglio.

2

Le chiavi surrogate possono essere utili quando le informazioni aziendali possono cambiare o essere identiche. I nomi delle imprese non devono essere univoci in tutto il paese, dopo tutto. Supponiamo che tu abbia a che fare con due aziende di nome Smith Electronics, una nel Kansas e una nel Michigan. Puoi distinguerli per indirizzo, ma questo cambierà. Anche lo stato può cambiare; cosa succederebbe se Smith Electronics di Kansas City, Kansas si trasferisse attraverso il fiume a Kansas City, Missouri? Non esiste un modo ovvio di mantenere distinte queste attività con informazioni chiave naturali, quindi una chiave surrogata è molto utile.

Pensa alla chiave surrogata come a un numero ISBN. Di solito, identifichi un libro per titolo e autore. Tuttavia, ho due libri intitolati "Pearl Harbor" di HP Willmott, e sono sicuramente libri diversi, non solo edizioni diverse. In un caso del genere, potrei riferirmi all'aspetto dei libri, o il precedente rispetto al successivo, ma è altrettanto bene che ho il codice ISBN su cui ripiegare.


1
Penso di non essere d'accordo con il tuo esempio qui. Un numero ISBN è un attributo di un libro. Una chiave surrogata è indipendente dal resto dei dati della riga, pertanto questa posizione è favorevole all'utilizzo di una chiave surrogata separata per una tabella di libri, anche se il codice ISBN identifica già in modo univoco ogni libro.
Christopher Cashell,

In alternativa, pensa al codice ISBN come chiave surrogata stessa. È un identificatore senza significato, solo un codice che viene applicato a un libro specifico. Se stai creando una tabella di libri, il codice ISBN potrebbe anche essere la chiave primaria (supponendo che tu abbia e avrai sempre un libro per riga).
David Thornley,

@Christopher Cashell - Mi sono imbattuto in questo post di un anno fa ma ho pensato di aggiungere qualcosa. I codici ISBN non sono garantiti come unici e possono avere duplicati. Ho un amico che ha lavorato in una biblioteca per un certo numero di anni e che spesso si imbattevano in libri con codici ISBN duplicati. Il problema è che l'unicità del codice ISBN dipende dall'editore piuttosto che da un solo organo che garantisca che tutti i numeri di tutte le pubblicazioni sono unici e quegli editori non hanno sempre agito insieme.
Thomas,

2
È arrivato attraverso questo post di un anno fa e volevo menzionare che i codici ISBN sono in realtà chiavi naturali. C'è un significato inserito nel valore della chiave stessa a differenza di una chiave surrogata. Ad esempio, parte della chiave identifica l'editore. Inoltre, come ho detto sopra, non sono garantiti per essere unici. Si suppone di essere unico, ma che l'unicità deriva dagli editori e non erano sempre perfetta.
Thomas,

Tecnicamente, le società non possono spostarsi tra gli stati; ciò che accade è che una nuova società viene creata nel nuovo stato e le attività vengono trasferite. Questo funziona anche per le informazioni del database.
Warren Dew,

2

Ricordiamo che non è buona norma posizionare indici cluster su chiavi surrogate casuali, ad esempio GUID che leggono XY8D7-DFD8S, poiché SQL Server non ha la capacità di ordinare fisicamente questi dati. Dovresti invece posizionare indici univoci su questi dati, anche se può essere utile eseguire semplicemente il profiler SQL per le operazioni della tabella principale e quindi posizionare tali dati in Ottimizzazione guidata motore di database.

Vedi thread @ http://social.msdn.microsoft.com/Forums/en-us/sqlgetstarted/thread/27bd9c77-ec31-44f1-ab7f-bd2cb13129be


Sono abbastanza sicuro che SQL Server possa ordinare i GUID.
Michael Green,

Questo non è accurato, mentre possono valutare il GUID, l'ordinamento risultante non è privo di senso per un essere umano. stackoverflow.com/questions/7810602/…
Bryan Swan

1
Un'affermazione vera, ma abbastanza diversa da "SQL Server non ha la capacità di ordinarli fisicamente".
Michael Green,

2

Caso 1: la tabella è una tabella di ricerca con meno di 50 tipi (inserti)

Usa chiavi aziendali / naturali . Per esempio:

Table: JOB with 50 inserts
CODE (primary key)       NAME               DESCRIPTION
PRG                      PROGRAMMER         A programmer is writing code
MNG                      MANAGER            A manager is doing whatever
CLN                      CLEANER            A cleaner cleans
...............
joined with
Table: PEOPLE with 100000 inserts

foreign key JOBCODE in table PEOPLE
looks at
primary key CODE in table JOB

Caso 2: la tabella è una tabella con migliaia di inserti

Utilizzare i tasti surrogato / autoincremento . Per esempio:

Table: ASSIGNMENT with 1000000 inserts
joined with
Table: PEOPLE with 100000 inserts

foreign key PEOPLEID in table ASSIGNMENT
looks at
primary key ID in table PEOPLE (autoincrement)

Nel primo caso:

  • È possibile selezionare tutti i programmatori nella tabella PEOPLE senza utilizzare join con la tabella JOB, ma solo con: "SELEZIONA * DA PERSONE DOVE JOBCODE = 'PRG'"

Nel secondo caso:

  • Le query del database sono più veloci perché la chiave primaria è un numero intero
  • Non è necessario preoccuparsi di trovare la chiave univoca successiva poiché il database stesso fornisce il successivo incremento automatico.

2

Questo è uno di quei casi in cui una chiave surrogata ha quasi sempre senso. Ci sono casi in cui puoi scegliere ciò che è meglio per il database o ciò che è meglio per il tuo modello di oggetto, ma in entrambi i casi, usare una chiave senza significato o GUID è un'idea migliore. Rende l'indicizzazione più semplice e veloce ed è un'identità per il tuo oggetto che non cambia.


1

Cavallo per corsi. Per dichiarare il mio pregiudizio; Prima sono uno sviluppatore, quindi mi occupo principalmente di fornire agli utenti un'applicazione funzionante.

Ho lavorato su sistemi con chiavi naturali e ho dovuto dedicare molto tempo ad assicurarmi che le variazioni di valore si propagassero.

Ho lavorato su sistemi con solo chiavi surrogate e l'unico inconveniente è stata la mancanza di dati denormalizzati per il partizionamento.

La maggior parte degli sviluppatori PL / SQL tradizionali con cui ho lavorato non amava le chiavi surrogate a causa del numero di tabelle per join, ma i nostri database di test e produzione non hanno mai sudato; i join extra non hanno influito sulle prestazioni dell'applicazione. Con i dialetti del database che non supportano clausole come "X inner join Y on Xa = Yb" o sviluppatori che non usano quella sintassi, i join extra per le chiavi surrogate rendono le query più difficili da leggere e più lunghe da digitare e controlla: vedi il post di @Tony Andrews. Ma se usi un ORM o qualsiasi altro framework di generazione SQL non lo noterai. Anche la digitazione tattile si attenua.


Anche; se vuoi davvero riportare a casa che le chiavi surrogate sono proprio questo, avviali con un numero casuale grande e incrementa le sequenze di 3+ ​​anziché di 1. Oppure usa la stessa sequenza per generare valori per più di una chiave.
WillC

1

Forse non è completamente pertinente a questo argomento, ma ho mal di testa con le chiavi surrogate. L'analisi preconfigurata di Oracle crea SK generati automaticamente su tutte le sue tabelle dimensionali nel magazzino e memorizza anche quelli sui fatti. Pertanto, ogni volta che devono essere ricaricate (dimensioni) quando vengono aggiunte nuove colonne o devono essere popolate per tutti gli elementi nella dimensione, gli SK assegnati durante l'aggiornamento rendono gli SK non sincronizzati con i valori originali memorizzati nel fatto, forzando una ricarica completa di tutte le tabelle dei fatti che vi si uniscono. Preferirei che anche se la SK fosse un numero insignificante, ci sarebbe un modo in cui non potrebbe cambiare per i record originali / vecchi. Come molti sanno, il pronto intervento raramente soddisfa le esigenze di un'organizzazione e dobbiamo personalizzare costantemente. Ora abbiamo 3 anni di dati nel nostro magazzino, e le ricariche complete dai sistemi finanziari Oracle sono molto grandi. Quindi, nel mio caso, non vengono generati dall'immissione dei dati, ma aggiunti in un magazzino per facilitare la segnalazione delle prestazioni. Ho capito, ma i nostri cambiano ed è un incubo.


0

Nel caso del database point in time è meglio avere una combinazione di chiavi surrogate e chiavi naturali. ad es. è necessario tenere traccia delle informazioni di un socio per un club. Alcuni attributi di un membro non cambiano mai. ad es. Data di nascita ma il nome può cambiare. Quindi crea una tabella Member con una chiave surrogata member_id e disponi di una colonna per DOB. Crea un'altra tabella chiamata nome persona e disponi di colonne per member_id, member_fname, member_lname, date_updated. In questa tabella la chiave naturale sarebbe member_id + date_updated.

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.