Perché utilizzare più colonne come chiavi primarie (chiave primaria composita)


109

Questo esempio è tratto da w3schools .

CREATE TABLE Persons
(
    P_Id int NOT NULL,
    LastName varchar(255) NOT NULL,
    FirstName varchar(255),
    Address varchar(255),
    City varchar(255),
    CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)
)

La mia comprensione è che entrambe le colonne insieme ( P_Ide LastName) rappresentano una chiave primaria per la tabella Persons. È corretto?

  • Perché qualcuno dovrebbe voler utilizzare più colonne come chiavi primarie invece di una singola colonna?
  • Quante colonne possono essere utilizzate insieme come chiave primaria in una determinata tabella?

... ora c'è anche una risposta per la 2a domanda
Wolf

1
@Martijn Peters. Perché la risposta è stata eliminata?
PerformanceDBA

Risposte:


119

La tua comprensione è corretta.

Lo faresti in molti casi. Un esempio è in una relazione come OrderHeadere OrderDetail. Il PK OrderHeaderpotrebbe esserlo OrderNumber. Il PK in OrderDetailpotrebbe essere OrderNumberAND LineNumber. Se fosse uno di quei due, non sarebbe unico, ma la combinazione dei due è garantita unica.

L'alternativa è utilizzare una chiave primaria generata (non intelligente), ad esempio in questo caso OrderDetailId. Ma allora non vedresti sempre la relazione così facilmente. Alcune persone preferiscono un modo; alcuni preferiscono l'altro modo.


2
È utile se sto usando branch_id e usando la replica tra due database, risolverà il duplicato di ID? !!
Mhmd

11
Tieni presente che in molti casi di utilizzo di una chiave primaria generata, spesso desideri comunque una chiave univoca sui valori compositi.
Bacon Bits,

Per favore, approfondisci "Alcune persone preferiscono un modo; altri preferiscono l'altro".
Nome utente

1
Motivi elaborati? Non sono sicuro di cosa dire. Ho conosciuto persone che preferiscono avere più campi concatenati come chiave perché è più facile capire intuitivamente cosa stanno guardando. Ne ho conosciuti altri che preferiscono assegnare solo una chiave univoca a ciascuna riga perché è più facile e veloce da digitare. È questo che stai chiedendo?
MJB

Quel messaggio era destinato a @Username. Ho dimenticato di dirigerlo.
MJB

26

Un altro esempio di chiavi primarie composte è l'utilizzo delle tabelle di associazione. Supponi di avere una tabella di persone che contiene un insieme di persone e una tabella di gruppo che contiene un insieme di gruppi. Ora vuoi creare una relazione molti a molti su persona e gruppo. Significa che ogni persona può appartenere a molti gruppi. Ecco come sarebbe la struttura della tabella utilizzando una chiave primaria composta.

Create Table Person(
PersonID int Not Null,
FirstName varchar(50),
LastName varchar(50),
Constraint PK_Person PRIMARY KEY (PersonID))

Create Table Group (
GroupId int Not Null,
GroupName varchar(50),
Constraint PK_Group PRIMARY KEY (GroupId))

Create Table GroupMember (
GroupId int Not Null,
PersonId int Not Null,
CONSTRAINT FK_GroupMember_Group FOREIGN KEY (GroupId) References Group(GroupId),
CONSTRAINT FK_GroupMember_Person FOREIGN KEY (PersonId) References Person(PersonId),
CONSTRAINT PK_GroupMember PRIMARY KEY (GroupId, PersonID))

ottima spiegazione: penso che la chiave sia la necessità di attributi per le relazioni m-to-n (in una modalità normalizzata).
Wolf,

forse aggiungere una piccola spiegazione di vantaggio sarebbe ancora meglio
Martian2049

10

L'esempio W3Schools non dice quando è necessario utilizzare chiavi primarie composte e fornisce solo la sintassi di esempio utilizzando la stessa tabella di esempio delle altre chiavi.

La loro scelta di esempio ti sta forse fuorviando combinando una chiave priva di significato (P_Id) e una chiave naturale (LastName). Questa strana scelta della chiave primaria dice che le seguenti righe sono valide secondo lo schema e sono necessarie per identificare in modo univoco uno studente. Intuitivamente questo non ha senso.

1234     Jobs
1234     Gates

Ulteriori letture: il grande dibattito sulla chiave primaria o solo Google meaningless primary keyso persino esaminare questa domanda SO

FWIW - I miei 2 centesimi sono di evitare chiavi primarie a più colonne e utilizzare un singolo campo id generato (chiave surrogata) come chiave primaria e aggiungere ulteriori vincoli (univoci) dove necessario.


1
1) il collegamento "grande dibattito sulla chiave primaria" è particolarmente stupido, le informazioni sono auto-utili e false. 2) Non si può evitare l'indice sulle colonne che rendono la riga univoca. Un ID "surrogato" con un indice è sempre una colonna aggiuntiva e un indice aggiuntivo. Piuttosto sciocco perché è ridondante. E più lento.
PerformanceDBA

