選了資料模型,也就選了配套的查詢語言。關聯模型帶來的真正革命不只是「表」,而是 SQL 這種宣告式查詢——你只描述「要什麼」,把「怎麼拿」整包交給資料庫。這一步讓查詢與底層實作徹底解耦,也讓平行化變得可能。
🧠 Intuition
TIP
命令式是「逐步告訴電腦怎麼走」(手寫一個迴圈逐筆過濾);宣告式是「只描述想要的資料長什麼樣」(條件、排序、聚合),把演算法留給查詢優化器。同一組 CSS 選好樣式、瀏覽器自己決定怎麼畫——SQL 對資料庫就是這個角色。
- 命令式 (imperative):指定操作與執行順序(早期 IMS / CODASYL 就是這樣寫)。
- 宣告式 (declarative):只給「結果的模式」——條件 (condition)、排序 (sorting)、聚合 (aggregation),交給查詢優化器 (query optimizer) 決定如何實現。
- 這不是資料庫獨有的優勢:瀏覽器裡用 CSS(宣告式)遠優於用 JavaScript 直接操作 DOM(命令式)——CSS 更簡潔,且瀏覽器能在不破壞相容性下改進效能。
⚖️ Tradeoffs
宣告式的三個好處
- 更簡潔:通常比等價的命令式程式碼短、也更好寫。
- 隱藏實作細節:底層儲存結構與查詢優化器可以自由演化,查詢本身不必改就能受益於效能改進。
- 易於平行化:因為只指定「結果模式」而非「執行演算法」,資料庫可自由選用平行實作;命令式因規定了執行順序,反而難平行化。
MapReduce:卡在宣告與命令之間
- MapReduce 是 Google 推廣的大規模處理模型,MongoDB / CouchDB 支援其有限形式;查詢邏輯寫成程式碼片段、由框架反覆呼叫——介於宣告與命令之間。
- 硬限制:map 與 reduce 必須是純函數 (pure function)、不能有副作用——正因如此,資料庫才能在任何地方、任何順序執行它們(這也是可平行、可重試的前提)。
- 代價:要寫兩個彼此協調的函數,比一句 SQL 難用、優化空間也小。於是 MongoDB 2.2 加入宣告式的 aggregation pipeline(本質是「JSON 語法版的 SQL 子集」)——NoSQL 兜了一圈,又把 SQL 的宣告式優勢重新發明了一遍。
Cypher:Neo4j 的宣告式圖查詢
- Cypher 為 Neo4j 而生,用箭頭表示法比對圖中的路徑樣式(pattern matching)。例:
(person) -[:BORN_IN]-> ()匹配一條BORN_IN的邊。 - 關鍵語法
:WITHIN*0..表示沿WITHIN邊遍歷零次或多次,如同正規表達式的*——這正是圖查詢處理「任意深度層級關係」的利器。 - 「找出所有從美國移居歐洲的人」在 Cypher 只需 4 行;同一查詢用 SQL
WITH RECURSIVE(遞迴 CTE)要 29 行——這道對比就是「不同資料模型配不同查詢語言」的最佳註腳。
SPARQL 與 Datalog:三元組世界的查詢
- SPARQL:建立在 RDF 資料模型上的查詢語言。RDF 把一切存成三元組 (subject, predicate, object)(如
(Jim, likes, bananas)),可用 Turtle 格式書寫。同一個移民查詢,SPARQL 比 Cypher 還簡潔,:within*一樣表達「零次或多次」的遍歷。 - Datalog(1980 年代,比前兩者更老,卻是許多語言的基礎;用於 Datomic、Cascalog):資料寫成
predicate(subject, object),查詢靠定義規則 (rule)——規則能參照其他規則、也能遞迴呼叫自己。一條within_recursive遞迴規則就能推導出所有「包含在某地點內」的位置。 - Datalog 需要換一種思維,一次性查詢不方便,但規則能跨查詢組合與重用,面對複雜資料時更強。
🔑 Takeaways
- 宣告式(SQL)vs 命令式是關聯模型帶來的關鍵分水嶺:只描述「要什麼」,讓查詢與底層實作解耦,並打開平行化空間。
- MapReduce 卡在中間——用純函數換來可平行/可重試,但難用到讓 MongoDB 又補上宣告式的 aggregation pipeline。
- 圖查詢語言各有擅場:Cypher(箭頭樣式)、SPARQL(RDF 三元組)、Datalog(可組合、遞迴規則);共同賣點都是用一行
*表達「任意深度」的關係遍歷。 - Cypher 4 行 vs SQL 遞迴 CTE 29 行——選對資料模型與查詢語言,是架構設計最關鍵的決策之一。
No notes yet — jot your takeaways or Q&A here.