資料模型:關聯式、文件、圖,你在選什麼
· tech
#distributed-systems#book-notes#data-modeling
📑 目錄
第一篇講了資料系統要追求什麼(可靠、可擴展、可維護)。這篇往下一層:你要用什麼「資料模型」來裝資料? 關聯式、文件、還是圖——這個選擇不是小事,它是你把現實映射成資料的底層抽象,決定了你怎麼建模、怎麼查、甚至怎麼想問題。
三種資料模型
真正的分水嶺:一對多 vs 多對多
要在關聯式和文件之間選,最實用的一把尺,是問資料的關係是「一對多」還是「多對多」。DDIA 用履歷(LinkedIn profile)當例子講得很傳神:
順帶一個相關的區分:文件模型多半是 schema-on-read(資料結構在讀取時才解釋,寫入很彈性),關聯式是 schema-on-write(寫入時就檢查結構,像靜態型別)。前者改結構方便、後者保證一致——這又是一個「彈性 vs 保證」的取捨,沒有絕對好壞,看你的資料多常變、多需要一致性。
為什麼關聯式當年會贏,文件又為何回來
這章還藏了一段很有意思的歷史。1970 年代,關聯式模型打敗了當時的網狀/階層模型,而關鍵不是效能,是宣告式:網狀模型要你在程式裡寫死「怎麼一步步走訪到資料」(存取路徑),換個查詢就得改一堆程式;關聯式讓你只說「要什麼」,把「怎麼走」交給 query optimizer。這聽起來是不是很熟?正是我在 SQL 系列反覆講的宣告式——把「怎麼做」交給比你更懂資料分佈的引擎。
而文件模型某種程度是階層模型的復活(巢狀、局部性好、讀一次拿整份),它回來是因為現代很多資料真的就是「一份自包含的文件」(貼文、訂單、事件)、加上 schema 彈性的吸引力。但注意:它復活的是「階層/巢狀」這個結構,不是推翻了關聯式的宣告式勝利——多對多這件事,關聯式和圖依然更強。
反思
選資料模型,是選「你想怎麼想問題」
我以前把「用什麼資料庫」當成技術選型的細節,後來才體會這是更根本的決定:它框定了你怎麼把現實映射成資料。 同一個業務,用表想、用文件想、用圖想,你的腦袋會走完全不同的路。所以我現在的順序是——先看資料的形狀:它是樹狀的(一對多,自然文件邊界)?網狀的(多對多,實體互相共享)?還是關係本身就是主角(社交、推薦、路網)?先認出形狀,再選模型,而不是反過來為了用某個潮的 DB 硬把資料塞進去。
一對多 vs 多對多,是我判斷「要不要用文件型 DB」的第一道題
這把尺太好用了。要不要上 MongoDB 這類文件庫,我第一個問的就是它:資料有沒有自然的文件邊界、關係是不是一對多(訂單+明細、貼文+留言、一個人+多筆經歷)→ 文件很爽,讀寫都在一份裡、局部性好。可是一旦出現多對多的共享實體(標籤、作者、公司、商品),文件模型就開始痛——不是把實體資料複製到每份文件(重複、難更新),就是存 id 然後在應用層自己 [sql-joins|join]。看到多對多,我就會很認真考慮關聯式。
關聯式的勝利,是「宣告式」的勝利——這件事沒被推翻
DDIA 這段歷史讓我更確定一個信念:資料工具幾十年的大方向,是不斷把「怎麼做」從人手上拿走、交給引擎。關聯式打敗網狀模型靠這個(你說要什麼、optimizer 決定怎麼取)、SQL 的 EXPLAIN 是這個、Spark 的 Catalyst 也是這個。文件模型帶回了巢狀與彈性,是很好的補充,但它沒有、也不該推翻那個宣告式的內核。所以我看任何新的資料模型或查詢語言,都會先問一句:它是讓我更專注在「意圖」,還是又把我拉回去管「步驟」? 前者才是站在歷史正確的一邊。