天天看點

徹底了解資料庫ER模型(CDM)中的強實體與弱實體:追根到底

目錄

    • 寫在最前
    • 一、 強實體與弱實體的定義
      • 1. 強實體
      • 2. 弱實體
        • 百度百科中的解釋
        • 《資料庫系統課程》中的解釋
        • 總結起來
    • 二、 關于定義的幾個疑惑
        • 什麼叫“依賴”?
        • 先有雞還是先有蛋?
        • 為什麼要定義弱實體?
        • 什麼時候需要定義弱實體?
        • 總結起來,以上四個問題其實是一個問題:
    • 三、 唯有實踐,方出真知
        • 教務系統資料庫設計(一)
        • 教育訓練公司資料庫設計
        • 教務系統資料庫設計(二)
    • 四、 對強實體與弱實體的總結

寫在最前

資料庫設計是困難的,其原因之一就在于我們很難去完全把握實體的定義。是不是實體、該不該定義實體是一直困擾資料庫初學者的問題,強實體、弱實體的概念同樣難以了解。

我一直深受強實體、弱實體概念的困擾,百度百科中的定義不能很好地解決我的困惑,一路學習過來,自己對強實體、弱實體的了解越來越深入,是以寫下這篇文章與大家分享自己對強實體與弱實體的一些體會。如果覺得有幫助,請點贊鼓勵!

一、 強實體與弱實體的定義

1. 強實體

其執行個體的存在不依賴于任何其他實體類型的執行個體;有自己獨立的主鍵,唯一性地辨別它的每個執行個體。

2. 弱實體

百度百科中的解釋

一個實體對于另一個實體(一般為強實體,也可以是依賴于其他強實體的弱實體)具有很強的依賴聯系,而且該實體主鍵的一部分或全部從其強實體(或者對應的弱實體依賴的強實體)中獲得,則稱該實體為弱實體。

《資料庫系統課程》中的解釋

其執行個體的存在依賴于其它實體類型的執行個體;其主鍵包括它所依賴的實體類型的主鍵。

總結起來

百度百科中的解釋和課程中的解釋都是在強調兩點:

第一點:依賴,弱實體應該依賴于強實體;

第二點:主鍵,弱實體的主鍵應該是組合主鍵(其他實體的主鍵組成的)。

二、 關于定義的幾個疑惑

但定義中有幾個地方令我不解,我相信初學者多少也會遇到同樣的問題。我總結了四點:

什麼叫“依賴”?

以教務系統資料庫為例,如果沒有學校,那麼學院不再是學院,學生不再是學生,課程更将不複存在,是以這些實體都依賴于其他實體,是以這些都是弱實體?但我們知道,學院、學生一般都作為強實體。是以,定義中的“依賴”指的是什麼呢?

先有雞還是先有蛋?

是因為一個實體的主鍵包括其他實體的主鍵而使該實體成為了弱實體,還是因為一個實體是弱實體,是以它的主鍵必須包括其他實體的主鍵?

這是一個先雞(弱實體)還是先蛋(組合主鍵)的問題。

為什麼要定義弱實體?

我們知道,弱實體對于另一個實體具有很強的依賴聯系,似乎并不是“真實”存在的事物,那麼為什麼我們還會有弱實體的概念,而不是直接認為實體就是強實體呢?

什麼時候需要定義弱實體?

有時候弱實體就是需求中的實體,隻是它依賴于其他實體,有時候關系也可以認為是弱實體,有時候出于設計的需要我們也會定義弱實體,那麼何時需要定義弱實體?

總結起來,以上四個問題其實是一個問題:

怎樣正确地了解強實體與弱實體的含義?

三、 唯有實踐,方出真知

有很多事情是很難想明白的,但經過幾次資料庫設計實戰,我發現自己或多或少地定義了一些弱實體。我選取了三個典型的例子:

教務系統資料庫設計(一)

之後我會專門寫一篇部落格介紹教務系統資料庫的設計過程,這裡選取其中一個比較典型的部分。業務需求是這樣的:

一周有七天,每一天有11節。

上面這句話中涉及到了幾個實體?很簡單吧,三個實體:周、天、節。那麼它們是強實體還是弱實體呢?不好說,但是我們可以确定,概念資料模型的設計應該是這個樣子:

徹底了解資料庫ER模型(CDM)中的強實體與弱實體:追根到底

需要勾選“Dependent”。首先回答一個問題:為什麼不能是下面這個樣子?

徹底了解資料庫ER模型(CDM)中的強實體與弱實體:追根到底

Day的主鍵應該是dayOfWeek,如果不用“Dependent”将Day的主鍵改為weekNum+dayOfWeek,我們的Day表格中隻能有七行記錄,也就是說對于某一個星期一,我們無法區分這是第幾周的星期一!同樣的道理,如果Section的主鍵僅僅為sectionNum,那麼我們根本無法區分這一節課是哪一天的課!教務系統要有排課、選課功能,隻知道第1節,但不知道是哪一天的第一節,這肯定是不可以的。

是以,當我們想要找到某一節時,需要同時指定那一周、星期幾、哪一節。比方說我可以把《資料庫設計》這門課安排在第一周星期一三四節。

在這個例子中,三個實體都是需求中明明白白告訴我們的實體,但我們将Day與Section都作為了弱實體,因為強實體的Day與Section根本無法滿足需求。

