Domanda

Ci risiamo, il vecchio argomento ancora si pone...

Sarebbe meglio avere una chiave primaria, chiave, o sarebbe meglio avere un surrogato id (es.un'identità di SQL Server) con un unico vincolo di chiave business in campo?

Si prega di fornire esempi o prova a sostegno della tua teoria.

È stato utile?

Soluzione

Entrambi.Avere la vostra torta e mangiare.

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

Se si utilizza una chiave surrogata, vuoi ancora un business chiave per garantire l'univocità secondo le regole di business.

Altri suggerimenti

Solo alcune delle ragioni per l'utilizzo di chiavi surrogate:

  1. Stabilità:La modifica di una chiave a causa di un business o naturale bisogno di influire negativamente sulle tabelle correlate.Chiavi Surrogate raramente, se non mai, ha bisogno di essere cambiato, perché non c'è nessun significato legato al valore.

  2. Convenzione:Permette di avere un standardizzate colonna di Chiave Primaria di una convenzione di denominazione, piuttosto che dover pensare a come unire le tabelle con nomi diversi per la loro PKs.

  3. Velocità:A seconda del valore di PK e tipo, una chiave surrogata di un numero intero può essere più piccolo, più veloce indicizzazione e la ricerca.

Sembra che nessuno ha ancora detto nulla a sostegno della non-madre surrogata (ho esitato a dire "naturale") chiavi.Così qui va...

Un svantaggio di chiavi surrogate è che sono senza senso (citata come un vantaggio da parte di alcuni, ma...).Questo a volte ti costringe a entrare in un sacco di più tabelle in una query che in realtà dovrebbe essere necessario.Confronto:

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 pensa seriamente la seguente è 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à: "che cosa succede quando il codice per il PROGETTO o VALIDO o HR modifiche?" Per cui la mia risposta sarebbe:"perché si è bisogno per cambiare?" Questi non sono "naturali" chiavi nel senso che alcuni al di fuori del corpo sta per legiferare che d'ora in poi "VALIDO" dovrebbe essere ri-codificato come 'BUONO'.Solo una piccola percentuale di "naturale" chiavi veramente rientrano in tale categoria - SSN e c.a.p. essere i soliti esempi.Mi sarebbe sicuramente usare di un senso tasto numerico per le tabelle come Persona, l'Indirizzo, ma non per tutto, che, per qualche ragione, la maggior parte delle persone qui sembrano avvocato.

Vedere anche: la mia risposta ad un'altra domanda

Chiavi Surrogate (in genere interi) hanno il valore aggiunto di rendere la vostra tabella di relazioni più veloce e più economico di archiviazione e velocità di aggiornamento (anche meglio, chiavi esterne non hanno bisogno di essere aggiornato in caso di utilizzo di chiavi surrogate, in contrasto con la business key campi, che non cambia tanto).

Una chiave primaria della tabella dovrebbe essere utilizzato per identificare univocamente la riga, principalmente per partecipare scopi.Pensare a una tabella Persone:i nomi possono cambiare, e non sono garantiti unico.

Pensa Aziende:sei un felice Merkin società di fare affari con altre aziende Merkia.Si sono abbastanza intelligenti da non utilizzare il nome della società come chiave primaria, in modo da utilizzare Merkia del governo unico ID di società nella sua interezza di 10 caratteri alfanumerici.Quindi Merkia cambia l'Id di società, perché hanno pensato che potesse essere una buona idea.Ok, è possibile utilizzare il db del motore a cascata funzionalità aggiornamenti, per un cambiamento che non deve coinvolgere in primo luogo.In seguito, la vostra attività si espande, e ora si lavora con una società di Freedonia.Freedonian id società sono fino a 16 caratteri.È necessario allargare la società id chiave primaria (anche esteri campi chiave Ordini di Problemi, MoneyTransfers ecc), aggiungendo un Paese di campo di chiave primaria (anche in chiavi esterne).Ouch!Guerra civile in Freedonia, è suddivisa in tre paesi.Il nome del paese di associare il tuo dovrebbe essere modificato per il nuovo;cascata aggiornamenti per il salvataggio.BTW, qual è la vostra chiave primaria?(Paese, CompanyID) o (CompanyID, Paese)?Quest'ultimo aiuta join, l'ex evita un altro indice (o forse molti, se volete che i vostri Ordini raggruppati per paese).

Tutte queste non sono prove, ma un'indicazione che una chiave surrogata per identificare in modo univoco una riga per tutti gli usi, tra cui le operazioni di join, è preferibile una chiave business.

Chiave surrogata non avrà MAI una ragione per cambiare.Non posso dire la stessa cosa di naturale chiavi.Cognome, e-mail, ISBN nubmers tutto può cambiare in un giorno.

Io odio le chiavi surrogate in generale.Essi dovrebbero essere usati solo quando non c'è qualità naturale disponibile.È piuttosto assurdo, quando si pensi, a pensare che l'aggiunta di dati privi di significato per il vostro tavolo potrebbe rendere le cose migliori.

Ecco i miei motivi:

  1. Quando si utilizza naturale chiavi, le tabelle sono raggruppati in modo che essi sono più spesso cercato rendendo le query più veloce.

  2. Quando si utilizza chiavi surrogate è necessario aggiungere indici univoci in chiave logica colonne.Hai ancora bisogno di evitare logiche di dati duplicati.Per esempio, non è possibile consentire a due Organizzazioni con lo stesso nome dell'Organizzazione tabella, anche se il pk è un surrogato della colonna id.

  3. Quando le chiavi surrogate sono utilizzati come chiave primaria è molto meno chiaro cosa naturale, le chiavi primarie sono.Quando si sviluppa volete sapere che cosa il set di colonne della tabella unica.

  4. In relazione uno a molti di catene, la chiave logica catene.Così, per esempio, le aziende hanno molti Conti e Conti il numero di Fatture.In modo logico-chiave dell'Organizzazione è OrgName.La logica e la chiave di Conti è OrgName, AccountID.Logico-chiave della Fattura è OrgName, AccountID InvoiceNumber.

    Quando surrogato tasti, la chiave catene sono troncati da solo avendo una chiave esterna per il padre immediato.Per esempio, la Fattura tabella non dispone di un OrgName colonna.Ha solo una colonna per il AccountID.Se si desidera cercare le fatture per una determinata organizzazione, allora si avrà bisogno di unire l'Organizzazione, il Conto, e le tabelle di fatturazione.Se si utilizza chiavi logiche, allora si potrebbe interrogare la tabella dell'Organizzazione direttamente.

  5. Memorizzazione chiave surrogata valori delle tabelle di ricerca cause tabelle di essere riempito con un senso interi.Per visualizzare i dati, viste complesse deve essere creato che si uniscono a tutte le tabelle di ricerca.Una tabella di ricerca, è destinata a contenere un insieme di valori accettabili per una colonna.Non deve essere codificata dalla memorizzazione di un numero intero chiave surrogata, invece.Non c'è nulla nelle regole di normalizzazione che suggeriscono che si dovrebbe memorizzare un surrogato intero invece del valore stesso.

  6. Ho tre diversi database di libri.Non uno di loro viene illustrato l'utilizzo di chiavi surrogate.

Voglio condividere la mia esperienza con voi, in questa guerra infinita :D naturale vs chiave surrogata dilemma.Penso che entrambi chiavi surrogate (artificiale auto-generate) naturali e chiavi (composto di colonna(s) con dominio significato) hanno pro e contro.Quindi, a seconda della situazione, potrebbe essere più rilevante per scegliere un metodo o l'altro.

Sembra che molte persone presenti chiavi surrogate come quasi soluzione perfetta e naturale tasti come la peste, mi concentrerò su altro punto di vista gli argomenti:

Gli svantaggi di chiavi surrogate

Chiavi Surrogate sono:

  1. Fonte di problemi di prestazioni:
    • Essi sono di solito implementato utilizzando auto-increment colonne, il che significa che:
      • Un viaggio andata e ritorno per il database ogni volta che si desidera ottenere un nuovo Id (so che questo può essere migliorata utilizzando la cache o [seq]hilo simili algoritmi ma tali metodi hanno i loro difetti).
      • Se un giorno hai bisogno di spostare i dati da uno schema ad un altro (succede abbastanza regolarmente in mia compagnia almeno) quindi potreste ritrovarvi con Id collisione problemi.E Sì, lo so che si possono usare gli Uuid, ma coloro dura necessita di 32 cifre esadecimali!(Se ti interessa la dimensione del database, allora può essere un problema).
      • Se si utilizza una sequenza per tutte le vostre chiavi surrogate quindi - per certo - non si finirà con la contesa con il database.
  2. Suscettibili di errore.Una sequenza è una max_value limite, quindi - come sviluppatore - è necessario porre l'attenzione sui seguenti punti:
    • È necessario ciclo di sequenza ( quando max viene raggiunto il valore torna a 1,2,...).
    • Se si utilizza la sequenza come un ordine (nel tempo) i vostri dati, è necessario gestire il caso di ciclismo (colonna con Id 1 potrebbe essere più recente rispetto riga con Id max-valore - 1).
    • Assicurarsi che il codice (e anche il vostro client di interfacce che non dovrebbe accadere come dovrebbe essere un Id interno) supporta 32b/64b interi che hai usato per memorizzare la sequenza di valori.
  3. Non garantire l'assenza di dati duplicati.Si può sempre avere 2 righe con gli stessi valori di una colonna, ma con un diverso valore generato.Per me questo è IL problema di chiavi surrogate da un database punto di vista della progettazione.
  4. Più in Wikipedia...

Miti naturale con i tasti

  1. Composito tasti sono meno inefficiente di chiavi surrogate.No!Dipende dal motore di database:
  2. Naturale chiavi non esistono nella vita reale.Mi dispiace ma non esiste!Nel settore dell'aviazione, per esempio, il seguente tupla sarà sempre unico riguardante una data pianificate volo (compagnia aerea, departureDate, flightNumber, operationalSuffix).Più in generale, quando un insieme di dati è garantito per essere unico, da un dato standard quindi, questo set di dati è un [buono] naturale candidato ideale.
  3. Naturale tasti "inquinare lo schema" del bambino tabelle.Per me è più una sensazione che un vero e proprio problema.Avendo un 4 colonne chiave primaria di 2 byte ciascuno potrebbe essere più efficace di una singola colonna di 11 byte.Inoltre, le 4 colonne può essere usato per interrogare la tabella figlio direttamente (utilizzando le 4 colonne in una clausola where) senza join alla tabella padre.

Conclusione

Uso naturale tasti quando è rilevante e utilizzare chiavi surrogate quando è meglio per il loro utilizzo.

Spero che questo ha aiutato qualcuno!

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

EDIT:Stavo cercando di trovare un collegamento on-line, ma non ho potuto.Tuttavia in I "modelli di Impresa Achitettura' [Fowler] si ha una buona spiegazione del perché non usare qualcosa di diverso da una chiave con senso di essere una chiave.Si riduce al fatto che dovrebbe avere un lavoro, e il lavoro di uno solo.

Chiavi Surrogate sono molto pratico se avete intenzione di usare un ORM strumento per gestire e/o generare le classi di dati.Mentre è possibile utilizzare le chiavi composte con alcune delle più avanzate di mappatori (leggi:hibernate), si aggiunge un po ' di complessità, per il codice.

(Naturalmente, database puristi sostengono che anche la nozione di una chiave surrogata è un abominio.)

Io sono un fan di utilizzo di fluidi per chiavi surrogate quando adatto.La grande vittoria con loro è che si conosce la chiave in anticipo per es.è possibile creare un'istanza di una classe con l'ID già stabilito e garantito per essere unico, mentre, per esempio, in una chiave integer avrai bisogno di default a 0 o -1 e aggiornamento per un valore appropriato quando si salva/aggiornamento.

Uidi sono sanzioni in termini di ricerca e di partecipare a velocità anche se in modo non dipende dall'applicazione in questione se sono desiderabili.

Utilizzando una chiave surrogata è meglio a mio parere non c'è alcuna possibilità di cambiare.Quasi tutto quello che posso pensare che si potrebbe utilizzare come chiave di naturale potrebbe cambiare (disclaimer:non è sempre vero, ma di solito).

Un esempio potrebbe essere un DB di auto - a prima vista, si potrebbe pensare che la targa potrebbe essere utilizzato come chiave.Ma questi potrebbero essere modificata in modo che sarebbe una cattiva idea.Si wouldnt vuole veramente sapere di più dopo di rilasciare l'app, quando qualcuno viene a voi che vogliono sapere perché non possono cambiare il loro numero di targa della loro nuova fiammante personalizzato una.

Utilizzare sempre una singola colonna, chiave surrogata, se possibile.Questo fa si unisce così come inserimenti/aggiornamenti/elimina molto più "pulito" perché sei solo responsabile per il monitoraggio di un singolo pezzo di informazioni per mantenere i record.

Poi, come necessario, il camino, il tuo business tasti come unici vincoli o indici.Questo permetterà di mantenere l'integrità dei dati intatti.

La logica di Business/naturale tasti possono cambiare, ma il fisico chiave di una tabella non dovrebbe MAI cambiare.

Su un datawarehouse scenario credo sia meglio seguire la chiave surrogata percorso.Due motivi:

  • Sei indipendente del sistema di origine, e le modifiche --come una modifica del tipo di dati-- non vi riguardano.
  • DW avrà bisogno di meno spazio fisico, in quanto si usa solo un tipo di dati integer per le chiavi surrogate.Anche gli indici di svolgere meglio il proprio lavoro.

Chiavi Surrogate può essere utile quando le informazioni possono cambiare o essere identici.Business nomi non devono essere univoco in tutto il paese, dopo tutto.Supponiamo che avete a che fare con due aziende di nome Smith, uno in Kansas e uno in Michigan.È possibile distinguerli in base all'indirizzo, ma che ti cambia.Anche lo stato può cambiare;che cosa succede se Smith Elettronica di Kansas City, Kansas, si muove attraverso il fiume a Kansas City, Missouri?Non c'è modo ovvio di mantenere queste imprese distinte naturale informazioni chiave, in modo che una chiave surrogata è molto utile.

Pensare la chiave surrogata come un numero ISBN.Di solito, si identifica un libro per titolo e autore.Tuttavia, ho due libri intitolati "Pearl Harbor" di H.P.Willmott, e sono sicuramente diversi libri, non solo di edizioni diverse.In un caso come questo, potrei vedere gli sguardi dei libri, o i precedenti contro il dopo, ma è solo così ho il codice ISBN a ripiegare su.

Come promemoria non è buona abitudine mettere in cluster indici casuale chiavi surrogate cioèGuid leggere XY8D7-DFD8S, come SQL Server, non ha la possibilità fisica di tali dati.Si dovrebbe invece gli indici univoci su questi dati, se può essere utile anche per eseguire semplicemente SQL profiler per la tabella principale delle operazioni e quindi inserire tali dati in Ottimizzazione guidata Motore di Database.

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

Caso 1: Il tavolo è un tabella di ricerca con meno di 50 tipi (inserti)

Utilizzare commerciale/naturale chiavi.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: Il tavolo è un tabella con migliaia di inserti

Utilizzare surrogato/autoincrement chiavi.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 in tabella PERSONE senza l'uso di join con la tabella di LAVORO, ma solo con:"SELECT * FROM PERSONE WHERE JOBCODE = 'PRG'"

Nel secondo caso:

  • Le query di database sono più veloce perché la chiave primaria è un numero intero
  • Non c'è bisogno di preoccuparsi se stessi con ricerca di il prossimo chiave univoca, perché il database per sé dà il successivo autoincrement.

Questo è uno di quei casi in cui una chiave surrogata praticamente sempre ha un senso.Ci sono casi in cui è scegliere ciò che è meglio per il database o di ciò che è meglio per il vostro modello di oggetto, ma in entrambi i casi, utilizzando un significato chiave o il GUID è un'idea migliore.Esso rendendo più facile e più veloce, e si tratta di un'identità per l'oggetto che non cambia.

Cavallo per i corsi.Di stato, il mio bias;Io sono uno sviluppatore, quindi mi occupo principalmente di dare agli utenti un'applicazione funzionante.

Ho lavorato sui sistemi naturali, con le chiavi, e ha dovuto spendere un sacco di tempo fare in modo che i cambiamenti di valore si sarebbe propagato attraverso.

Ho lavorato su sistemi con chiavi surrogate, e l'unico inconveniente è stata una mancanza di denormalised dati per il partizionamento.

Più tradizionale PL/SQL gli sviluppatori con cui ho lavorato non come surrogato di chiavi a causa del numero di tabelle per partecipare, ma i nostri test e i database di produzione non alzava mai una goccia di sudore;extra unisce non influenzano le prestazioni dell'applicazione.Con un database di dialetti che non supportano clausole del tipo "X inner join Y su x = Y. b", o gli sviluppatori che, non usare la sintassi, l'extra si unisce per chiavi surrogate fare le query più difficile da leggere, e più per tipo e di controllo:vedi @Tony Andrews post.Ma se si utilizza un ORM o qualsiasi altra SQL-generazione quadro non si dovrebbe notare.Touch-tipizzazione attenua.

Forse non del tutto pertinente a questo argomento, ma un mal di testa devo trattare con chiavi surrogate.Oracle pre-consegnato analytics crea generata automaticamente SKs su tutte le tabelle dimensione del magazzino, e memorizza anche quelli sui fatti.Così, in qualsiasi momento (dimensioni) hanno bisogno di essere ricaricato come nuove colonne vengono aggiunte o bisogno di essere compilato per tutti gli elementi della dimensione, la SKs ricevuto durante l'aggiornamento rende l'SKs fuori sincronia con i valori originali conservati per il fatto, costringendo una completa ricarica di tutte le tabelle dei fatti che aderire ad esso.Io preferirei che anche se la SK è un numero privo di significato, ci sarebbe un modo che non poteva cambiare per originale/vecchio record.Come molti sanno, out-of-the-box raramente serve le esigenze di un'organizzazione, e abbiamo personalizzare costantemente.Ora abbiamo 3 anni vale la pena di dati nel nostro magazzino, e completo di ricarica da Oracle sistemi Finanziari sono molto grandi.Quindi nel mio caso, non sono generate dal data entry, ma ha aggiunto in un magazzino per aiutare le prestazioni di reporting.Ho capito, ma il nostro non cambiare, ed è un incubo.

Nel caso di punto nel tempo database è meglio avere una combinazione di surrogato naturale e chiavi.ad es.è necessario tenere traccia di un membro informazioni per un club.Alcuni attributi di un membro non cambiano mai.e.g Data di Nascita, ma il nome può cambiare.Quindi, creare una tabella Membro con un member_id chiave surrogata e dispone di una colonna per il DOB.Creare un'altra tabella chiamata nome di persona e colonne per member_id, member_fname, member_lname, date_updated.In questa tabella naturali chiave sarebbe member_id + date_updated.

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