Document DB 快在局部性:把該一起用的東西實際存在一起
MongoDB 比 PostgreSQL 快,不是因為查詢演算法比較聰明——它有 secondary index、有 aggregation pipeline,這些 SQL 也都有。真正的機制是:東西擺在一起。
同一筆資料,兩種擺法
關聯式正規化之後,一筆感測器讀數是散的:
readings 表 → temp, timestamp, device_id
devices 表 → device_id, model, site_id
sites 表 → site_id, 廠區名稱, 城市
要湊出完整資訊 → 三張表、三次查找、兩次 JOIN。
Document 的同一筆:
{ "temp": 28.3, "timestamp": "...",
"device": { "id": "d-01", "model": "X200",
"site": { "name": "廠區A", "city": "台中" } } }一份文件、一個連續的區塊、一次讀取、零 JOIN。 這叫局部性(locality)。
寫入快也是同一個原因:一次連續寫完,沒有外鍵檢查、沒有跨表協調。
代價你已經知道
「廠區A」這個名字在 500 萬筆文件裡重複了 500 萬次,改名要改 500 萬份。
這就是 拆表把成本集中在一次 join,不拆表把成本攤到每一列 的同一條帳——Document DB 是「不拆表」那一端的極致。
所以它不是一種新的東西,是把反正規化做到底、並且讓資料庫原生支援巢狀結構。一致性的風險也跟著繼承,見 改漏一列的代價不是工多,是資料安靜地不一致。
兩個常見誤解
- 它不是 Key-Value。 可以按欄位查、可以建索引、可以聚合,Key-Value 的限制是為了換分片而付的價 講的那些「不准」對它不成立。
- 水平擴展是另一個機制,跟局部性無關。而且分片之後,沒打中 shard key 的查詢反而更慢——見 key-range sharding 用順序換熱點,hash 用均勻換範圍查詢。