Columnar 不是 NoSQL,是換了儲存佈局的關聯式資料庫
教材常把 Columnar 跟 Key-Value/Document/Graph 並列在「NoSQL」底下。但它們分的根本不是同一個軸。
| Key-Value | Document | Graph | Columnar | |
|---|---|---|---|---|
| 差在哪 | 資料模型 | 資料模型 | 資料模型 | 實體儲存佈局 |
前三種回答「資料長什麼樣」;Columnar 回答「同一份關聯式資料,在磁碟上怎麼擺」。
row-oriented :一筆記錄的所有欄位存在一起
column-oriented :同一個欄位的所有值存在一起
兩者的資料模型可以一模一樣——同樣的表、同樣的欄位、同樣的 SQL,只是擺法不同。BigQuery、Redshift、Snowflake、ClickHouse 全是 columnar,全都講 SQL、全都有 schema。PostgreSQL 甚至有 columnar 擴充(Citus columnar),同一個關聯式資料庫可以兩種佈局並存。
Columnar ≠ NoSQL,它是「為 OLAP 最佳化的關聯式資料庫」。
三個正交的軸
| 軸 | 選項 |
|---|---|
| 資料模型 | 關聯式 / 文件 / 圖 / KV |
| 儲存佈局 | row-oriented / column-oriented |
| 工作負載 | OLTP / OLAP |
Columnar 動的是第二軸,而它常跟 OLAP 綁在一起,是因為第二、三軸高度相關。
為什麼聚合查詢差那麼多
以 SELECT AVG(temp) FROM readings(5 億列)為例,看磁碟實際讀了什麼:
為了拿到 temp 要讀什麼 | 浪費 | |
|---|---|---|
| row-oriented | 每一列的全部欄位都讀進來,才挑出那 8 bytes | 一列 200 bytes → 浪費 96% |
| column-oriented | 只讀 temp 那一欄,同型別連續存放、壓縮率極高 | 幾乎沒有 |
反過來,SELECT * FROM orders WHERE id = 123 要一整筆記錄——row 佈局一次 I/O 拿完,column 佈局反而要去每一欄各撈一次。
| 負載 | 查詢形狀 | 佈局 |
|---|---|---|
| OLTP | 拿一整筆、改一整筆 | row |
| OLAP | 一兩個欄位 × 全部的列 | column |
這正是 同一個寫法在互動式列表沒事,在全量掃描必爆 說的「負載形狀決定慣例的適用範圍」,在儲存層的版本。