跳轉到

1976 - 陳氏實體關係模型(ER 圖:資料庫設計的統一語言)#

案件摘要#

1976 年,MIT 的陳品山(Peter Chen,1947–) 在 ACM Transactions on Database Systems 發表 The Entity-Relationship Model—Toward a Unified View of Data:

\[ \boxed{\text{實體、屬性、關係——連接「現實世界」與「資料模型」的橋樑}} \]

在 ER 模型之前,資料庫設計者面對的是一堆表格與綱要—— 「為什麼這樣分表?」「現實世界怎麼映射進來?」沒有統一語言; Chen 提出三個基本概念: - 實體(entity):現實中可區別的「東西」(學生、課程、客戶); - 屬性(attribute):實體的性質(姓名、學分、地址); - 關係(relationship):實體之間的關聯(選課、下單、隸屬)。

\[ \text{實體} \xrightarrow{\text{屬性描述}} \text{關係連接} \xrightarrow{\text{ER 圖}} \text{關聯式綱要}. \]

ER 圖成為資料庫設計的「世界語」—— 半世紀以來,每一堂資料庫課、每一份設計文件都畫著它。

前因 -- 為什麼會有這個案子#

  • 三種資料模型的三國鼎立(1970s 初):
\[ \text{階層式(IMS)} \quad \text{網狀式(CODASYL)} \quad \text{關聯式(Codd)} \]

三種模型各有自己的描述語言—— 設計方法互不相通、文件無法交換——

\[ \boxed{\text{缺乏一個「統一觀點」:讓三種模型互相翻譯}} \]

Chen 的論文副標題 Toward a Unified View of Data 正是這個野心。 - Codd 關聯式模型的「設計缺口」: Codd 的模型(見 1970-科德關聯式資料庫.md)告訴你 資料長什麼樣(表)與怎麼查(關聯代數)—— 但沒有告訴你怎麼從現實世界設計出這些表:

\[ \text{現實世界} \xrightarrow{\ ???\ }\ \text{表格綱要}. \]

這個「\ ???\ 」正是 ER 模型要填補的洞。 - Bachmann 網路模型的啟發(1969): Charles Bachmann 的網狀模型(見 ../資訊科學/1969-巴赫曼網路模型.md ——若存在)用圖(nodes and links)描述資料—— Chen 受其啟發,但把「關係」從「集合的推廣」提升為一級概念:

\[ \text{集合(數學)} \supset \text{關係(n 元聯繫)} \xrightarrow{\text{Chen(1976)}} \text{一級概念}. \]

(Bachmann 於 1973 年獲圖靈獎——網狀模型的功臣。) - 「語義」的覺醒: 1970s 中,學界開始問:資料的「意義」(semantics)去哪了? 表格裡的每一格只有值,沒有意義—— ER 模型是語義資料模型(semantic data model)的開山之作——

\[ \text{語法(表、欄位)} \xrightarrow{\text{ER(1976)}} \text{語義(實體、關係)}. \]

線索與推理 -- 數學式、程式、理論#

第一條線索:ER 模型的形式定義#

ER 模型 = \((E, \text{Attr}, R)\) : - \(E\) :實體集(entity sets),如「學生」「課程」; - \(\text{Attr}\) :屬性函數 \(\text{Attr}: E \to \text{值的集合}\) , 如 學生.學號 \(\in \{1, 2, \dots\}\) ; - \(R \subseteq E_1 \times E_2 \times \cdots \times E_n\) : \(n\) 元關係集。 ER 圖的畫法(Chen 的記號): - 矩形 ▭:實體;橢圓 ⬭:屬性;菱形 ◇:關係。

\[ \text{學生} \xrightarrow{\text{矩形}} \;[\text{選課}]\xrightarrow{\text{菱形}} \;[\text{課程}] \]

第二條線索:基數(cardinality)——一對一、一對多、多對多#

關係的基數決定資料的結構:

\[ \text{1:1} \quad \text{1:N} \quad \text{M:N} \]
  • 一對一(1:1):每人一張身分證—— \(R \subseteq E_1 \times E_2\) 且每個實體至多出現一次;
  • 一對多(1:N):一部門多員工—— \(\forall r_1, r_2 \in R:\ r_1[E_1] = r_2[E_1] \Rightarrow r_1 = r_2\) ( \(E_1\) 側唯一);
  • 多對多(M:N):多學生選多課程—— 無唯一性限制——
\[ \boxed{\text{M:N 是關聯式表格的剋星:必須拆出「橋接表」}} \]

第三條線索:ER → 關聯式綱要的轉換規則#

