Ogni tabella dovrebbe avere una chiave primaria?


341

Sto creando una tabella di database e non ho assegnato una chiave primaria logica. Quindi, sto pensando di lasciarlo senza una chiave primaria, ma mi sento un po 'in colpa per questo. Dovrei?

Ogni tabella dovrebbe avere una chiave primaria?


5
Potresti dare qualche dettaglio in più sul tavolo? La risposta è probabilmente "sì" però.
Ryan Bair,

7
Sì, ogni tabella dovrebbe avere la chiave primaria.
Syed Tayyab Ali,

Risposte:


314

Risposta breve: .

Risposta lunga:

  • Hai bisogno che il tuo tavolo sia unificabile su qualcosa
  • Se vuoi che la tua tabella sia raggruppata, hai bisogno di una specie di chiave primaria.
  • Se il design del tuo tavolo non ha bisogno di una chiave primaria, ripensa al tuo design: molto probabilmente ti stai perdendo qualcosa. Perché conservare record identici?

In MySQL, il motore di archiviazione InnoDB crea sempre una chiave primaria se non la hai specificata esplicitamente, creando così una colonna aggiuntiva a cui non hai accesso.

Si noti che una chiave primaria può essere composita.

Se si dispone di una tabella di collegamenti molti-a-molti, si crea la chiave primaria su tutti i campi coinvolti nel collegamento. In questo modo ti assicuri di non avere due o più record che descrivono un link.

Oltre ai problemi di coerenza logica, la maggior parte dei motori RDBMS trarrà vantaggio dall'inclusione di questi campi in un indice univoco.

E poiché qualsiasi chiave primaria comporta la creazione di un indice univoco, è necessario dichiararlo e ottenere coerenza e prestazioni logiche.

Vedi questo articolo nel mio blog per sapere perché dovresti sempre creare un indice univoco su dati univoci:

PS Ci sono alcuni casi davvero speciali in cui non hai bisogno di una chiave primaria.

Per lo più essi includono le tabelle di registro che non hanno alcun indici per motivi di prestazioni.


hanno ancora una chiave primaria, quella composita
kristof

2
@annakata: dovrebbero avere una chiave primaria composita
Quassnoi,

1
"E poiché qualsiasi PRIMARY KEY implica la creazione di un indice UNICO" non è vero per Oracle. È possibile utilizzare un indice non univoco per applicare una chiave primaria. In effetti, a volte è NECESSARIO che i vincoli univoci e PK utilizzino indici non univoci.
Stephanie Pagina

3
Solo un commento sulla domanda retorica "Perché conservare registrazioni identiche?". Si noti che l'aggiunta di un PK non garantirà l'assenza di duplicazioni. Spesso il PK non è visibile all'utente, quindi ciò che è importante è nei campi visibili, che potrebbero contenere dati duplicati. A seconda del progetto, questo può essere desiderabile o meno.
Rossco,

1
Le chiavi non hanno nulla a che fare con l'adesività. E l'argomento del cluster dipende dal DBMS che usi e mescola considerazioni logiche e fisiche.
Jon Heggland,

36

Sempre meglio avere una chiave primaria. In questo modo soddisfa il primo modulo normale e consente di continuare lungo il percorso di normalizzazione del database .

Come affermato da altri, ci sono alcuni motivi per non avere una chiave primaria, ma la maggior parte non verrà danneggiata se esiste una chiave primaria


5
@PaulSuart I dati non devono sempre essere nelle loro forme normali. In effetti, quando i dati diventano enormi, non dovrebbero essere mantenuti nella loro forma normale, altrimenti l'accesso ai dati sarebbe terribilmente lento per le query che eseguono join di tabelle, ecc. I moduli normali sono una "idealizzazione" e praticamente possibile solo quando non si prevede che i dati crescano enorme.
Pacerier,

13

Praticamente ogni volta che ho creato una tabella senza una chiave primaria, pensando che non ne avrei avuto bisogno, ho finito per tornare indietro e aggiungerne una. Ora creo anche le mie tabelle di join con un campo identità generato automaticamente che utilizzo come chiave primaria.


13
Una tabella di join È una chiave primaria, una composita, composta dai PK di entrambi i record che vengono uniti. Ad esempio CREATE TABLE PersonOrder (PersonId int, OrderId int, PRIMARY KEY (PersonId, OrderId)).
Keith Williams,

3
Sì, ma cosa succede se la tabella dei collegamenti ha anche un terzo attributo, diciamo "OrderDate". Lo aggiungeresti anche alla chiave composita? IMHO no - perché è ulteriormente riducibile e non serve il carattere non riducibile che dovrebbe avere una chiave primaria.
Steve

