資料庫是細節 (The Database Is a Detail)#
在軟體開發中,我們常聽到這句話:「我們先把資料庫 schema 設計出來。」 Uncle Bob 在這一章大聲疾呼:這是錯的。
從架構的角度來看,資料庫並不是「實體(Entity)」,它只是一個**「細節(Detail)」**。 它只是一個負責將資料從記憶體搬到磁碟(或反之)的機制。架構師不應該讓這種低層級的機制,去主導高層級的系統設計。
一、關聯式資料庫的興起背景#
為什麼關聯式資料庫(RDBMS)會變得如此重要,甚至被誤認為是架構的核心? 原因只有一個:磁碟(Disk)太慢了。
- 物理限制: 傳統硬碟需要移動讀寫頭,這需要幾毫秒的時間。對 CPU 來說,這簡直是幾百萬年的等待。
- 解決方案: 為了掩蓋磁碟的龜速,我們發明了索引、B-Tree、快取、查詢優化器(Query Optimizer)和 SQL。
- 本質: 這些複雜的機制,都是為了克服硬體限制而存在的細節,與業務邏輯毫無關係。
二、如果記憶體無限大?#
試想一個情境:如果你的電腦擁有無限大的 RAM,且永遠不會斷電,你會怎麼儲存資料?
- 你會用 SQL 寫
INSERT嗎?不會。 - 你會把資料拆成表格(Table)再用 Foreign Key 連起來嗎?不會。
- 你會怎麼做: 你會直接用資料結構(Linked List, Hash Map, Tree, Stack)。你會直接
users.add(newUser)。
這揭示了一個真相:資料庫的表格結構,並不是資料最自然的結構。 強迫業務物件(Objects)去配合資料庫表格(Tables),就是所謂的「物件關聯阻抗不匹配(Object-Relational Impedance Mismatch)」。
三、架構觀點:資料庫只是儲存桶#
在整潔架構中,資料庫的地位非常低:
- 它只是工具: 資料庫就像是檔案系統(File System)一樣,只是一個存取資料的工具。
- 它是外部的: 應用程式的核心(實體、使用案例)不應該知道資料庫的存在。
- 依賴方向: 資料庫應該依賴應用程式,而不是應用程式依賴資料庫。
四、效能是細節#
有人會反駁:「但是為了效能,我們必須精心設計 SQL 和 Table!」 Uncle Bob 承認效能很重要,但效能也是一種細節。
- 隔離: 如果我們用良好的架構將資料存取層(Data Access Layer)隔離。
- 替換: 我們可以先用簡單的檔案系統實作。當效能不足時,再換成 MySQL,再不足時換成 Redis,或者將部分熱點資料放入 RAM。
- 關鍵: 只要架構正確,更換這些儲存機制不會影響到任何一行業務邏輯程式碼。
總結: 不要讓資料庫這個「工具」喧賓奪主,變成了你的「架構」。 資料模型(Data Model)$\neq$ 資料庫模型(Database Model)。 你的業務物件應該長得像業務邏輯需要的樣子,而不是長得像資料庫表格的樣子。