Zu sagen, dass die Verwendung von "Composite keys as PRIMARY KEY is bad practice"
völlig Unsinn ist!
Verbundwerkstoffe PRIMARY KEY
sind oft eine sehr "gute Sache" und die einzige Möglichkeit, natürliche Situationen im Alltag zu modellieren!
Denken Sie an das klassische Lehrbeispiel Databases-101 für Studenten und Kurse und an die vielen Kurse, die von vielen Studenten besucht werden!
Erstellen Sie Tabellen Kurs und Schüler:
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)
);
Ich gebe Ihnen das Beispiel im PostgreSQL-Dialekt (und MySQL ) - sollte für jeden Server mit ein wenig Optimierung funktionieren.
Jetzt wollen Sie natürlich den Überblick behalten , von denen Schüler nehmen , welcher Kurs - so haben Sie , was eine genannt wird joining table
(auch genannt linking
, many-to-many
oder m-to-n
Tabellen). Sie sind auch als associative entities
eher im Fachjargon bekannt!
1 Kurs kann viele Studenten haben.
1 Student kann viele Kurse belegen.
Sie erstellen also eine Verbindungstabelle
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)
);
Die einzige Möglichkeit, diesem Tisch eine sinnvolle Note zu geben, PRIMARY KEY
besteht darin, KEY
eine Kombination aus Kurs und Schüler zu erstellen. Auf diese Weise können Sie nicht bekommen:
ein Duplikat der Kombination aus Student und Kurs
Sie haben auch eine fertige Suche KEY
nach Kurs pro Schüler - AKA ein Deckungsindex ,
Es ist trivial, Kurse ohne Studenten und Studenten zu finden, die keine Kurse belegen!
- Das db-Geige Beispiel hat die PK Einschränkung in die CREATE TABLE gefaltet - Es kann so oder so durchgeführt werden. Ich bevorzuge es, alles in der Anweisung CREATE TABLE zu haben.
ALTER TABLE course_student
ADD CONSTRAINT course_student_pk
PRIMARY KEY (cs_course_id, cs_student_id);
Wenn Sie feststellen, dass die Suche nach Schülern nach Kurs langsam war, können Sie ein UNIQUE INDEX
on (sc_student_id, sc_course_id) verwenden.
ALTER TABLE course_student
ADD CONSTRAINT course_student_sc_uq
UNIQUE (cs_student_id, cs_course_id);
Es gibt kein Allheilmittel Indizes für das Hinzufügen - sie werden machen INSERT
s und UPDATE
s langsamer, aber im großen Vorteil enorm abnimmtSELECT
Zeiten! Es ist in den Entwickler bis zu indizieren ihre Kenntnisse und Erfahrungen gegeben , um zu entscheiden, aber zu sagen , dass Verbund PRIMARY KEY
s sind immer schlecht ist schlicht und einfach falsch.
Beim Verbinden von Tabellen sind sie normalerweise die einzigen PRIMARY KEY
, die Sinn machen! Das Verbinden von Tabellen ist auch sehr häufig die einzige Möglichkeit zu modellieren, was in der Wirtschaft oder in der Natur oder in praktisch jeder Sphäre passiert, die mir einfällt!
Diese PK ist auch nützlich, covering index
um die Suche zu beschleunigen. In diesem Fall wäre es besonders nützlich, wenn man regelmäßig nach (course_id, student_id) sucht, was, wie man sich vorstellen kann, oft der Fall sein kann!
Dies ist nur ein kleines Beispiel dafür, wo ein Komposit PRIMARY KEY
eine sehr gute Idee sein kann und der einzig vernünftige Weg, die Realität zu modellieren! Auf den ersten Blick fällt mir noch viel mehr ein.
Ein Beispiel aus meiner eigenen Arbeit!
Betrachten Sie eine Flugtabelle mit einer Flug-ID, einer Liste der Abflug- und Ankunftsflughäfen und den relevanten Zeiten sowie eine Cabin_crew-Tabelle mit Besatzungsmitgliedern!
Die einzig vernünftige Möglichkeit, dies zu modellieren, besteht darin, eine Flight_Crew-Tabelle mit der Flight_ID und der Crew_ID als Attribut zu haben. Die einzig vernünftige Möglichkeit PRIMARY KEY
besteht darin, den zusammengesetzten Schlüssel der beiden Felder zu verwenden!