Ogni tabella dovrebbe avere una surrogata a campo singolo / chiave primaria artificiale?


33

Capisco un vantaggio delle chiavi surrogate / artificiali in generale: non cambiano e questo può essere molto conveniente. Ciò vale sia che si tratti di campi singoli o multipli, purché siano "artificiali".

Tuttavia, a volte sembra essere una questione di politica avere un campo intero a incremento automatico come chiave primaria di ogni tabella. È sempre questa la migliore idea di avere una tale chiave a campo singolo e perché (o perché no)?

Per essere chiari, questa domanda non riguarda l'artificiale o il naturale, ma se tutte le chiavi artificiali debbano essere a campo singolo


Risposte:


28

Sto per dire di no, non sempre, ma il più delle volte sì. .

Queste sono alcune circostanze in cui non hai bisogno di una chiave surrogata o artificiale:

  • Tabelle di intersezione pure . Se non vi è alcun rischio che l'intersezione sia il bersaglio di una chiave esterna e se c'è un rischio minimo o nullo dell'intersezione che attrae attributi indipendenti (cioè qualcosa di diverso da FK rispetto alle due tabelle principali), allora si può cavarsela usando la combinazione di FK come PK con buona fiducia.
  • Tabelle di ricerca con chiavi business statiche . Se disponi di una
    tabella di ricerca con una chiave aziendale unica, fissata esternamente alla tua
    attività e che non ha alcuna possibilità di cambiare per qualsiasi
    scopo pratico, l'utilizzo diretto della chiave aziendale può semplificare le
    cose. Un esempio potrebbe essere un elenco di
    codici stato o provincia o un elenco di numeri standard ANSI, ecc.
  • Tabelle contenenti dati consolidati da più fonti indipendenti . Se il tuo sistema ha molte fonti di dati che devono essere messe insieme in un'unica tabella, diciamo alla sede centrale, a volte hai bisogno di una chiave composta che includa il valore della chiave del sistema di origine e un codice che indichi quale fosse il sistema di origine.

Ci sono anche alcune situazioni in cui la chiave surrogata intera integra monotonicamente fedele non è l'ideale. Puoi avere chiavi surrogate alfanumeriche. Questi potrebbero includere:

  • Situazioni in cui è necessario unire i dati da più fonti indipendenti. Per evitare le collisioni tra chiavi, è possibile utilizzare i GUID anziché le chiavi IDENTITY.
  • Situazioni in cui si è costretti a utilizzare rappresentazioni di tasti non numerici. Supponiamo che tu abbia un database di targhe. La chiave potrebbe essere il valore alfanumerico anziché un numero puro.
  • Situazioni in cui alcuni requisiti esterni ti costringono ad applicare la compressione al valore chiave. Invece di usare 10 cifre per un int32 è possibile utilizzare sei cifre di base 36.

Perché il più delle volte sì? La risposta più fondamentale a questa domanda è che è un vero inferno se hai mai bisogno di modificare un valore di chiave primaria su qualsiasi tabella. Dato che quasi tutto ciò che un utente può vedere o toccare è potenzialmente soggetto ad un aggiornamento ad un certo punto, l'uso di un valore chiave visibile sta invitando l'inferno puro. L'uso di una chiave surrogata ti impedirà di cadere in questa trappola.

Detto questo, ricorda che c'è spazio per YAGNI nell'applicare questo concetto. Non è necessario forzare le tabelle di codici con le chiavi IDENTITY in ogni angolo del tuo schema, nel caso in cui qualcuno decida che il simbolo del genere maschile nella tabella dei dipendenti deve cambiare da M a X o qualcosa di stupido.


"L'uso di una chiave surrogata ti impedirà di cadere in questa trappola" La domanda non riguarda il surrogato rispetto al naturale, ma ai surrogati a campo singolo vs a più campi.
Jack Douglas,

Come hai riconosciuto in un commento la tua risposta, siamo in "accordo di non essere d'accordo" territorio quando si tratta di ciò che è prudente nella progettazione del database. Data la tua modifica, non avrei fatto la distinzione tra chiavi surrogate e chiavi naturali, quindi il mio secondo punto elenco è tardivamente fuori tema. Le altre mie considerazioni su quando si potrebbe divergere dal classico approccio identità / sequenza restano valide.
Joel Brown,

Non ho cambiato la domanda come puoi vedere dalla storia, ho solo aggiunto l'enfasi su dove pensavo potesse aiutare i lettori di skim
Jack Douglas,

12

No.

Direi che ci sono certamente casi in cui le chiavi a campo singolo sono inferiori alle chiavi composte, almeno ai fini delle chiavi esterne . Questo non vuol dire che non dovresti avere anche una chiave surrogata a campo singolo se preferisci, ma personalmente preferisco che la chiave che viene più spesso utilizzata come target di una chiave esterna sia chiamata chiave primaria