13

Fatta eccezione per alcuni casi molto rari (forse una tabella di relazione molti-a-molti, o una tabella che usi temporaneamente per il caricamento di grandi quantità di dati), vorrei dire:

Se non ha una chiave primaria, non è una tabella!

Marc


10
A rigor di termini quella frase è sbagliata. Le tabelle possono essere "Visualizza tabelle" create dalla lingua della query. Un RDBMS è composto da relazioni non da tabelle. Quella frase dovrebbe dire: "Se non ha una chiave primaria, non è una relazione!".
Steve

O forse "se non ci sono chiavi candidate, allora non è una tabella relazionale". Ma vedi i casi molto rari in cui è ok avere una tabella che non rappresenta una relazione.
Walter Mitty,

Perché una tabella molti-a-molti non ha una chiave primaria? È possibile creare una chiave primaria separata e quindi creare un indice univoco per il surrogato delle chiavi esterne. Penso che sia meglio avere una chiave primaria su ogni tavolo. Anche su una tabella di caricamento di massa potresti voler identificare separatamente una chiave primaria che non include i dati importati in quanto potrebbe aiutarti a identificare i record duplicati in un processo ETL. Mi sembra che ogni tabella dovrebbe avere ancora una chiave primaria, anche se è un po 'più di memoria. Una tabella creata da una vista è un sottoinsieme di una tabella e non una tabella stessa.
John Ernest,

1
In una tabella di relazione da molte a molte, è possibile creare una chiave primaria composita composta da entrambi gli ID per le relazioni.
Jaap,

8

Aggiungilo, ti dispiacerà in seguito quando non l'hai fatto (selezione, eliminazione, collegamento, ecc.)


8

Avrai mai bisogno di unirti a questo tavolo con altri tavoli? Hai bisogno di un modo per identificare in modo univoco un record? Se la risposta è sì, è necessaria una chiave primaria. Supponiamo che i tuoi dati siano qualcosa di simile a una tabella dei clienti che ha i nomi delle persone che sono clienti. Potrebbe non esserci una chiave naturale perché hai bisogno di indirizzi, e-mail, numeri di telefono, ecc. Per determinare se questa Sally Smith è diversa da quella di Sally Smith e memorizzerai tali informazioni in tabelle correlate poiché la persona può avere telefoni multipli, additivi , e-mail, ecc. Supponiamo che Sally Smith sposi John Jones e diventi Sally Jones. Se non hai una chiave artificiale sul tavolo, quando aggiorni il nome, hai appena cambiato 7 Sally Smiths in Sally Jones anche se solo uno di loro si è sposato e ha cambiato il suo nome.

Dici di non avere una chiave naturale, quindi non hai nemmeno combinazioni di campi da rendere uniche, questo rende fondamentale la chiave artificiale.

Ho trovato ogni volta che non ho una chiave naturale, una chiave artificiale è un must assoluto per mantenere l'integrità dei dati. Se hai una chiave naturale, puoi usarla come campo chiave. Ma personalmente, a meno che la chiave naturale non sia un campo, preferisco comunque una chiave artificiale e un indice univoco sulla chiave naturale. Te ne pentirai più tardi se non ne inserirai uno.


6

È buona norma avere un PK su ogni tavolo, ma non è DEVE. Molto probabilmente avrai bisogno di un indice univoco e / o di un indice cluster (che sia PK o meno) a seconda delle tue necessità.

Consulta le sezioni Chiavi primarie e indici cluster nella documentazione online (per SQL Server)

"I vincoli PRIMARY KEY identificano la colonna o l'insieme di colonne che hanno valori che identificano in modo univoco una riga in una tabella. Nessuna riga in una tabella può avere lo stesso valore della chiave primaria. Non è possibile inserire NULL per nessuna colonna in una chiave primaria. consiglia di utilizzare una piccola colonna intera come chiave primaria. Ogni tabella dovrebbe avere una chiave primaria. Una colonna o combinazione di colonne che si qualificano come valore della chiave primaria viene definita chiave candidata. "

Ma dai un'occhiata anche a: http://www.aisintl.com/case/primary_and_foreign_key.html



