の使用"Composite keys as PRIMARY KEY is bad practice"
はまったくナンセンスだと言うには!
コンポジットPRIMARY KEY
は多くの場合非常に「良いこと」であり、日常生活で発生する自然な状況をモデル化する唯一の方法です。
古典的なDatabases-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
をコースと学生の組み合わせにすることです。そのようにすると、以下を取得できません。
学生とコースの組み合わせの複製
コースは同じ学生を1回のみ登録できます。
学生は同じコースに1回のみ登録できます
また、KEY
学生ごとのコースの既製の検索もあります。
学生のいないコースや、コースを履修していない学生を見つけるのは簡単です。
-db-fiddleの例では、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
遅くだが、非常に大きな利点で減少SELECT
回!知識と経験を踏まえてインデックスを作成するかどうかは開発者次第ですが、コンポジットPRIMARY KEY
は常に悪いと言うのは間違いです。
テーブルを結合する場合、それらは通常、意味のある唯一の PRIMARY KEY
ものです!テーブルを結合することは、ビジネスや自然、または私が考えることができるほぼすべての領域で何が起こるかをモデル化する唯一の方法でもあります。
このPKは、covering index
検索の高速化に役立つとしても使用されます。この場合、(course_id、student_id)を定期的に検索していると特に便利です。
これは、コンポジットPRIMARY KEY
が非常に優れたアイデアであり、現実をモデル化する唯一の健全な方法のほんの一例です!私の頭の上から、私はもっと多くのことを考えることができます。
私自身の作品の例!
flight_id、出発空港と到着空港のリスト、および関連する時刻が含まれているフライトテーブルを検討してください。さらに、搭乗員がいるcabin_crewテーブルも検討してください。
唯一これをモデル化することができる健全な方法はattibutesとしてflight_idとcrew_idでflight_crewテーブルを持つことであり、唯一の正気は、PRIMARY KEY
二つのフィールドの複合キーを使用することです!