Powiedzieć, że użycie "Composite keys as PRIMARY KEY is bad practice"jest kompletnym nonsensem!
Kompozyty PRIMARY KEYsą często bardzo „dobrą rzeczą” i jedynym sposobem na modelowanie naturalnych sytuacji występujących w życiu codziennym!
Pomyśl o klasycznym przykładzie nauczania baz danych 101 i uczniach oraz o kursach wielu studentów!
Stwórz tabelę kursu i ucznia:
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)
);
Dam ci przykład w dialekcie PostgreSQL (i MySQL ) - powinien działać na każdym serwerze z drobnymi poprawkami.
Teraz oczywiście chcą śledzić której uczeń bierze który oczywiście - tak masz, co się nazywa joining table(zwane również linking, many-to-manyczy m-to-ntabele). Znane są również jako associative entitiesw bardziej technicznym żargonie!
1 kurs może mieć wielu studentów.
1 uczeń może wziąć udział w wielu kursach.
Tak więc tworzysz tabelę łączenia
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)
);
Teraz jedynym sposobem na rozsądne nadanie temu stołowi PRIMARY KEYjest KEYpołączenie tego kursu z uczniem. W ten sposób nie możesz uzyskać:
duplikat kombinacji studentów i kursów
masz również gotowe wyszukiwanie KEYkursu na ucznia - AKA indeks obejmujący ,
znalezienie kursów bez studentów i studentów, którzy nie biorą kursów jest banalne!
- db-skrzypce przykładem jest ograniczenie PK złożony do tabeli Create - Można to zrobić w obu kierunkach. Wolę mieć wszystko w instrukcji CREATE TABLE.
ALTER TABLE course_student
ADD CONSTRAINT course_student_pk
PRIMARY KEY (cs_course_id, cs_student_id);
Teraz, jeśli okaże się, że wyszukiwanie studentów według kursu było powolne, UNIQUE INDEXmożesz użyć opcji on (sc_student_id, sc_course_id).
ALTER TABLE course_student
ADD CONSTRAINT course_student_sc_uq
UNIQUE (cs_student_id, cs_course_id);
Nie ma srebrnej kuli do dodawania indeksów - sprawią, że INSERTs i UPDATEs będą wolniejsze, ale z wielką korzyścią ze znacznie krótszychSELECT czasów! Deweloper musi zdecydować o zaindeksowaniu ze względu na swoją wiedzę i doświadczenie, ale stwierdzenie, że kompozyt PRIMARY KEYjest zawsze zły, jest po prostu błędne.
W przypadku łączenia stolików są one zwykle jedyne, PRIMARY KEY które mają sens! Łączenie stołów jest również bardzo często jedynym sposobem modelowania tego, co dzieje się w biznesie, przyrodzie lub w praktycznie każdej sferze, o której myślę!
Ten PK jest również przydatny jako narzędzie, covering indexktóre może przyspieszyć wyszukiwanie. W takim przypadku byłoby szczególnie przydatne, gdybyś regularnie szukał (course_id, student_id), co, jak można sobie wyobrazić, często może mieć miejsce!
To tylko mały przykład, gdzie kompozyt PRIMARY KEYmoże być bardzo dobrym pomysłem i jedynym rozsądnym sposobem modelowania rzeczywistości! Z czubka głowy mogę wymyślić o wiele więcej.
Przykład z mojej własnej pracy!
Rozważmy tabelę lotów zawierającą identyfikator lotu, listę lotnisk odlotów i przylotów oraz odpowiednie czasy, a następnie tabelę personelu pokładowego z członkami załogi!
Jedyny rozsądny sposób ten może być modelowany jest mieć stolik flight_crew z flight_id i crew_id jako atrybuty reklamy i jedynym SANE PRIMARY KEYjest użycie klucza kompozytowego z dwóch pól!