1974 - Ingres(大學版關聯式資料庫與查詢最佳化)#
案件摘要#
1974–75 年,UC Berkeley 的 Michael Stonebraker(1943–) 帶領學生開始開發 Ingres(INteractive Graphics REtrieval System):
同一時間,IBM 的 System R(見 1974-錢柏林SQL.md)在大公司的資源下開發; Ingres 走的是完全不同的路線: - 大學原型:學生、廉價硬體、開放原始碼; - QUEL 語言:不用 SELECT--FROM--WHERE,而用元組關聯演算(tuple calculus); - 查詢最佳化:選擇下推(selection pushdown)——先過濾再連接。
Ingres 證明:關聯式不是 IBM 的專利—— 這是開放原始碼資料庫血統的起點,也是 Stonebraker 日後 2014 年圖靈獎的立功之地。
前因 -- 為什麼會有這個案子#
- Codd 的關聯式模型(1970): Codd 在 IBM 發表關聯式模型(見
1970-科德關聯式資料庫.md):
理論上任何一行代數式都可算出—— 但沒有人證明它在真實硬體上跑得動—— 學界質疑:「漂亮的數學會不會慢得不能用?」 - IBM 內外的冷熱對比: IBM 內部對 Codd 的理論興趣缺缺(IMS 網狀資料庫既得利益); 但 Berkeley 的 Stonebraker 讀了 Codd 的論文後意識到:
他向 NSF(美國國家科學基金會)申請經費——大學版資料庫專案啟動。 - System R 的競爭對照: IBM 在 1974 年啟動 System R(見 1974-錢柏林SQL.md)—— 同一問題、兩種路線:
兩邊互相看論文、搶時間、較勁效能—— 這場競賽加速了整個資料庫產業的誕生。 - QUEL 的理論基礎: Stonebraker 採用 Codd 的元組關聯演算(tuple relational calculus):
Codd 已證明代數與演算等價—— QUEL 選了演算這條路,SQL 選了代數這條路——殊途同歸。
線索與推理 -- 數學式、程式、理論#
第一條線索:QUEL 的元組演算#
一個 QUEL 查詢(列出薪水高於 50000 的員工):
range of e is emp
retrieve (e.name) where e.salary > 50000
range of e is emp:宣告變數 \(e\) 的範圍(存在量詞的顯式化);retrieve ... where:集合建構式 \(\{t \mid \varphi(t)\}\) ;
第二條線索:代數等價變換——查詢最佳化的雛形#
同一個查詢有多種代數寫法,結果相同但成本天差地遠:
選擇下推( \(\sigma \downarrow\) ):把選擇盡量往樹的下方推——
為什麼更快? - 假設 \(|A| = m\) 、 \(|B| = n\) 、選擇條件留下比例 \(f\) : - 先連接再選擇:中間結果 \(m \times n\) 行; - 先選擇再連接:中結果 \(f \cdot m \times f \cdot n\) 行——
第三條線索:Ingres 的「分解式最佳化」#
Ingres 的創新:查詢分解(query decomposition)—— 把巢狀查詢拆成多個簡單的單變數查詢,逐一處理:
- 這是動態規劃式最佳化的先聲;
- System R 後來發展出成本基礎最佳化(cost-based optimizer)—— 兩條路線共同奠定了現代查詢最佳化器的基礎:
Python:查詢最佳化——先選擇再連接 vs 先連接再選擇#
# Toy 資料:員工表 emp 與部門表 dept
emp = [(i, f"員工{i}", (i % 5) * 20000 + 30000, i % 10)
for i in range(1, 1001)] # 1000 筆員工,薪水 30000~110000
dept = [(d, f"部門{d}") for d in range(10)] # 10 個部門
def salary_key(r):
"""薪水欄位的位置:原始 emp 行在 [2],JOIN 後的行在 [0][2]"""
return r[2] if isinstance(r[0], int) else r[0][2]
def select_salary_over_90k(rows):
"""σ:選擇薪水 > 90000 的行(留下約 1/5)"""
return [r for r in rows if salary_key(r) > 90000]
def join(emp_rows, dept_rows):
"""⋈:emp ⋈ dept(笛卡兒積再過濾,比對 dept_id)"""
dmap = dict(dept_rows) # 鍵→值映射(JOIN 的本質)
return [(e, dmap[e[3]]) for e in emp_rows]
# 方法 A:先連接再選擇(壞計畫:1000 × 10 的中間結果)
middle_A = join(emp, dept) # 中間結果:1000 行(積之後過濾)
result_A = select_salary_over_90k(middle_A)
# 方法 B:先選擇再連接(好計畫:σ↓ 選擇下推,中間結果只剩 200 行)
small_emp = select_salary_over_90k(emp) # 中間結果:約 200 行
result_B = join(small_emp, dept)
# 成本對比
f = len(small_emp) / len(emp)
print("查詢最佳化:σ↓(選擇下推)的威力")
print(f" 員工表 {len(emp)} 行 × 部門表 {len(dept)} 行")
print(f" 選擇條件 salary > 90000 留下比例 f = {f:.2f}")
print(f" 方法 A(先⋈再σ):中間結果 {len(middle_A)} 行")
print(f" 方法 B(先σ↓再⋈):中間結果 {len(small_emp)} 行")
print(f" 理論值 f²·mn = {f**2 * len(emp) * len(dept):.0f},f·mn ≈ {f * len(emp):.0f}")
print(f" 省下 {len(middle_A) - len(small_emp)} 行中間處理({(1-f)*100:.0f}% 減量)")
print(f" 兩種方法結果相同嗎?{sorted(result_A) == sorted(result_B)}({len(result_A)} 筆)")
print(" → 代數等價變換:結果不變,成本大減——Ingres 的核心洞察 ✓")
查詢最佳化:σ↓(選擇下推)的威力
員工表 1000 行 × 部門表 10 行
選擇條件 salary > 90000 留下比例 f = 0.20
方法 A(先⋈再σ):中間結果 1000 行
方法 B(先σ↓再⋈):中間結果 200 行
理論值 f²·mn = 400,f·mn ≈ 200
省下 800 行中間處理(80% 減量)
兩種方法結果相同嗎?True(200 筆)
→ 代數等價變換:結果不變,成本大減——Ingres 的核心洞察 ✓
結案 -- 後果與影響#
- 開放原始碼的先驅(1970s): Ingres 以象徵性費用授權給任何申請者—— 約有上千個單位拿到原始碼——
這是 UNIX 之外,大學軟體散佈模式的又一成功案例 (見 ../資訊科學/1973-UNIX作業系統.md)。 - 商業血統:Sybase 與 SQL Server: - Sybase(1984):由 Ingres 團隊成員創立——承襲 Ingres 的技術血統; - MS SQL Server(1989):微軟與 Sybase 合作——SQL Server 的祖先是 Ingres!
- QUEL vs SQL 之爭:
- QUEL:更理論化(元組演算)、有型別檢查、無「SQL 方言混亂」;
- SQL:更商業化(IBM 背書)、語法簡單、生態系統龐大;
技術上更好的語言不見得贏——這是軟體史的重要教訓。 - Postgres(1986): Stonebraker 在 Ingres 之後啟動 Postgres (POST-Ingres,加入物件概念,見 1986-波斯特Postgres.md,稍後建立)—— 它後來變成 PostgreSQL——至今最強的開源關聯式資料庫。 - Stonebraker 2014 圖靈獎(伏筆):
從 Ingres(1974)到圖靈獎(2014)——四十年的學術長跑; 他也是 C-Store(Vertica)、H-Store(VoltDB) 等多家公司的創辦人。 - 理論與產業的雙贏:
兩條路線共同證明:關聯式模型是可行、高效、可商用的—— 這個驗證讓整個資料庫產業在 1980 年代全面轉向關聯式。 - 歷史定位:Ingres 是「學術原型改變產業」的典範—— 一群學生在廉價硬體上寫出的系統,
關鍵人物與文獻#
- M. Stonebraker:Ingres(1974–75,與 E. Wong、G. Held 等合作);Postgres(1986);2014 圖靈獎。
- E. Wong、G. Held、P. Kreps:Ingres 核心開發者;The Design and Implementation of INGRES(1976)。
- E. F. Codd:關聯式模型(1970)與元組關聯演算——Ingres 的理論基礎。
- D. Chamberlin & R. Boyce:SEQUEL(1974)——System R 的競爭對照。
- 相關案件:
1936-圖靈機.md、1970-科德關聯式資料庫.md、1974-錢柏林SQL.md、1979-甲骨文ORACLE.md、1986-波斯特Postgres.md。