Chen 的轉換法則(設計方法論的核心): 1. 實體集 → 表:每個實體集變成一張表,屬性變成欄位;

\[ E(\text{key}, a_1, a_2, \dots) \to \text{表 } E(\text{key}, a_1, a_2, \dots) \]
  1. 1:N 關係 → 外鍵:在「N 側」的表加外鍵(foreign key);
\[ \text{員工}.\text{dept\_id} \to \text{部門}.\text{id} \]
  1. M:N 關係 → 橋接表:關係集本身變成一張表, 主鍵 = 兩側主鍵的組合:
\[ R(E_1.\text{key}, E_2.\text{key}, \text{關係屬性}) \to \text{表 } R \]
\[ \text{選課}(\text{學號}, \text{課號}, \text{成績}) \leftarrow \text{M:N 的解法} \]
  • 這三條規則機械化了資料庫設計—— 從 ER 圖到 SQL 綱要,不再需要靈感,只需要規則:
\[ \text{ER 圖(語義)} \xrightarrow{\text{轉換規則}} \text{綱要(SQL)} \xrightarrow{\text{SQL}} \text{查詢(1974)}. \]

Python:用類別實作小型 ER 模型(學生-課程-選課 M:N)#

import sqlite3

# 1) ER 模型的類別表示(實體、屬性、關係)
class Entity:
    def __init__(self, name, key, attrs):
        self.name, self.key, self.attrs = name, key, attrs

class Relationship:
    def __init__(self, name, e1, e2, cardinality, attrs=()):
        self.name, self.e1, self.e2 = name, e1, e2
        self.card, self.attrs = cardinality, attrs

student = Entity("學生", "學號", ["姓名", "系所"])
course  = Entity("課程", "課號", ["課名", "學分"])
enroll  = Relationship("選課", student, course, "M:N", ["成績"])

print("ER 模型(學生-課程-選課):")
print(f"  實體:{student.name}(鍵:{student.key},屬性:{student.attrs})")
print(f"  實體:{course.name}(鍵:{course.key},屬性:{course.attrs})")
print(f"  關係:{enroll.name}({enroll.card},屬性:{enroll.attrs})")

# 2) ER → 關聯式綱要(Chen 的轉換規則 1 與 3)
conn = sqlite3.connect(":memory:")
cur = conn.cursor()
cur.execute(f"CREATE TABLE {student.name} ({student.key} INTEGER PRIMARY KEY, "
            f"姓名 TEXT, 系所 TEXT)")
cur.execute(f"CREATE TABLE {course.name} ({course.key} TEXT PRIMARY KEY, "
            f"課名 TEXT, 學分 INTEGER)")
cur.execute(f"CREATE TABLE {enroll.name} ("           # M:N → 橋接表
            f"學號 INTEGER, 課號 TEXT, 成績 INTEGER, "
            f"PRIMARY KEY (學號, 課號), "               # 組合主鍵
            f"FOREIGN KEY (學號) REFERENCES 學生(學號), "
            f"FOREIGN KEY (課號) REFERENCES 課程(課號))")

# 3) INSERT:把「現實世界」的資料映射進關聯式表格
students = [(1, "王大明", "資工系"), (2, "林小美", "數學系"), (3, "陳阿土", "資工系")]
courses  = [("CS101", "計算機概論", 3), ("MA201", "線性代數", 3), ("CS340", "資料庫", 3)]
enrolls  = [(1, "CS101", 88), (1, "CS340", 92), (2, "MA201", 95),
            (2, "CS101", 78), (3, "CS101", 85), (3, "CS340", 90)]
cur.executemany("INSERT INTO 學生 VALUES (?,?,?)", students)
cur.executemany("INSERT INTO 課程 VALUES (?,?,?)", courses)
cur.executemany("INSERT INTO 選課 VALUES (?,?,?)", enrolls)
conn.commit()

# 4) 查詢:M:N 關係的威力——一次看到三個實體的交集
print("\nM:N 查詢:誰選了什麼課、成績如何?(三表 JOIN)")
for name, cname, grade in cur.execute(
        """SELECT 學生.姓名, 課程.課名, 選課.成績
           FROM 選課
           JOIN 學生 ON 選課.學號 = 學生.學號
           JOIN 課程 ON 選課.課號 = 課程.課號
           ORDER BY 學生.姓名, 課程.課名"""):
    print(f"  {name} × {cname}:{grade} 分")

