查詢語言:宣告式 vs 命令式 (Query Languages)

★★★★Draft

FromDDIA

📚 From the Books

查詢語言:宣告式 vs 命令式 (Query Languages)Data Models

選了資料模型,也就選了配套的查詢語言。關聯模型帶來的真正革命不只是「表」,而是 SQL 這種宣告式查詢——你只描述「要什麼」,把「怎麼拿」整包交給資料庫。這一步讓查詢與底層實作徹底解耦,也讓平行化變得可能。

🧠 Intuition

TIP

命令式是「逐步告訴電腦怎麼走」(手寫一個迴圈逐筆過濾);宣告式是「只描述想要的資料長什麼樣」(條件、排序、聚合),把演算法留給查詢優化器。同一組 CSS 選好樣式、瀏覽器自己決定怎麼畫——SQL 對資料庫就是這個角色。

⚖️ 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

✍️ My Notes

No notes yet — jot your takeaways or Q&A here.

📖 Further Reading