Foreign-Key

如何用 UNIQUE 索引和外鍵表示它?

  • July 5, 2013

“小組”是一群學生。“主題”是課程的主題。

每個組都對應一個主題。(因此每個主題可能有多個組。)

一個學生對應多個組,但每個主題最多一個組。

如何根據 MySQL 中的 UNIQUE 索引和外鍵來實現這一點?

這是一個常見的問題。“訣竅”是:

  • 添加Groups- 除了主鍵 - 上的冗餘唯一約束(Topic, Group)
  • 這允許您Topic在關係中添加屬性Participates
  • 強制您將 Foreign Key 約束從 to 修改ParticipatesGroups因此它Topic不僅包括Group.
  • 然後您可以添加唯一約束Participates (Pupil, Topic)(意味著學生只能參與一次主題,而不是兩次或更多,這是想要的結果。)
Topics
 Topic  PK

Lessons
 Lesson PK 
 Topic         FK -> Topics

Groups
 Group  PK UQ1
 Topic     UQ1 FK -> Topics  

Pupils
 Pupil  PK

PupilParticipatesInGroup
 Pupil  PK UQ1 FK1 -> Pupils
 Group  PK     FK2 -> Groups
 Topic     UQ1 FK2 

附錄

Abbreviation   Constraint
------------   -----------
  PK           Primary Key
  UQ           Unique 
  FK           Foreign Key

請注意,設計已經完成,**3NF**並且冗餘唯一約束Topics僅在大多數 DBMS 中實現時才需要(因此強制執行外鍵。)

唯一的另一個問題是Group -> Topic關係中的依賴Participates關係使模式違反**BCNF**。

在連結頁面的Achievability of BCNF段落中,您會看到已證明並非所有表都可以分解為滿足BCNF並保留原始表中包含的依賴關係的表。Participates提供的範例與此處的表格非常相似:

在某些情況下,非 BCNF 表無法分解為滿足 BCNF 並保留原始表中保存的依賴關係的表。Beeri 和 Bernstein 在 1979 年表明,例如,一組函式依賴{AB → C, C → B}不能用 BCNF 模式表示。

$$ 6 $$因此,與前三種範式不同,BCNF 並不總是可以實現的。

儘管如此,讓我們再做一個改變,以解決這個問題(如果可以的話!):


讓我們檢查一下如果我們從Primary Key (Group)約束中刪除(好像它從未存在過) Groups(並將唯一性放在它的位置)會發生什麼。讓我們也將主鍵更改為Participates- 注意 - 從一開始就是我們的目標的唯一約束. 設計變為(前兩個表被省略,因為它們保持不變):

   Groups
     Group  PK 
     Topic  PK     FK -> Topics  

   Pupils
     Pupil  PK

   PupilParticipatesInGroup
     Pupil  PK     FK1 -> Pupils
     Group         FK2 -> Groups
     Topic  PK     FK2 

根本沒有多餘的列。魔法!這是和(正如我們的模型想要的那樣)Participates之間的常見多對多關係,並且兩個外鍵引用相應表的主鍵。Groups``Pupils

所以發生了什麼事?魔法?(不是真的,不是)而且不是Group仍然是候選鍵Groups嗎?(無論如何,刪除它只是一個思想實驗。)從實際表中省略這個約束,我們不會失去一些東西嗎?


問題 - 以及上述解決問題的原因 - 是您嘗試建模的唯一約束需要關係中的Topic屬性Participates。因此,您必須使用Groups複合且包含的候選鍵Topic。它不一定是(Topic, Group). 它可能是其他一些組合。還有什麼其他屬性Groups

例如,如果and中有一個屬性OrderNo是唯一的,那麼我們可以有這樣的設計(終於!),沒有冗餘,沒有多餘的屬性,所有約束都在那裡,並且模式位於:Groups``(Topic, OrderNo``BCNF

   Groups
     Group   PK 
     Topic      UQ1 FK -> Topics
     OrderNo    UQ1

   Pupils
     Pupil   PK

   PupilParticipatesInGroup
     Pupil   PK     FK1 -> Pupils
     Topic   PK     FK2 -> Groups
     OrderNo        FK2 

引用自:https://dba.stackexchange.com/questions/45744