設計一個穩健的資料庫,不僅需要理解語法,更需要對資料在現實系統中如何互動,建立清晰的心智模型。實體關係圖(ERD)正是這種結構的藍圖。若沒有實際練習,正規化、基數和外鍵等理論概念將始終停留在抽象層面。要真正掌握資料庫建模,你必須投入實務問題,這些問題模擬真實的商業邏輯。
本指南專注於透過具體且真實的情境來應用ERD原則。透過這些範例的練習,你將增強辨識實體、定義關係,並避免常見結構錯誤的能力。目標是建立一套可靠的作業流程,將複雜的需求轉化為清晰且高效的資料模型。

理解核心元件 🧱
在進入情境之前,務必回顧ERD的構成要素。扎實的基礎能確保你在面對複雜需求時,無需重新學習基本概念。
1. 實體與屬性
- 實體: 這些代表系統內的獨立物件或概念。範例包括顧客, 產品,或員工.
- 屬性: 這些描述實體的特性。對於一個顧客,屬性可能包括顧客編號, 姓名,以及電子郵件地址.
- 主要鍵: 每個實體都需要一個唯一的識別碼,以區分不同記錄。
2. 關係與基數
實體之間的連結定義了資料的完整性。基數說明了一個實體與另一個實體相關的實例數量。
| 基數類型 | 描述 | 範例 |
|---|---|---|
| 一對一 (1:1) | 一個實例僅與另一實體的一個實例相關聯。 | 一個 員工擁有一個 身份證. |
| 一對多 (1:N) | 一個實例與另一實體的多個實例相關聯。 | 一個 部門擁有多個 員工. |
| 多對多 (M:N) | 多個實例與另一實體的多個實例相關聯。 | 多個 學生註冊多門 課程. |
情境 1:電子商務平台 🛒
線上零售系統涉及複雜的交易、庫存管理與使用者帳戶。此情境測試您處理聯結表格與狀態追蹤的能力。
需求分析
- 顧客可以在一段時間內下多個訂單。
- 單一訂單可包含多個產品。
- 一個產品可以出現在多個不同的訂單中。
- 每個訂單必須追蹤特定狀態(例如:待處理、已發貨)。
- 產品屬於特定類別。
建模步驟
- 識別實體: 客戶、訂單、產品、類別。
- 定義屬性:
- 客戶: 客戶編號、名字、姓氏、電子郵件。
- 訂單: 訂單編號、訂單日期、狀態、送貨地址。
- 產品: 產品編號、名稱、價格、庫存數量。
- 類別: 類別編號、類別名稱。
- 確定關係:
- 客戶至訂單: 一對多。一位客戶產生多筆訂單。
- 訂單至產品: 多對多。一筆訂單包含多項產品,而一項產品會出現在多筆訂單中。這需要建立一個關聯表。
- 產品至類別: 多對一。多項產品屬於同一個類別。
設計優化
針對訂單與產品之間的多對多關係,必須建立一個關聯表,通常稱為訂單明細。此表打破直接連結,並可儲存交易明細的特定資料,例如數量以及銷售時的單價.
- 訂單明細屬性: 訂單明細編號、訂單編號(外鍵)、產品編號(外鍵)、數量、單價。
- 正規化檢查: 確保 單價 儲存在這裡,而不是在 產品 表中,因為價格會隨時間變動。
情境 2:醫院管理系統 🏥
醫療資料庫由於資料的關鍵性,需要高度的準確性。此情境強調嚴格的資料完整性與層級關係。
需求分析
- 醫生專精於特定部門。
- 病人會前往醫生處就診。
- 一位醫生可以有多位病人,而一位病人也可以看多位醫生。
- 處方箋是在就診期間開立的。
- 每位病人皆有獨一無二的醫療紀錄。
建模步驟
- 識別實體: 醫生、病人、就診、處方箋、部門。
- 定義屬性:
- 醫生: 醫生編號、姓名、專長、執照編號。
- 部門: 部門編號、部門名稱、部門主管醫生編號。
- 就診: 就診編號、日期時間、診斷備註。
- 處方箋: 處方編號、藥物名稱、劑量、持續時間。
- 確定關係:
- 部門至醫生: 一對多。一個部門聘請多位醫生。
- 醫生至就診: 一對多。一位醫生進行多場就診。
- 患者到預約: 一對多。一名患者會參加多個預約。
- 預約到處方: 一對多。一次預約可能產生多張處方。
處理複雜約束
在此情境中,資料完整性至關重要。您必須確保處方無法在沒有關聯預約的情況下存在。這透過外鍵約束來強制執行。
- 自我引用關係: 一 醫生實體可能需要連結到同一張表格中的 主任醫師。這是一對一的關係,其中 主任醫師編號 參考 醫生編號.
- 時間資料: 預約具有特定日期。請確保 DateTime 欄位以標準格式儲存,以便進行排程查詢。
情境 3:大學學生門戶 🎓
學術系統涉及大量的多對多關係與條件邏輯。此情境專注於管理註冊與先修課程。
需求分析
- 學生註冊多門課程。
- 每門課程有多位授課教師。
- 一門課程可以在多個學期中開設。
- 部分課程有先修課程。
- 成績依學生與課程分別授予。
建模步驟
- 識別實體: 學生、課程、授課教師、學期、註冊。
- 定義屬性:
- 學生: 學生編號、GPA、主修科目。
- 課程: 課程代碼、標題、學分。
- 講師: 講師編號、姓名、職稱。
- 註冊: 註冊編號、成績、學期年份。
- 確定關係:
- 學生至課程: 多對多。透過「註冊」關聯表格進行管理。
- 課程至講師: 多對多。一門課程在不同時間可由多位講師授課。
- 課程至先修課程: 自引用。一門課程列舉另一門課程為先修課程。
處理先修課程邏輯
先修課程的要求在「課程」實體中產生遞迴關係。您需要在「課程」資料表中新增一欄,例如先修課程編號,其參考同一資料表中另一筆資料的課程編號。
- 實作: 這允許「數學 101 課程連結至 數學 100 課程。
- 驗證: 系統必須防止課程成為自身的先修課程,以避免循環邏輯錯誤。
ERD 設計中的常見陷阱 ⚠️
即使是經驗豐富的設計師也會犯錯。檢視常見錯誤有助於你在實作前優化你的模型。
1. 重複資料
在多個地方儲存相同資訊會增加不一致的風險。例如,在 訂單 表中儲存客戶地址對於配送目的而言是可以接受的,但 客戶 表應保持為其永久地址的唯一真實來源。
- 檢查: 詢問:若更改一個表格中的屬性,是否需要在其他表格中進行更新?
- 修正: 在可能的情況下,將資料規範化至第三範式(3NF)。
2. 模糊的關係
有時難以判斷關係是強制性的還是可選的。在 客戶 至 訂單 的關係中,客戶在下訂單前就已存在。然而,訂單必須始終屬於某位客戶。
| 概念 | 含義 |
|---|---|
| 可選關係 | 此側的實體不需要與另一實體建立連結。 |
| 強制關係 | 此側的實體必須與另一實體建立連結。 |
3. 忽略資料類型
選擇錯誤的資料類型可能會導致儲存效率低下或計算錯誤。例如,若在沒有小數位的價格欄位中使用整數類型,將會導致貨幣精確度喪失。
- 最佳實務: 使用十進位類型處理貨幣,並使用日期/時間類型進行排程。
- 限制條件: 為文字欄位定義最大長度,以防止資料庫膨脹。
逐步建模工作流程 📝
遵循此結構化方法,以確保所有練習問題的一致性。
- 收集需求: 列出問題描述中出現的每一個名詞(實體)和動詞(關係)。
- 草擬初始圖示: 放置實體並繪製線條以表示連結。目前無需擔心完美。
- 指派鍵值: 為每個實體識別主鍵,並為每個關係識別外鍵。
- 細化基數: 根據業務規則驗證 1:1、1:N 和 M:N 的關係。
- 新增屬性: 使用必要的欄位來完整描述每個實體。移除任何由其他欄位推導出的欄位。
- 檢視是否符合規範化: 確保不存在傳遞依賴(例如,如果 A 決定 B,且 B 決定 C,則 A 不應決定 C 直接)。
- 最終驗證: 透過資料輸入的場景來走過一遍,以確認模型是否支援。
自我評估清單 ✅
在最終確定您的ERD之前,請走過此清單以確保品質。
- 唯一性: 每個資料表都有主鍵嗎?
- 一致性: 相關資料表之間的資料類型是否一致?
- 完整性: 是否可以在不違反約束條件的情況下插入所有必要資料?
- 清晰度: 資料實體與屬性名稱是否具描述性且標準化?
- 可擴展性: 如果資料量增加十倍,此設計是否仍能維持穩定?
- 約束條件: 在資料為必要時,是否正確應用允許空值的約束?
進階考量 🚀
隨著信心的增加,您可以探索更多進階的模型設計技術。
1. 弱實體
弱實體的存在依賴於另一個實體。例如,訂單明細若無訂單,則無法存在。其主鍵通常是其自身部分鍵與擁有者主鍵的組合。
2. 繼承
有時實體會共用共同的屬性。在一個員工系統中,全職 和 兼職 員工共用一個ID和姓名,但福利不同。你可以使用超類別和子類別結構來建模。
3. 時間表
有些資料會隨時間變動。一個 產品價格 每週變動。你可能需要儲存價格變動的歷史紀錄,而不僅僅是目前的值。這需要為你的屬性加入有效的起始和結束日期。
實務練習的最後考量 💡
建立ERD設計的信心是一個漸進的過程。這需要不斷地優化與批判性思考資料在系統中流動的方式。透過實際案例,例如電商、醫療和教育,你將接觸到各種結構上的挑戰。
請記住,幾乎很少有一個「完美」的模型。不同的應用可能重視不同的面向,例如讀取速度與寫入速度之間的權衡。關鍵在於理解設計選擇中所涉及的取捨。
持續以新的需求進行練習。嘗試建模圖書館系統、飯店預訂系統或社群媒體網路。每個領域都有獨特的限制與關係模式。練習得越多,這個過程就越自然。
重點總結
- 實體是基礎: 在連結之前,明確定義它們。
- 基數很重要: 確保關係類型符合業務規則。
- 正規化可降低風險: 避免重複以維持資料完整性。
- 定期檢視: 始終根據新需求驗證你的設計。
只要專注並有系統地練習,你將培養出設計可靠且可擴展資料庫系統所需的技能。專注於連結背後的邏輯,技術實現將自然跟上。









