1961 - IBM 層次資料庫(IMS:為登月計畫而生的樹狀資料庫)#
案件摘要#
1961 年,IBM 的工程師團隊(Vernon Watts、Oscar Gilbert 等人, 與 North American Aviation 的 Rockwell 合作)接下一樁「不能失敗」的案子: 阿波羅登月計畫的物料清單(BOM)管理系統。 一支太空船有數百萬個零件,每個零件又由子零件組成—— 樹狀結構應聲而出:
這就是 IMS(Information Management System)—— 第一個大規模商用的層次資料庫(1966 年隨阿波羅計畫上線,1968 年正式發售)。 資料獨立的萌芽也在此埋下:程式透過「層次路徑」取資料, 而不再直接讀寫磁帶上的原始位元組。
前因 -- 為什麼會有這個案子#
- 計算的理論基礎(1936): 一切要從 圖靈機 說起(見
../資訊科學/1936-圖靈機.md)——
資料庫正是這個思想的大型工程實現:資料可以被結構化地儲存與查詢。 - 1960 年代磁帶與檔案處理的混亂: 當時的「資料管理」是這樣辦案的: - 資料存在磁帶上(順序存取,找一筆記錄要從頭倒帶); - 每個程式自帶檔案格式——同一份物料資料,會計程式與工程程式 各自維護一份副本; - 資料重複、更新不同步:改了一處忘了另一處,數字對不上。
- 阿波羅計畫的物料危機(1961): North American Aviation 負責建造指揮艙與服務艙—— 幾百萬個零件、層層組裝:太空船 → 艙段 → 組件 → 零件 → 原料。 這個結構天然是一棵樹:每個零件只有一個直屬上級組件。
IBM 接案時最初名為 ACS,後來演變為 IMS—— 硬體基礎則是 IBM System/360(1964)與磁碟機(隨機存取,不用再倒帶)。 - 分時系統的平行線(1961): 同一年,MIT 的 CTSS(見 ../資訊科學/1961-科巴托分時系統.md)證明了 一台機器可以服務多個使用者——
IMS 把同樣的邏輯搬到資料上:一份資料,多個程式共用。
線索與推理 -- 數學式、程式、理論#
第一條線索:樹狀結構的數學定義#
層次模型 = 一棵有序樹 \(T = (V, E)\) : - \(V\) :記錄型態(record type)的集合——每個節點是一種記錄; - \(E \subseteq V \times V\) :父子邊——每個節點至多一個父親; - 唯一的根 \(r \in V\) :沒有父親的節點(如「太空船」)。
層次路徑(hierarchical path):從根到某節點的唯一通路——
第二條線索:父子指標遍歷#
IMS 的基本操作就是沿指標走(如同圖靈機的讀寫頭沿紙帶移動): - GET FIRST / GET NEXT:在父親的兒子序列中移動; - GET NEXT IN PARENT:跳到下一個同型態的記錄。
BOM 展開 = 樹的深度優先遍歷:
其中 \(c_1, \ldots, c_k\) 是 \(v\) 的兒子, \(\Vert\) 是序列串接。 需要的零件總數:
第三條線索:資料獨立的萌芽#
IMS 的進步:程式不再讀磁帶的原始位元組,而是用「層次路徑」描述資料:
但只走了一半:路徑本身綁死在樹狀結構上—— - 樹狀結構一改,所有程式的路徑全部要改(邏輯相依); - 同一筆資料要服務兩個父親?樹說不行。
Python:小型層次資料庫與 BOM 遞迴展開#
# IMS 層次資料庫:樹狀結構 + 父/子指標 + 物料清單(BOM)遞迴展開
class Record:
"""一筆 IMS 記錄:資料欄位 + 指向子記錄的指標(樹狀)"""
def __init__(self, name, **fields):
self.name = name
self.fields = fields
self.children = [] # 子記錄指標(父子鏈結)
def add(self, *children):
for c in children:
self.children.append(c) # 建立父子指標
return self
def explode(rec, path=""):
"""BOM 查詢:把零件遞迴展開成完整的層次路徑"""
full = f"{path}/{rec.name}" if path else rec.name
results = [(full, rec.fields.get("qty", 1))]
for c in rec.children:
results.extend(explode(c, full))
return results
def count_leaves(rec):
"""樹的葉節點數 = 最終的基礎零件數"""
if not rec.children:
return 1
return sum(count_leaves(c) for c in rec.children)
# ---- 建立阿波羅計畫的物料清單(BOM 樹)----
bom = Record("太空船") \
.add(
Record("指令艙").add(
Record("隔熱板", qty=1).add(
Record("酚醛樹脂", qty=40),
Record("蜂巢鋁板", qty=8),
),
Record("降落傘", qty=3).add(
Record("尼龍布", qty=12),
Record("鋼索", qty=6),
),
),
Record("登月艙").add(
Record("下降引擎", qty=1).add(
Record("噴嘴", qty=1),
Record("燃料泵", qty=2),
),
Record("起落架", qty=4).add(
Record("緩衝柱", qty=4),
),
),
)
# ---- 查詢 1:層次路徑遍歷( IMS 的 GET NEXT 呼叫)----
print("查詢 1:BOM 樹的層次遍歷(父 → 子)")
def walk(rec, depth=0):
qty = rec.fields.get("qty")
print(" " * depth + rec.name + (f"(數量={qty})" if qty else ""))
for c in rec.children:
walk(c, depth + 1)
walk(bom)
# ---- 查詢 2:BOM 遞迴展開 ----
print("\n查詢 2:BOM 遞迴展開(零件的完整層次路徑)")
for path, qty in explode(bom):
print(f" {path}(數量={qty})")
# ---- 查詢 3:統計 ----
print(f"\n查詢 3:基礎零件(葉節點)總數 = {count_leaves(bom)}")
# ---- 查詢 4:層次模型的僵化——若新資料需求破壞樹狀假設 ----
print("\n層次模型的僵化(伏筆):")
print(" 同一個「尼龍布」同時供給「降落傘」與「太空服」?")
print(" 樹中每個子記錄只能有一個父親 → 必須複製整條子樹,")
print(" 資料重複、更新異常 → 這正是網路模型(1969)要解的案。")
查詢 1:BOM 樹的層次遍歷(父 → 子)
太空船
指令艙
隔熱板(數量=1)
酚醛樹脂(數量=40)
蜂巢鋁板(數量=8)
降落傘(數量=3)
尼龍布(數量=12)
鋼索(數量=6)
登月艙
下降引擎(數量=1)
噴嘴(數量=1)
燃料泵(數量=2)
起落架(數量=4)
緩衝柱(數量=4)
查詢 2:BOM 遞迴展開(零件的完整層次路徑)
太空船(數量=1)
太空船/指令艙(數量=1)
太空船/指令艙/隔熱板(數量=1)
太空船/指令艙/隔熱板/酚醛樹脂(數量=40)
太空船/指令艙/隔熱板/蜂巢鋁板(數量=8)
太空船/指令艙/降落傘(數量=3)
太空船/指令艙/降落傘/尼龍布(數量=12)
太空船/指令艙/降落傘/鋼索(數量=6)
太空船/登月艙(數量=1)
太空船/登月艙/下降引擎(數量=1)
太空船/登月艙/下降引擎/噴嘴(數量=1)
太空船/登月艙/下降引擎/燃料泵(數量=2)
太空船/登月艙/起落架(數量=4)
太空船/登月艙/起落架/緩衝柱(數量=4)
查詢 3:基礎零件(葉節點)總數 = 7
層次模型的僵化(伏筆):
同一個「尼龍布」同時供給「降落傘」與「太空服」?
樹中每個子記錄只能有一個父親 → 必須複製整條子樹,
資料重複、更新異常 → 這正是網路模型(1969)要解的案。
結案 -- 後果與影響#
- 第一個商用資料庫(1966/1968):
IMS 隨阿波羅計畫上線,1968 年以 IMS/360 之名正式發售—— 這是資料庫產業的起點。 - 至今仍在運行(60 年): IMS 至今仍在銀行、航空、保險業的核心系統中運行—— ATM 提款、機票訂位,背後可能還是那棵 1961 年的樹。
- 層次模型的僵化:
這些僵化為關聯式革命埋下伏筆(見 1969-巴赫曼網路模型.md、 1970-科德關聯式模型.md)。 - 樹的另一個遺產: 樹狀結構沒有消失,而是轉世——XML(1998)、JSON(2001)、檔案系統、DOM——
- 歷史定位:IMS 是資料庫史的第一章—— 它證明了「一份資料、多個程式共用」可行, 但也留下了「結構綁死」的懸案,等著 Bachman 與 Codd 來偵辦。
關鍵人物與文獻#
- Vernon Watts、Oscar Gilbert(IBM):IMS 的主要設計者(1961 起)。
- North American Aviation / Rockwell:阿波羅計畫承包商——IMS 的第一個客戶。
- IBM:System/360(1964)與 IMS/360(1968)——資料庫產業的起點。
- Fernando Corbató:CTSS 分時系統(1961)——一台機器服務多人(見
../資訊科學/1961-科巴托分時系統.md)。 - 相關案件:
../資訊科學/1936-圖靈機.md、1969-巴赫曼網路模型.md、1970-科德關聯式模型.md。