2
Il "grande dibattito sulle chiavi primarie" non è stupido. È un problema molto valido per gli sviluppatori che non sono sviluppatori sql o DBA sql e non trascorrono tutto il loro tempo in sql. Anche in sql puro preferirei avere una chiave generata automaticamente senza significato come chiave primaria quando ci si unisce piuttosto che ricordarsi di passare n bit di dati intorno a essere la chiave naturale. Sei il benvenuto nel tuo punto di vista, ma apprezzeremmo non essere così sprezzante.
Robert Paulson

4

Si utilizza una chiave composta (una chiave con più di un attributo) ogni volta che si desidera garantire l'unicità di una combinazione di più attributi. Una singola chiave attributo non otterrebbe la stessa cosa.


1
Per quanto riguarda la garanzia di una chiave univoca, potresti fare affidamento sulla combinazione di due attributi per formare una chiave che logicamente non può essere duplicata, Persona e data di laurea da un set di dati più grande sarebbero un esempio.
John Mark

3

Sì, entrambi formano la chiave primaria. Soprattutto nelle tabelle in cui non si dispone di una chiave surrogata , potrebbe essere necessario specificare più attributi come identificatore univoco per ogni record (cattivo esempio: una tabella con sia un nome che un cognome potrebbe richiedere che la combinazione di essi sia unico).


3

Più colonne in una chiave avranno, in generale, prestazioni inferiori rispetto a una chiave surrogata. Preferisco avere una chiave surrogata e quindi un indice univoco su una chiave a più colonne. In questo modo è possibile ottenere prestazioni migliori e l'unicità necessaria viene mantenuta. E ancora meglio, quando uno dei valori in quella chiave cambia, non è necessario aggiornare anche un milione di voci figlio in 215 tabelle figlio.


1
1) Prestazioni. Non in una piattaforma SQL (forse nel finto "sql" e freeware). 2) La preferenza è irrilevante. Ciò che le tabelle richiedono, per l'integrità, è rilevante. 3) Un ID "surrogato" con un indice è sempre una colonna aggiuntiva e un indice aggiuntivo . Quindi sarebbe più lento, su qualsiasi piattaforma. Rispetto alla performance, ti contraddichi. 4) Se non sai come aggiornare correttamente il mitico "milione di voci figlio in 215 tabelle figlio" , fai una domanda.
Performance

2
Non sono d'accordo con l'affermazione "Più colonne in una chiave, in generale, si comportano più male di una chiave surrogata". Spesso è necessaria una query aggiuntiva per ottenere la chiave surrogata di una relazione quando la si considera. A quel punto è un viaggio di andata e ritorno completo più lento in termini di prestazioni.
ttugates

3

La tua seconda domanda

Quante colonne possono essere utilizzate insieme come chiave primaria in una determinata tabella?

è specifico dell'implementazione: è definito nel DBMS in uso. [1], [2], [3] Devi controllare le specifiche tecniche del sistema di database che utilizzi. Alcuni sono molto dettagliati, altri no. La ricerca sul Web di tali limitazioni può essere difficile perché la terminologia varia. Il termine chiave primaria composita dovrebbe essere obbligatorio;)

Se non riesci a trovare informazioni esplicite, prova a creare un database di prova per assicurarti di poter aspettarti una gestione stabile (e specifica) delle violazioni dei limiti (che sono prevedibili). Fai attenzione a ottenere le giuste informazioni su questo: a volte i limiti vengono accumulati e vedrai risultati diversi con diversi layout di database.



2

L'utilizzo di una chiave primaria su più tabelle è utile quando si utilizza una tabella intermedia in un database relazionale.

Userò un database che ho creato una volta per un esempio e in particolare tre tabelle all'interno di quella tabella. Alcuni anni fa ho creato un database per un webcomic. Una tabella era chiamata "fumetti", un elenco di tutti i fumetti, i loro titoli, il nome del file di immagine, ecc. La chiave primaria era "comicnum".

La seconda tabella era "caratteri": i loro nomi e una breve descrizione. La chiave primaria era su "charname".

Poiché ogni fumetto, con alcune eccezioni, aveva più personaggi e ogni personaggio appariva all'interno di più fumetti, non era pratico inserire una colonna in "personaggi" o "fumetti" per riflettere ciò. Invece, ho creato una terza tabella chiamata "comicchars", e quella era una lista di quali personaggi apparivano in quali fumetti. Poiché questa tabella essenzialmente univa le due tabelle, aveva bisogno solo di due colonne: charname e comicnum, e la chiave primaria era su entrambe.


1

Creiamo chiavi primarie composite per garantire i valori di colonna di unicità che compongono un singolo record. È un vincolo che aiuta a prevenire l'inserimento di dati che non dovrebbero essere duplicati.

ad esempio: se tutti gli ID degli studenti e i numeri dei certificati di nascita sono assegnati in modo univoco a una singola persona. Quindi sarebbe una buona idea rendere la chiave primaria di una persona una composizione di ID studente e numero di certificato di nascita perché impedirebbe di inserire accidentalmente due persone che hanno ID studente diversi e lo stesso certificato di nascita.

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.