深入理解數據庫ER模型(CDM)中的強實體與弱實體:追根到底

寫在最前

數據庫設計是困難的,其原因之一就在於我們很難去完全把握實體的定義。是不是實體、該不該定義實體是一直困擾數據庫初學者的問題,強實體、弱實體的概念同樣難以理解。
我一直深受強實體、弱實體概念的困擾,百度百科中的定義不能很好地解決我的困惑,一路學習過來,自己對強實體、弱實體的理解越來越深入,因此寫下這篇文章與大家分享自己對強實體與弱實體的一些體會。如果覺得有幫助,請點贊鼓勵!

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

1. 強實體

其實例的存在不依賴於任何其他實體類型的實例;有自己獨立的主鍵,唯一性地標識它的每個實例。

2. 弱實體

百度百科中的解釋

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

《數據庫系統課程》中的解釋

其實例的存在依賴於其它實體類型的實例;其主鍵包括它所依賴的實體類型的主鍵。

總結起來

百度百科中的解釋和課程中的解釋都是在強調兩點:
第一點:依賴,弱實體應該依賴於強實體;
第二點:主鍵,弱實體的主鍵應該是組合主鍵(其他實體的主鍵組成的)。

二、 關於定義的幾個疑惑

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

什麼叫“依賴”?

以教務系統數據庫爲例,如果沒有學校,那麼學院不再是學院,學生不再是學生,課程更將不復存在,所以這些實體都依賴於其他實體,因此這些都是弱實體?但我們知道,學院、學生一般都作爲強實體。因此,定義中的“依賴”指的是什麼呢?

先有雞還是先有蛋?

是因爲一個實體的主鍵包括其他實體的主鍵而使該實體成爲了弱實體,還是因爲一個實體是弱實體,所以它的主鍵必須包括其他實體的主鍵?
這是一個先雞(弱實體)還是先蛋(組合主鍵)的問題。

爲什麼要定義弱實體?

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

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

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

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

怎樣正確地理解強實體與弱實體的含義?

三、 唯有實踐,方出真知

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

教務系統數據庫設計(一)

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

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

上面這句話中涉及到了幾個實體?很簡單吧,三個實體:周、天、節。那麼它們是強實體還是弱實體呢?不好說,但是我們可以確定,概念數據模型的設計應該是這個樣子:
在這裏插入圖片描述
需要勾選“Dependent”。首先回答一個問題:爲什麼不能是下面這個樣子?
在這裏插入圖片描述
Day的主鍵應該是dayOfWeek,如果不用“Dependent”將Day的主鍵改爲weekNum+dayOfWeek,我們的Day表格中只能有七行記錄,也就是說對於某一個星期一,我們無法區分這是第幾周的星期一!同樣的道理,如果Section的主鍵僅僅爲sectionNum,那麼我們根本無法區分這一節課是哪一天的課!教務系統要有排課、選課功能,只知道第1節,但不知道是哪一天的第一節,這肯定是不可以的。

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

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

培訓公司數據庫設計

業務需求是這樣的:

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

言外之意,公司有很多課程。我們只分析“每位學生每期只能參加一門課程”這一需求,發現涉及到兩個實體:學生、課程。所以我們或許會想當然地這樣去設計數據庫:
在這裏插入圖片描述
一個課程可以由多個學生選擇,一個學生只可以選擇一門課程。發現問題了嗎?業務需求裏不是說一個學生只能參加一門課程,而是說一個學生在一期只能參加一門課程!這麼設計數據庫是在斷人家財路。因此,我們必須考慮“每期課程”這個概念:在這裏插入圖片描述
看樣子似乎是沒問題了,但是數據庫設計是不可能這麼容易就沒問題的。我們把每期課程都作爲一個記錄,那麼對於課程的信息,比方說課程名稱、價格、介紹,每開一期課就要向數據庫中存一行記錄,因此我們的數據庫會出現大量冗餘(也就是說不滿足數據庫第二範式)。因此,我們應該這樣去設計數據庫:
在這裏插入圖片描述
看到了嗎?這裏的“Record”是一個弱實體,它的主鍵是“學期主鍵+學生主鍵”,代表學生參加課程這一行爲,抽象成爲了弱實體。爲什麼要用學期表的主鍵和學生表的主鍵呢?因爲一個學生、一個學期,那麼就只能參加一門課程了,所以根據主鍵唯一標識每行記錄的原則,應該這樣去選取。課程表的主鍵成爲了Record表的外鍵,課程表與Record表之間存在一對多關係。

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

教務系統數據庫設計(二)

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

老師授課。

似乎業務需求很簡單,但事實上,多位老師可以獨立上同一門課,也可以共同上同一門課。一位老師可以參與多門課的授課。真實的教務系統的確是這個樣子的。一般,像馬原、高數等課程是多位老師獨立授課,專業核心課大多是多位老師共同爲同一班級授課。那麼數據庫要怎樣設計呢?
在這裏插入圖片描述
像這樣嗎?老師、課程之間建立多對多關係?不難發現,這樣的多對多聯繫無法區分上面所說的兩種授課情況。也就是說,我們必須引入第三個表,纔有可能實現業務需求,兩張表格是行不通的。我是這樣設計的:
在這裏插入圖片描述
在課程表與老師表之間,引入了新的一張表格——排課表。一個課程可以安排多次排課,一個排課就對應一個獨立的授課安排,可以由一位老師完成,也可以由多位老師完成。那麼像馬原授課這種多位老師獨立授課的情況該如何解決呢?在排課表中,認爲不同老師的馬原課是同一課程(引用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. 業務需求決定弱實體的定義,分三種情況:

    情況一、 業務需求中明確的弱實體
    情況二、 業務需求中隱含的弱實體
    情況三、 業務需求中無、但爲實現業務需求不得不定義的弱實體

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章