4
quella pagina è abbastanza stupida. Innanzitutto, è necessaria una chiave primaria per motivi di prestazioni. Leggendo la sua pagina apprendo che l'aggiunta di un ID a un tavolo di un libro è inutile perché il testo del libro è unico; ovviamente, il ragazzo non ha mai lavorato con i database, ma ha anche problemi a comprendere ciò che critica. Pagina scritta che 1) un valore PK fa riferimento a una riga 2) è possibile unire 2 tabelle da qualsiasi set di colonne. Non c'è contraddizione. È sorprendente che un autore di articoli accademici non capisca le basi della teoria relazionale.
Federico Razzoli,

1
"In primo luogo, è necessaria una chiave primaria per motivi di prestazioni", ciò non è corretto, PK non influisce direttamente sulle prestazioni. Non avere un PK può portare a molti problemi (identificazione di una riga, unione ecc.) Ma le prestazioni non sono tra queste. Quando si crea PK su una tabella, il server SQL crea un indice cluster univoco, quell'indice influisce sulle prestazioni e non sul PK stesso. Come esempio reale, la mia tabella ha un indice cluster nella colonna della data e un PK in un campo GUID, perché le mie righe dovrebbero essere ordinate fisicamente nella colonna della data nella tabella poiché tutte le query hanno un intervallo di date (nel mio caso).
endo64,

Tale indice cluster è un sapore della chiave primaria, creato da SQL Server e da molti altri DBMS. Sei sicuro che sia una buona idea usarlo? Ad esempio, in MySQL, non lo è per diversi motivi non documentati.
Federico Razzoli,

1
Tieni presente che GUID non è un tipo ottimale per PK, in InnoDB. Tutti gli indici contengono un riferimento al PK, quindi, più grande è il PK, più grandi saranno tutti gli altri indici.
Federico Razzoli,

6

Non sono d'accordo con la risposta suggerita. La risposta breve è: NO .

Lo scopo della chiave primaria è identificare in modo univoco una riga sulla tabella per formare una relazione con un'altra tabella. Tradizionalmente, viene utilizzato un valore intero auto-incrementato per questo scopo, ma ci sono variazioni a questo.

Esistono casi, ad esempio la registrazione di dati di serie temporali, in cui l'esistenza di tale chiave non è semplicemente necessaria e richiede solo memoria. Rendere unica una riga è semplicemente ... non necessario!

Un piccolo esempio: Tabella A: LogData

Columns:  DateAndTime, UserId, AttribA, AttribB, AttribC etc...

Nessuna chiave primaria necessaria.

Tabella B: utente

Columns: Id, FirstName, LastName etc. 

Chiave primaria (ID) necessaria per essere utilizzata come "chiave esterna" nella tabella LogData.


3

So che per utilizzare determinate funzionalità di gridview in .NET, è necessario disporre di una chiave primaria per consentire a gridview di sapere quale riga deve essere aggiornata / eliminata. La pratica generale dovrebbe essere quella di avere una chiave primaria o un cluster di chiavi primarie. Personalmente preferisco il primo.


3

Per renderlo a prova di futuro dovresti davvero. Se vuoi replicarlo, ne avrai bisogno. Se vuoi unirti ad un altro tavolo, la tua vita (e quella dei poveri sciocchi che dovranno mantenerlo l'anno prossimo) sarà molto più facile.


Non sono ancora convinto che sia necessario, ma "fallo perché altrimenti qualcuno dovrà affrontare le conseguenze in un secondo momento" è sufficiente per farmi sbagliare dalla parte del farlo. Posso sempre semplicemente rilasciare la colonna più tardi se sembra utile provare a
ridurla

3

Sono nel ruolo di mantenimento dell'applicazione creata dal team di sviluppo offshore. Ora sto riscontrando tutti i tipi di problemi nell'applicazione perché lo schema del database originale non conteneva TASTI PRIMARI su alcune tabelle. Quindi, per favore, non lasciare che altre persone soffrano a causa del tuo design scadente. È sempre una buona idea avere le chiavi primarie sui tavoli.


2

Ho sempre una chiave primaria, anche se all'inizio non ho ancora in mente uno scopo. Ci sono state alcune volte in cui alla fine ho bisogno di un PK in un tavolo che non ne ha uno ed è sempre più difficile inserirlo in un secondo momento. Penso che ci sia più di un vantaggio nel includerne sempre uno.


1

In breve, no. Tuttavia, è necessario tenere presente che determinate operazioni CRUD di accesso client lo richiedono. Per le prove future, tendo sempre a utilizzare le chiavi primarie.


1

Se si utilizza l'ibernazione, non è possibile creare un'entità senza una chiave primaria. Questi problemi possono creare problemi se si lavora con un database esistente creato con semplici script sql / ddl e non è stata aggiunta alcuna chiave primaria

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.