Una chiave primaria dovrebbe essere immutabile?


26

Una recente domanda su StackOverflow ha provocato una discussione sull'immutabilità delle chiavi primarie. Avevo pensato che fosse una specie di regola che le chiavi primarie dovessero essere immutabili. Se c'è la possibilità che un giorno una chiave primaria venga aggiornata, ho pensato che dovresti usare una chiave surrogata. Tuttavia non è nello standard SQL e alcune funzionalità di "aggiornamento in cascata" di RDBMS consentono di modificare una chiave primaria.

Quindi la mia domanda è: è ancora una cattiva pratica avere una chiave primaria che può cambiare? Quali sono gli eventuali svantaggi di avere una chiave primaria modificabile?

Risposte:


25

È necessario che la chiave primaria sia immutabile solo se è collegata a una chiave esterna o se viene utilizzata come identificatore all'esterno del database (ad esempio in un URL che punta a una pagina per l'elemento).

D'altra parte, è necessario disporre di una chiave mutabile solo se contiene alcune informazioni che potrebbero cambiare. Uso sempre una chiave surrogata se il record non ha un identificatore semplice e immutabile che può essere usato come chiave.


7
Perché "hai bisogno che la chiave primaria sia immutabile se è collegata a una chiave esterna"? Come menzionato dall'OP, la maggior parte dei RDBMS ha la funzione di aggiornamento "a cascata".
Thanatos,

1
La maggior parte dei rdbms (in realtà tutto quello che ho incontrato) non consentirà le chiavi primarie mutabili ma ha aggiornamenti a cascata. Una chiave primaria, nella saggezza del dba generalmente accettata, non dovrebbe contenere informazioni, essere solo un identificatore di record univoco (quindi nemmeno un timestamp, un intervallo di record rinviato da esso, ecc.).
jwenting

5
@jwenting: stiamo parlando della stessa cosa? "la maggior parte dei rdbms non consente chiavi primarie mutabili" include cosa? MySQL e PostgreSQL consentono entrambe chiavi primarie mutabili e rispettano gli aggiornamenti a cascata ... come penso che SQL standard dice che dovrebbero. Inoltre, "generalmente accettata la saggezza del dba"? Ho incontrato molti DBA che discutono contro le chiavi surrogate e molti che discutono contro le chiavi naturali.
Thanatos,

2
@Thanatos Gli argomenti a favore di "tutte le tabelle devono avere un sostituto" mancano di riferimenti bibliografici, citano "generalmente accettata la saggezza" ma non citano mai un libro. I libri canonici affermano che dovresti usare il surrogato se: A. non esiste una chiave naturale, B. la chiave a più colonne è esclusa da 3 colonne o, C. Dovrai cambiare la chiave continuamente. Quindi: naturale quando si adattano, surroga quando i naturali non si adattano.
Tulains Córdova,

4
@ user61852: che cosa?
Guffa,

15

Una chiave primaria dovrebbe comprendere qualsiasi tupla necessaria per determinare l'unicità. Il fatto che i dati possano cambiare o meno è irrilevante. È importante solo l'unicità del disco. Questa è la progettazione concettuale del database.

Quando entriamo nel regno dell'implementazione, la cosa più sicura da fare è semplicemente usare una chiave surrogata.


15

Sì, secondo me una chiave primaria dovrebbe essere immutabile.

Anche se ci sono chiavi candidate ovvie, uso sempre una chiave surrogata. In poche occasioni non l'ho fatto, quasi sempre me ne sono pentito. E non importa quanto tu pensi che sia la chiave immutabile, non puoi proteggerti dagli errori di immissione dei dati - dicendo agli utenti che non possono modificare quel po 'di informazioni perché è una chiave primaria che non si lava tristemente.


Un buon punto sugli errori di immissione dei dati
Tim Goodman,

richeym, sembra che tu stia spiegando perché le chiavi NON devono essere immutabili: gli utenti potrebbero volerle cambiare.
nvogel,

4
@dportas - il mio punto è che mi piace che i PK siano immutabili, quindi usa sempre le chiavi surrogate anche se penso che ci sia una chiave ovvia che può essere derivata dai dati della tabella (ad esempio e-mail, nome utente).
Richeym,

2

I meccanismi di memorizzazione nella cache tra il database e l'utente perderanno l'efficacia se cambiano le chiavi primarie.


2

Perchè no? Perché vuoi eliminare una colonna?