教育訓練公司資料庫設計

業務需求是這樣的:

每位學生每期隻能參加一門課程。

言外之意,公司有很多課程。我們隻分析“每位學生每期隻能參加一門課程”這一需求,發現涉及到兩個實體:學生、課程。是以我們或許會想當然地這樣去設計資料庫:

徹底了解資料庫ER模型(CDM)中的強實體與弱實體:追根到底

一個課程可以由多個學生選擇,一個學生隻可以選擇一門課程。發現問題了嗎?業務需求裡不是說一個學生隻能參加一門課程,而是說一個學生在一期隻能參加一門課程!這麼設計資料庫是在斷人家财路。是以,我們必須考慮“每期課程”這個概念:

徹底了解資料庫ER模型(CDM)中的強實體與弱實體:追根到底

看樣子似乎是沒問題了,但是資料庫設計是不可能這麼容易就沒問題的。我們把每期課程都作為一個記錄,那麼對于課程的資訊,比方說課程名稱、價格、介紹,每開一期課就要向資料庫中存一行記錄,是以我們的資料庫會出現大量備援(也就是說不滿足資料庫第二範式)。是以,我們應該這樣去設計資料庫:

徹底了解資料庫ER模型(CDM)中的強實體與弱實體:追根到底

看到了嗎?這裡的“Record”是一個弱實體,它的主鍵是“學期主鍵+學生主鍵”,代表學生參加課程這一行為,抽象成為了弱實體。為什麼要用學期表的主鍵和學生表的主鍵呢?因為一個學生、一個學期,那麼就隻能參加一門課程了,是以根據主鍵唯一辨別每行記錄的原則,應該這樣去選取。課程表的主鍵成為了Record表的外鍵,課程表與Record表之間存在一對多關系。

在這個例子中,學生、課程是業務需求描述中顯而易見的實體,“期”也可以認為是比較明顯的實體,但“參加”這個動詞在我們的資料庫中便成為了“參加記錄” ,也就是Record實體。

教務系統資料庫設計(二)

這一部分的業務需求是這樣的:

老師授課。

似乎業務需求很簡單,但事實上,多位老師可以獨立上同一門課,也可以共同上同一門課。一位老師可以參與多門課的授課。真實的教務系統的确是這個樣子的。一般,像馬原、高數等課程是多位老師獨立授課,專業核心課大多是多位老師共同為同一班級授課。那麼資料庫要怎樣設計呢?

徹底了解資料庫ER模型(CDM)中的強實體與弱實體:追根到底

像這樣嗎?老師、課程之間建立多對多關系?不難發現,這樣的多對多聯系無法區分上面所說的兩種授課情況。也就是說,我們必須引入第三個表,才有可能實作業務需求,兩張表格是行不通的。我是這樣設計的:

徹底了解資料庫ER模型(CDM)中的強實體與弱實體:追根到底

在課程表與老師表之間,引入了新的一張表格——排課表。一個課程可以安排多次排課,一個排課就對應一個獨立的授課安排,可以由一位老師完成,也可以由多位老師完成。那麼像馬原授課這種多位老師獨立授課的情況該如何解決呢?在排課表中,認為不同老師的馬原課是同一課程(引用Course表中同一記錄的主鍵作為外鍵),但是它們是不同的排課(ArangeNo不同,可能一個是1,另一個是2)。也正因如此,排課表的主鍵是組合主鍵(課程編号+排課編号,如CS163、1)。

這個例子中,需求中并沒有提“排課”這一實體,這個實體完全是我們為了滿足需求而定義的,甚至它和課程表在概念上還有點關系。注意到了嗎,這裡的“關系”就是弱實體概念中所說的“依賴”!

四、 對強實體與弱實體的總結

  1. 差別弱實體與強實體的關鍵在于主鍵,“依賴”的實質是主鍵之間的關系。是以歸根到底,就一個主鍵之間是否有關系、主鍵是否是組合主鍵的問題。
  2. 弱實體與強實體可以互相轉換,沒有絕對意義上的強與弱。既然差別弱實體與強實體的關鍵在于主鍵,那麼一個同樣意義的表,當我給它一個編号作為主鍵,那麼它就不是弱實體,而如果我令它的主鍵是組合主鍵,它就是弱實體。就像剛剛,我們說排課表的主鍵是組合主鍵(課程編号+排課編号,如CS163、1),是以它是弱實體,那麼如果我定義排課編号是“CS16301”,而不再是“1”,那麼它的主鍵(排課編号)就不再需要課程編号,它就成為了強實體。
  3. 弱實體也可以依賴于弱實體。就像第一個例子中的Session,它依賴于Day,Day就是一個弱實體。
  4. 弱實體與它所依賴的實體之間的關系隻能是1:1或n:1。也就是說,一個弱實體執行個體不可能依賴于同一實體的多個執行個體。這個其實很好了解,因為如果弱實體執行個體A依賴于執行個體B,那麼A的主鍵要包括B的主鍵,是以A當然不可以依賴于很多個B。
  5. 業務需求決定弱實體的定義,分三種情況:

    情況一、 業務需求中明确的弱實體

    情況二、 業務需求中隐含的弱實體

    情況三、 業務需求中無、但為實作業務需求不得不定義的弱實體

    如果覺得這篇文章對你有幫助,請給部落客點個贊!

繼續閱讀