Сказати, що використання - "Composite keys as PRIMARY KEY is bad practice"
це сувора нісенітниця!
Композиція PRIMARY KEY
часто - це дуже "добра річ" і єдиний спосіб моделювати природні ситуації, що трапляються в повсякденному житті!
Подумайте про класичний приклад баз даних-101 для студентів та курсів та про безліч курсів, які проходять багато студентів!
Створіть таблицю курсу та студента:
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)
);
Я наведу вам приклад в діалекті PostgreSQL (і MySQL ) - повинен працювати на будь-якому сервері, який трохи налаштовує.
Тепер ви, очевидно, хочете відслідковувати, який студент проходить який курс - так у вас є те, що називається joining table
(також називається linking
, many-to-many
або m-to-n
таблиці). Вони також відомі як associative entities
у більш технічному жаргоні!
1 курс може мати багато студентів.
1 студент може пройти багато курсів.
Отже, ви створюєте таблицю приєднання
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)
);
Тепер єдиний спосіб розумно дати цій таблиці PRIMARY KEY
- KEY
це поєднання курсу та студента. Таким чином, ви не можете отримати:
дублікат комбінації студентів та курсів
на курс може бути записаний той самий студент лише один раз, і
студент може записатися на той самий курс лише один раз
у вас також є готовий пошук KEY
курсів на одного студента - AKA показник покриття ,
Неважливо знайти курси без студентів та студентів, які не беруть курсів!
- ДБ-скрипці приклад має обмеження PK складене в CREATE TABLE - Це може бути зроблено в будь-якому випадку. Я вважаю за краще, щоб все було у викладі CREATE TABLE.
ALTER TABLE course_student
ADD CONSTRAINT course_student_pk
PRIMARY KEY (cs_course_id, cs_student_id);
Тепер ви могли б, якби виявили, що пошук студента за курсом повільний, скористатися 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);
Там немає ні срібної кулі для додавання індексів - вони будуть робити INSERT
з і UPDATE
S повільніше, але на великий зиск надзвичайно убутніSELECT
раз! Розробник повинен вирішити індексувати, враховуючи свої знання та досвід, але сказати, що композитні PRIMARY KEY
s завжди погані, це просто неправильно.
У випадку приєднання таблиць вони, як правило, єдині, PRIMARY KEY
що мають сенс! Приєднання до столів також дуже часто є єдиним способом моделювання того, що відбувається в бізнесі чи природі чи практично у будь-якій сфері, про яку я можу придумати!
Цей ПК також використовується в якості covering index
засобу, який може допомогти прискорити пошук. У цьому випадку було б особливо корисно, якби хтось регулярно здійснював пошук на (course_id, student_id), що, можна було б уявити, часто може бути!
Це лише невеликий приклад того, де композит PRIMARY KEY
може бути дуже хорошою ідеєю і єдиним розумним способом моделювання реальності! Я маю на увазі ще багато інших.
Приклад з моєї власної роботи!
Розгляньте таблицю польотів, що містить переліт_id, перелік аеропортів вильоту та прибуття та відповідні часи, а потім також таблицю екіпажних кабін з членами екіпажу!
Тільки розумний спосіб це може бути змодельоване, щоб мати таблицю flight_crew з flight_id і crew_id як і атрибути оголошення єдиними розумними PRIMARY KEY
, щоб використовувати складовою ключ з двох полів!