Dire che l'uso di "Composite keys as PRIMARY KEY is bad practice"
è una totale assurdità!
I compositi PRIMARY KEY
sono spesso una "cosa buona" e l'unico modo per modellare situazioni naturali che si verificano nella vita di tutti i giorni!
Pensa al classico esempio di database di Database-101 di studenti e corsi e ai numerosi corsi seguiti da molti studenti!
Crea corso tavoli e studente:
CREATE TABLE course
(
course_id SERIAL,
course_year SMALLINT NOT NULL,
course_name VARCHAR (100) NOT NULL,
CONSTRAINT course_pk PRIMARY KEY (course_id)
);
CREATE TABLE student
(
student_id SERIAL,
student_name VARCHAR (50),
CONSTRAINT student_pk PRIMARY KEY (student_id)
);
Ti darò l'esempio nel dialetto PostgreSQL (e MySQL ) - dovrebbe funzionare per qualsiasi server con un po 'di modifiche.
Ora, ovviamente, vuoi tenere traccia di quale studente sta seguendo quale corso - quindi hai quello che viene chiamato un joining table
(anche chiamato linking
, many-to-many
o m-to-n
tabelle). Sono anche conosciuti come associative entities
in gergo tecnico!
1 corso può avere molti studenti.
1 studente può seguire molti corsi.
Quindi, si crea una tabella di unione
CREATE TABLE course_student
(
cs_course_id INTEGER NOT NULL,
cs_student_id INTEGER NOT NULL,
-- now for FK constraints - have to ensure that the student
-- actually exists, ditto for the course.
CREATE CONSTRAINT cs_course_fk FOREIGN KEY (cs_course_id) REFERENCES course (course_id),
CREATE CONSTRAINT cs_student_fk FOREIGN KEY (cs_student_id) REFERENCES student (student_id)
);
Ora, l' unico modo per dare ragionevolmente a questo tavolo PRIMARY KEY
è quello di creare KEY
una combinazione di corso e studente. In questo modo, non puoi ottenere:
un duplicato della combinazione studente e corso
hai anche una ricerca pronta KEY
per corso per studente - AKA un indice di copertura ,
è banale trovare corsi senza studenti e studenti che non seguono corsi!
- L' esempio db-fiddle ha il vincolo PK ripiegato nella CREATE TABLE - Può essere fatto in entrambi i modi. Preferisco avere tutto nell'istruzione CREATE TABLE.
ALTER TABLE course_student
ADD CONSTRAINT course_student_pk
PRIMARY KEY (cs_course_id, cs_student_id);
Ora, potresti scoprire che se le ricerche degli studenti per corso erano lente, usa a UNIQUE INDEX
on (sc_student_id, sc_course_id).
ALTER TABLE course_student
ADD CONSTRAINT course_student_sc_uq
UNIQUE (cs_student_id, cs_course_id);
Non v'è alcuna pallottola d'argento per l'aggiunta di indici - che saranno rendere INSERT
s e UPDATE
s più lento, ma al grande vantaggio di enorme decrescentiSELECT
volte! Spetta allo sviluppatore decidere di indicizzare in base alle proprie conoscenze ed esperienze, ma dire che i compositi PRIMARY KEY
sono sempre cattivi è semplicemente sbagliato.
Nel caso di unirsi ai tavoli, di solito sono gli unici PRIMARY KEY
che hanno senso! Partecipare ai tavoli è anche molto spesso l'unico modo di modellare ciò che accade nel mondo degli affari o della natura o praticamente in ogni ambito a cui riesco a pensare!
Questo PK è anche covering index
utile per accelerare le ricerche. In questo caso, sarebbe particolarmente utile se si cercasse regolarmente (course_id, student_id) che, si potrebbe immaginare, spesso può essere il caso!
Questo è solo un piccolo esempio di dove un composito PRIMARY KEY
può essere un'ottima idea e l'unico modo sano per modellare la realtà! In cima alla mia testa, posso pensare a molti altri.
Un esempio dal mio stesso lavoro!
Prendi in considerazione una tabella di volo contenente un flight_id, un elenco di aeroporti di partenza e di arrivo e gli orari pertinenti e quindi anche una tabella di cabine con i membri dell'equipaggio!
L' unico modo sano per modellare questo è di avere una tabella flight_crew con flight_id e crew_id come attibutes e l'unico modo sano PRIMARY KEY
è usare la chiave composita dei due campi!