資料編碼與演進 (Encoding & Evolution)

★★★★★Draft

FromDDIA

📚 From the Books

資料編碼與演進 (Encoding & Evolution)ConceptCommunication

系統會滾動升級,所以新舊版程式碼、新舊格式資料一定會同時並存。編碼格式選得好不好,決定你能不能一邊部署一邊不出事——關鍵是雙向相容

🧠 Core Ideas

TIP

兩個方向都要顧:向後相容=新程式碼讀得懂舊資料;向前相容=舊程式碼讀得懂(並忽略)新資料。向前相容比較難,因為要讓舊碼安全跳過它不認識的東西。

⚖️ Tradeoffs

三類格式,一條相容性光譜
  • 語言內建(Java Serializable、pickle):綁單一語言、有安全風險、相容性差 → 只適合極短暫用途,別拿來持久化或跨服務。
  • 文字格式(JSON / XML / CSV):人類可讀、跨語言、最適合組織間交換;但數字有模糊性(JSON 不分整數/浮點,>2⁵³ 會掉精度)、二進位要 Base64(+33%)、schema 支援參差。
  • 二進位 schema 格式(Thrift / Protocol Buffers / Avro)組織內部首選——更小、更快、相容語義明確、schema 兼作文件與程式碼生成。
Protobuf / Thrift — 靠「欄位標籤」做演進
  • schema 給每個欄位一個數字標籤;編碼只放標籤不放欄位名 → 小很多。
  • 演進規則(背下來):
    • 可以改欄位名(編碼裡只有標籤);不能改標籤(一改舊資料全失效)。
    • 新增欄位用新標籤,且必須 optional 或有預設值(否則破壞向後相容)。
    • 移除只能移 optional 欄位,且標籤永不重用
Avro — 沒有標籤,靠 writer/reader schema 對齊
  • 編碼只有值、連欄位名/標籤都沒有 → 最緊湊(範例 32 bytes vs Protobuf 33、JSON 81)。
  • 核心:寫入者 schema 與讀取者 schema 不必相同、只要相容,函式庫用欄位名自動對齊差異(多的忽略、缺的補預設)。
  • 可選欄位用 union(如 union{null,long})+ 預設值,強迫你明講哪些能為 null。
  • 沒有標籤 → 特別適合從資料庫 schema 動態生成,改 schema 不用手動維護標籤對應。
三種資料流的相容性責任
  • 經資料庫:寫入者編碼、讀取者解碼;小心舊碼讀到新欄位、寫回時把它弄丟(要保留未知欄位)。
  • 經服務(REST/RPC):一般伺服器先升 → 請求要向後相容、回應要向前相容;跨組織時得長期維護多個 API 版本
  • 經非同步訊息:透過 broker 傳位元組,只要編碼支援雙向相容,publisher / consumer 就能各自獨立升級。

🔑 Takeaways

✍️ My Notes

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

📖 Further Reading