數據建模是藝術代表關係圖中的真實世界。你的模式是正確的,但它是真的嗎?
想一想,什麼是CLASS?這是一個教師,一個主題和一個等級。那些是你的關係。此外,您還想強制規定主語適用於該等級,並且教師可以在該等級中教授該主語。
我認爲你的問題在於使用交叉表中的代理鍵。這些表格代表您的多對多關係:teacher_subject
,grade_subject
。無論如何,這些都是合成表,而且它們只是由鍵組成。因此,複合主鍵就足夠了。
代理主鍵沒有意義,所以我們需要定義一個唯一約束grade_subject(subject_id, grade_id)
以確保我們沒有兩個記錄('PHYSICS','YEAR 2')。鑑於grade_subject
是一個沒有其他列添加代理鍵的交集表是毫無意義的。代理鍵的價值在於最小化業務密鑰更改的影響。但grade_subject
沒有商業密鑰,只有兩個代理鍵subject_id
和grade_id
。
當涉及到定義引用完整性時,這具有優勢。
所以我會接近你的問題是這樣的:
grade_subject
----------------
grade_id
subject_id
primary key (grade_id, subject_id)
foreign key (grade_id) reference grade (grade_id)
foreign key (subject_id) reference subject (subject_id)
teacher_subject
---------------------
teacher_id
grade_id
subject_id
primary key (teacher_id,grade_id, subject_id)
foreign key (grade_id) reference grade (grade_id)
foreign key (subject_id) reference subject (subject_id)
foreign key (teacher_id) reference teacher (teacher_id)
foreign key (grade_id,subject_id) reference grade_subject (grade_id,subject_id)
Class
-----------------------------------
id
teacher_id
grade_id
subject_id
primary key (id)
foreign key (grade_id) reference grade (grade_id)
foreign key (subject_id) reference subject (subject_id)
foreign key (teacher_id) reference teacher (teacher_id)
foreign key (grade_id,subject_id) reference grade_subject (grade_id,subject_id)
foreign key (teacher_id,grade_id,subject_id) reference teacher_subject (teacher_id,grade_id,subject_id)
這可能看起來像外鍵一堆了,我可以在審查階段設想一些參數。 (我在grade_subject
上包含了外鍵,所以我有些事情可以承認我不關心那麼多,所以可以承認)。
但我不喜歡通過像TEACHER_SUBJECT這樣的輔助關係強制執行混淆CLASS_SUBJECT等重要數據關係。我不想加入到TEACHER_SUBJECT和SUBJECT_GRADE以便將CLASS加入到SUBJECT中。
現在,當後者間接強制執行前者時,爲什麼我會選擇將參照完整性約束包含到單個父表和交叉表中?因爲它使模型中的關係更清晰。我在該模型中強調,因爲在物理數據庫中,我可能會選擇省略單個表外鍵或禁用它們,並相信交集表的關係完整性。
關於三列組合的一些問題使我感到困惑,我想是這樣的:它沒有足夠標準化。你可能有一個特例,但更一般的模型是兩個規則,TEACHER_SUBJECT和TEACHER_GRADE。這應該是這樣的
teacher_subject
---------------------
teacher_id
subject_id
primary key (teacher_id, subject_id)
foreign key (subject_id) reference subject (subject_id)
foreign keye (teacher_id) reference teacher (teacher_id)
teacher_grade
---------------------
teacher_id
grade_id
primary key (teacher_id,grade_id)
foreign key (grade_id) reference grade (grade_id)
foreign key (teacher_id) reference teacher (teacher_id)
Class
-----------------------------------
id
teacher_id
grade_id
subject_id
primary key (id)
foreign key (grade_id) reference grade (grade_id)
foreign key (subject_id) reference subject (subject_id)
foreign key (teacher_id) reference teacher (teacher_id)
foreign key (grade_id,subject_id) reference grade_subject (grade_id,subject_id)
foreign key (teacher_id,subject_id) reference teacher_subject (teacher_id,subject_id)
foreign key (teacher_id,grade_id) reference teacher_grade (teacher_id,grade_id)
當然,如果你還是想執行的規則德魯先生只能教數學到第四劑和物理學到六年級學生就需要有TEACHER_SUBJECT_GRADE表。
您的數據模型沒有解決的一件事是調度問題。學校的時間表必須網格化,所以課程需要適合預先確定的網格。您可能需要將時間表的插槽定義爲單獨的表格,並將CLASS鏈接到該表格。課堂也需要教室。那是另一張桌子。
非常感謝APC提供的答案和時間。你的設計中有兩件事是我可憐的大腦無法理解的。 1)代理鍵:不會有一個唯一的(自動增量)整數是否足夠?使用複合主鍵有什麼好處? (2)在teacher_subject表中,爲什麼使用(grade_id,subject_id)作爲外鍵,而grade_id和subject_id已被單獨用作外鍵?對不起,我的無知。但如果你能向我解釋這一點,我會很感激你。週末愉快。 – 2012-04-20 13:27:35