Để nói rằng việc sử dụng "Composite keys as PRIMARY KEY is bad practice"
là hoàn toàn vô nghĩa!
Các hỗn hợp PRIMARY KEY
thường là một "điều tốt" và là cách duy nhất để mô hình hóa các tình huống tự nhiên xảy ra trong cuộc sống hàng ngày!
Hãy nghĩ về ví dụ giảng dạy Cơ sở dữ liệu-101 cổ điển của sinh viên và các khóa học và nhiều khóa học được thực hiện bởi nhiều sinh viên!
Tạo bảng khóa học và sinh viên:
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)
);
Tôi sẽ cho bạn ví dụ trong phương ngữ PostgreSQL (và MySQL ) - sẽ hoạt động cho bất kỳ máy chủ nào có một chút điều chỉnh.
Bây giờ, bạn rõ ràng là muốn theo dõi trong đó học sinh được tham gia trong đó dĩ nhiên - vì vậy bạn có những gì được gọi là joining table
(hay còn gọi là linking
, many-to-many
hoặc m-to-n
bảng). Họ cũng được biết đến như associative entities
trong thuật ngữ kỹ thuật hơn!
1 khóa học có thể có nhiều sinh viên.
1 sinh viên có thể học nhiều khóa.
Vì vậy, bạn tạo một bảng tham gia
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)
);
Bây giờ, cách duy nhất để đưa ra bảng này một cách hợp lý PRIMARY KEY
là biến nó KEY
thành sự kết hợp giữa khóa học và sinh viên. Bằng cách đó, bạn không thể có được:
một bản sao của sự kết hợp giữa sinh viên và khóa học
một khóa học chỉ có thể có cùng một sinh viên đăng ký một lần, và
một sinh viên chỉ có thể đăng ký vào cùng một khóa học một lần duy nhất
bạn cũng có một tìm kiếm sẵn sàng KEY
về khóa học cho mỗi học sinh - AKA một chỉ số bao trùm ,
Thật là tầm thường khi tìm các khóa học mà không có học sinh và sinh viên không tham gia khóa học!
- Ví dụ db-fiddle có ràng buộc PK được gấp lại thành BẢNG TẠO - Nó có thể được thực hiện theo một trong hai cách. Tôi thích có mọi thứ trong câu lệnh CREATE TABLE.
ALTER TABLE course_student
ADD CONSTRAINT course_student_pk
PRIMARY KEY (cs_course_id, cs_student_id);
Bây giờ, bạn có thể, nếu bạn thấy rằng các tìm kiếm cho sinh viên theo khóa học là chậm, hãy sử dụng một UNIQUE INDEX
(sc_student_id, sc_cference_id).
ALTER TABLE course_student
ADD CONSTRAINT course_student_sc_uq
UNIQUE (cs_student_id, cs_course_id);
Không có viên đạn bạc nào để thêm chỉ mục - chúng sẽ làm cho INSERT
s và UPDATE
s chậm hơn, nhưng với lợi ích lớn là thời gian giảm mạnhSELECT
! Tùy thuộc vào nhà phát triển quyết định lập chỉ mục dựa trên kiến thức và kinh nghiệm của họ, nhưng để nói rằng PRIMARY KEY
các s composite luôn xấu thì hoàn toàn sai.
Trong trường hợp tham gia các bảng, chúng thường là duy nhất PRIMARY KEY
có ý nghĩa! Tham gia các bảng cũng rất thường xuyên là cách duy nhất để mô hình hóa những gì xảy ra trong kinh doanh hoặc tự nhiên hoặc trong hầu hết mọi lĩnh vực tôi có thể nghĩ đến!
PK này cũng được sử dụng như một covering index
thứ có thể giúp tăng tốc tìm kiếm. Trong trường hợp này, nó sẽ đặc biệt hữu ích nếu một người tìm kiếm thường xuyên trên (Course_id, student_id), mà người ta có thể tưởng tượng, thường có thể là trường hợp!
Đây chỉ là một ví dụ nhỏ về việc một hỗn hợp PRIMARY KEY
có thể là một ý tưởng rất tốt và là cách duy nhất để mô hình hóa thực tế! Ngoài đỉnh đầu, tôi có thể nghĩ về nhiều thứ nữa.
Một ví dụ từ công việc của tôi!
Hãy xem xét một bảng chuyến bay có chứa một chuyến bay_id, một danh sách các sân bay khởi hành và đến và thời gian liên quan và sau đó là một bảng cabin_crew với các thành viên phi hành đoàn!
Cách duy nhất có thể được mô hình hóa này là có một bảng bay_crew với chuyến bay_id và crew_id như các tùy chọn và cách duy nhất PRIMARY KEY
là sử dụng khóa tổng hợp của hai trường!