print("\n各課程平均成績(M:N 的分組聚合):")
for cname, avg in cur.execute(
        """SELECT 課程.課名, AVG(選課.成績)
           FROM 選課 JOIN 課程 ON 選課.課號 = 課程.課號
           GROUP BY 課程.課名 ORDER BY 課程.課名"""):
    print(f"  {cname}:平均 {avg:.1f} 分")
conn.close()
輸出:
ER 模型(學生-課程-選課):
  實體:學生(鍵:學號,屬性:['姓名', '系所'])
  實體:課程(鍵:課號,屬性:['課名', '學分'])
  關係:選課(M:N,屬性:['成績'])

M:N 查詢:誰選了什麼課、成績如何?(三表 JOIN)
  林小美 × 線性代數:95 分
  林小美 × 計算機概論:78 分
  王大明 × 計算機概論:88 分
  王大明 × 資料庫:92 分
  陳阿土 × 計算機概論:85 分
  陳阿土 × 資料庫:90 分

各課程平均成績(M:N 的分組聚合):
  線性代數:平均 95.0 分
  計算機概論:平均 83.7 分
  資料庫:平均 91.0 分

結案 -- 後果與影響#

  • 資料庫設計方法論的誕生(1976):
\[ \boxed{\text{ER 圖把「設計」從藝術變成工程:規則化、可教、可畫}} \]

此後每一本資料庫教科書都以 ER 模型為設計篇的核心—— ER 圖成為資料庫課程的必修圖。 - 業界標準(1980s–): - CASE 工具(Computer-Aided Software Engineering):ERwin、PowerDesigner—— 自動把 ER 圖轉成 SQL 綱要; - UML 的類別圖(1990s):承襲 ER 模型的語義思想;

\[ \text{ER(1976)} \xrightarrow{\text{思想延伸}} \text{UML(1990s)} \xrightarrow{} \text{現代建模工具}. \]
  • 正規化理論的姐妹線: Codd 的正規化(1971,1NF/2NF/3NF)告訴你表格該長什麼樣; ER 模型告訴你表格從哪裡來——
\[ \text{正規化(1971):怎麼分表} \quad \parallel \quad \text{ER(1976):為什麼分表}. \]

兩條線索在 1980s 合流——正規化成為檢驗 ER 設計的標準—— 這是資料庫理論的姐妹雙璧。 - 語義資料模型的譜系: ER 模型之後,語義模型蓬勃發展: - 擴充 ER(EER,1980s):加入繼承(is-a)、子類; - 物件導向模型(1990s):實體 → 物件; - 本體論(ontology)與知識圖譜(2000s–):實體與關係的 AI 版——

\[ \text{ER(1976)} \xrightarrow{\text{語義}} \text{知識圖譜(2012 Google)} \xrightarrow{} \text{LLM 時代的 RAG}. \]
  • Chen 的榮耀: Peter Chen 獲 ACM Fellow、多項終身成就獎—— ER 模型是資訊科學史上被引用最多的論文之一(引用數以萬計);
\[ \text{一頁論文(1976)} \xrightarrow{\text{半世紀}} \text{每一堂課、每一份設計文件}. \]
  • 統一觀點的實現:
\[ \text{現實世界} \xrightarrow{\text{ER 模型}} \text{概念模型} \xrightarrow{\text{轉換規則}} \text{邏輯模型} \xrightarrow{\text{DBMS}} \text{物理模型} \]

這個三層設計流程(概念→邏輯→物理)至今仍是所有資料庫設計的標準流程—— 而 SQL(1974) 與 Ingres(1974) 的戰場 (見 1974-錢柏林SQL.md、1974-斯東布雷克Ingres.md), 正是這個流程的邏輯與物理層。 - 歷史定位:陳品山是「資料建模之父」—— 他把 Codd 的數學(1970)與 Bachmann 的圖(1969)統合,

\[ \text{數學 + 圖(1970s)} \xrightarrow{\text{Chen(1976)}} \text{設計的統一語言}. \]

關鍵人物與文獻#

  • P. P.-S. Chen(陳品山):The Entity-Relationship Model—Toward a Unified View of Data(ACM TODS, 1976)。
  • E. F. Codd:關聯式模型(1970)與正規化(1971)——ER 的轉換目標(見 1970-科德關聯式資料庫.md)。
  • C. W. Bachmann:網狀模型(1969)與圖形記法——1973 圖靈獎——ER 的啟發者。
  • J. Martin:Computer Data-Base Organization(1975)等——ER 方法論的普及者。
  • 相關案件:1936-圖靈機.md、1970-科德關聯式資料庫.md、1974-錢柏林SQL.md、1974-斯東布雷克Ingres.md、1986-波斯特Postgres.md。