Cercherò di illustrare il mio punto nei seguenti esempi, in cui:

  • brand è marchio automobilistico, ad esempio Ford, Toyota ecc
  • dealer è una concessionaria fisica, legata a un marchio (ad esempio una concessionaria Ford che vende solo Ford)
  • model è il tipo di auto, ad esempio Ford Focus, Ford Fiesta ecc
  • stock è il conteggio delle auto del piazzale attuale per ogni concessionaria

Se creiamo una chiave surrogata a campo singolo per dealere modelcome segue:

create table brand( brand_id integer primary key );

create table dealer( dealer_id integer primary key, 
                     brand_id integer references brand )

create table model( model_id integer primary key, 
                    brand_id integer references brand )

create table stock( model_id integer references model, 
                    dealer_id integer references dealer, 
                    quantity integer,
                      primary key(model_id, dealer_id) )

quindi è possibile inserire una riga stockche collega una Ford dealera un modello "Toyota". L'aggiunta brand_id references branda stocknon fa che peggiorare il problema. D'altra parte se manteniamo la chiave esterna come parte della chiave primaria come segue:

create table brand( brand_id integer primary key );

create table dealer( brand_id integer references brand, 
                     dealer_id integer, 
                       primary key(brand_id, dealer_id) )

create table model( brand_id integer references brand, 
                    model_id integer, 
                      primary key(brand_id, model_id) )

create table stock( brand_id integer, 
                    model_id integer, 
                    dealer_id integer, 
                    quantity integer,
                      primary key(brand_id, model_id, dealer_id),
                      foreign key(brand_id, model_id) references model,
                      foreign key(brand_id, dealer_id) references dealer )

ora la regola secondo cui i concessionari "Ford" possono rifornire solo auto "Ford" è applicata naturalmente dal modello.

Si noti che nell'esempio delle "chiavi composite", dealer_idpuò essere o non essere univoco, in base alle preferenze. Non ha bisogno di essere univoco (cioè una chiave alternativa), ma si perde molto poco rendendolo tale (forse un po 'di spazio di archiviazione) e può essere molto utile, così è il modo in cui lo installo di solito, ad esempio:

create table dealer( brand_id integer references brand, 
                     dealer_id serial unique, 
                       primary key(brand_id, dealer_id) )

3
Tenendo conto delle consuete disposizioni sugli esempi che non sono necessariamente perfetti da ogni angolazione, direi che questo tipo di design è particolarmente fragile. Sebbene ci sia qualcosa di soddisfacente nel trovare un modo per utilizzare DRI per far rispettare le regole aziendali, toglie anche parte della tua capacità di rispondere ai cambiamenti. Se la Toyota acquista la Ford, o anche se un concessionario della Ford decide di vendere una Toyota usata, le regole aziendali basate sul DRI ti faranno venire il mal di testa da manutenzione.
Joel Brown,

1
Quindi "le tue regole aziendali potrebbero cambiare". Questo è vero per qualsiasi regola aziendale e sarà sempre potenzialmente difficile rimodellare. Di solito mi viene detto quali sono le regole aziendali - non le decido da solo.
Jack Douglas,

1
Stai dicendo che il DRI non dovrebbe essere usato affatto per far rispettare le regole aziendali? Non è l'unica cosa che fa DRI? - anche le semplici chiavi esterne sono regole aziendali imposte da DRI.
Jack Douglas,

4
Naturalmente DRI applica regole aziendali. Devi decidere quali regole verranno applicate nel codice e quali nel tuo schema. Le modifiche allo schema sono quasi sempre più difficili delle modifiche al codice. Esistono due tipi di regole aziendali che possono essere inserite nel modello di dati. Uno appartiene lì e uno no. La natura fondamentale dei dati che è importante per la tua azienda non cambia molto. I modi specifici in cui operi su tali dati sono molto più volatili . Una regola come le automobili hanno un produttore appartiene al modello di dati. Una regola come quella dei concessionari non venderà mai due marchi di automobili.
Joel Brown,

4
"I cambiamenti di schema sono quasi sempre più difficili dei cambiamenti di codice" IMO è vero il contrario. In realtà non sono d'accordo con praticamente tutto quello che hai appena detto, ma dubito che abbia senso discutere del lancio con te, quindi lo lascerò a quello.
Jack Douglas,

12

"dipende"

Sì: i campi IDENTITÀ / AUTONUMBER surrogati sono validi quando la chiave naturale è ampia e non numerica. Nota: ciò presuppone la fusione di "PK" e indice cluster che si verifica per impostazione predefinita in SQL Server e Sybase ecc

No: molte / molte tabelle quando sono sufficienti le 2 chiavi principali. O quando la chiave naturale è corta e fissa, ad es. Codice valuta

Naturalmente, un ORM braindead (leggi: (n) Hibernate) può superare queste regole ...

Modifica: rileggere la domanda

Una tabella molte / molte con 2 chiavi parent surrogate avrà un PK a più colonne.
Tuttavia, non ha bisogno di un'altra colonna surrogata.

Se una tabella ha una chiave surrogata (IDENTITÀ ecc.), Non è necessario che sia una colonna multipla.

Puoi avere una super chiave che include il surrogato, ma ciò significherebbe far rispettare altre regole (es. Sottotipi )

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.