Solo perché i requisiti richiedono che tre colonne siano univoche, non significa che debba essere la chiave primaria. Potresti pensare che la regola durerà per sempre (ricorda durante quell'incontro quando il caposquadra giurò che non sarebbe mai cambiato? Sai, quello che è appena stato licenziato.), Ma non lo farà.

Non vengo pagato per ogni aggiornamento in cascata che implemento e un bonus se lo codifico da solo.

Il computer non richiede alcun significato per una chiave; IMHO, le chiavi sono per i computer, lascia che le persone rovinino il resto dei dati.


1
"le chiavi sono per computer, lascia che le persone rovinino il resto dei dati." +1, carino.

2

Non è una cattiva pratica avere una chiave i cui valori possono cambiare.

Le proprietà di una buona chiave includono la stabilità. L'immutabilità è l'ideale ma non è un prerequisito. Introdurre una chiave artificiale per il bene dell'immutabilità è una cattiva pratica.

Prendi l'esempio del numero di libro standard internazionale (ISBN) . È molto stabile ma non immutabile: a volte gli editori di libri commettono errori e - orrore! - possono verificarsi numeri ISBN duplicati. Questo significa che il codice ISBN non dovrebbe essere accettato come chiave candidata in un database computerizzato? Ovviamente no. Uno dei vantaggi di ISBN è che ha una fonte attendibile che risolverà i problemi per tutti gli utenti a livello globale.

Esistono altre proprietà di una buona chiave ISBN che mancherà a una chiave intera senza auto-incremento, ad esempio familiarità (tutti gli operatori del libro conoscono o hanno familiarità con il codice ISBN), verificabile (il codice ISBN è stampato su tutti i libri moderni), può essere validato con riferimento al DBMS (il codice ISBN è a larghezza fissa e include un checksum), ecc.


3
Il codice ISBN ha una larghezza fissa, tranne quando non lo è (vedi ISBN-10 vs ISBN-13).
un CVn del

Quindi, come consiglieresti di gestire codici ISBN duplicati? In tutti i RDBMS di cui sono a conoscenza, dovresti avere un vincolo UNICO sul campo per usarlo come chiave primaria.
Wildcard il

1

Tutto ciò che può essere immutabile dovrebbe essere. Aiuta a garantire la correttezza e aiuta quando si desidera rendere l'applicazione multithread.


1

Sì, una chiave primaria deve essere immutabile, oltre a essere non nulla e univoca. Tuttavia, devo ancora trovare un database che imponga l'immutabilità delle chiavi primarie in modo che tu possa probabilmente andare avanti e modificarne i valori se lo desideri.


0

Come alcuni commenti hanno già detto, una soluzione è utilizzare una nuova chiave primaria

Ad esempio (seguendo l'esempio di @onedaywhen), diciamo che esiste la tabella Libri che memorizza un elenco di libri e abbiamo "usato" per determinare il codice ISBN come chiave primaria. Tuttavia, alcuni autori hanno commesso l'errore di digitare un codice ISBN errato, quindi hanno chiesto di modificare il codice ISBN, includendo le attività successive:

  • creare un nuovo registro nella tabella Libri
  • punta tutti i riferimenti dal vecchio ISBN al nuovo ISBN. (*)
  • E infine, elimina il vecchio registro dalla tabella Libri.

(*) potrebbe essere banale trovare tutti i riferimenti per un modello di database che utilizza chiavi esterne ma alcuni modelli ne sono privi.

Table Books
ISBN  is the primary key
NAME is a simple field.
etc.

Lo cambiamo come

Table Books
InternalBookId as the primary key
ISBN as a simple field or an indexed field.
NAME is a simple field.
etc.

Dove il nuovo InternalBookId potrebbe persino essere un valore autonumerico.

I contro a riguardo:

  • aggiunge un nuovo campo che utilizza più spazio / risorsa.

  • potrebbe richiedere di riscrivere l'intero modello.

  • il nuovo modello potrebbe essere meno autoesplicativo.

Il pro

  • Permette di mutare la "chiave primaria".
  • Permette persino di eliminare o refactoring la "chiave primaria", ad esempio, cambiare Libri in ISBN-13 è così semplice da eliminare la colonna precedente e crearne una nuova

Nuovo tavolo:

Table Books
InternalBookId as the primary key
ISBN13 is a new field.
NAME is a simple field.
etc.
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.