服務分開了,資料庫帳號卻還是共用,每個服務都能修改所有 Schema。看到這樣的安排,我會先想:如果資料被改錯了,到底由誰負責確認?
在新舊系統並存的過程中,可能會先遇到這種情況。服務有各自的名字,資料卻仍可以互相改動。只要寫入的來源不清楚,負責服務就很難保證自己管理的資料正確,後續也不好追查。
所以,我會先把資料責任整理成一張表,再討論資料庫要怎麼分:
| 資料域 | Owner | 其他服務如何取得 | 禁止方式 |
|---|---|---|---|
| 訂單 | Order Service | API/事件 | 直接 UPDATE 訂單表 |
| 物料 | Material Service/ERP | 查詢 API/同步事件 | 自寫 SQL 直接抄 ERP 物料表 |
| 庫存 | Inventory Service/ERP | 即時查詢或快照 | 自行計算並當作正式庫存 |

圖 Day 08-1:服務與資料所有權。
我對資料所有權的理解,是先知道誰能決定寫入規則。即使暫時使用同一台資料庫主機,也可以先分開 Schema 權限,讓寫入經過負責服務。主機怎麼規劃,之後再依需求評估。
直接 UPDATE 訂單表,眼前可能很方便,但會跳過負責服務的規則。所以表裡我也會保留「禁止方式」這一欄,先把這些容易走的捷徑寫下來,Review 時才有共同的檢查依據。
移轉期間,物料或庫存仍可能要以 ERP 為準。這部分更要寫仔細:正式來源是哪裡、多久同步、可以晚多久,以及對不起來時誰處理。即使表上同時列出服務與 ERP,也要把各自的責任說清楚。
實作至少應包含帳號分離、最小權限、Schema migration 版本控管、資料分類與稽核。目前平台已做到每個服務各有一個資料庫與帳號,訂單、EDI、EIP 與 RAG 服務的 Schema 也已用 Flyway 做版本控管;最小權限、資料分類與稽核則還要再補。對外提供穩定的 API 契約,內部資料表調整則由負責服務管理。
帳號分離的部分,是在資料庫容器第一次啟動時由初始化腳本建立,每個服務一個資料庫、一組帳號:
-- 容器首次啟動時由 superuser 執行
-- order-service
\connect postgres
CREATE DATABASE schema_ord;
CREATE USER ord WITH PASSWORD '<password>';
GRANT CONNECT ON DATABASE schema_ord TO ord; -- 只開這一個資料庫的連線權
\connect schema_ord
GRANT ALL ON SCHEMA public TO ord; -- 資料表權限限定在自己的資料庫內
-- inventory-service
\connect postgres
CREATE DATABASE schema_inv;
CREATE USER inv WITH PASSWORD '<password>';
GRANT CONNECT ON DATABASE schema_inv TO inv;
\connect schema_inv
GRANT ALL ON SCHEMA public TO inv;
第一步,我會先確認每個服務都有自己的資料庫帳號,權限也只開在負責的資料庫。實際用帳號測一次,確認跨域寫入會被拒絕,就能知道這條界線有沒有生效。
像刪欄位、改型別這類變更,未必能直接反向執行。所以資料結構要改之前,我會先想好怎麼恢復,並分階段規劃。Migration 的執行與回復方式,都要能照著紀錄驗證;目前只有往前的 migration 腳本,回復腳本還沒有準備。
我會希望分析工作有適合的資料來源,也讓交易庫保留足夠資源處理日常作業。所以報表如果需要大量查詢,可以再評估唯讀投影或資料倉儲。
| 取捨 | 這樣選的理由 | 何時要重新評估 |
|---|---|---|
| 先做資料庫與帳號分離,暫不拆資料庫主機 | 所有權可以先成立,不必立刻承擔多個 instance 的維運 | 效能或可用性需求要求獨立實例時 |
| 移轉期間以 ERP 為部分資料域的正式來源 | 避免同一份資料出現兩個正式來源 | ERP 該資料域的規則已完整搬移時 |
| 跨域取得資料一律經 API 或事件 | 保留各域調整內部結構的空間 | 即時性需求無法由現行方式滿足時 |
| 分析查詢另建唯讀投影 | 避免分析負載影響交易 | 投影延遲已無法滿足報表需求時 |
資料隔離會增加查詢與一致性處理成本,共享過多則會限制獨立修改能力。這個取捨沒有通用答案,但要記錄當時的選擇與理由,後續才能判斷是否該調整。
| 指標 | 計算方式 | 想回答的問題 |
|---|---|---|
| DB 權限掃描違規數 | 帳號可存取但不屬於該服務的 Schema 數 | 最小權限是否落實? |
| 跨 Schema 寫入次數 | 違反責任表的寫入紀錄數 | 禁止方式是否真的生效? |
| migration 回復測試通過率 | 可成功回復的 migration/全部 migration | 結構變更是否有退路? |
| 對帳差異率 | 對帳不一致筆數/對帳總筆數 | 與 ERP 的資料是否維持一致? |
這四項可以逐步建立自動檢查。先從資料庫權限開始,確認設定和責任表一致,再把其餘量測接上,日後比較容易持續追蹤。
整理到這裡,資料誰負責、從哪裡取得,以及誰可以修改,都有了比較清楚的答案。下一篇,再把視線移到服務外面,看看 Gateway 怎麼整理共同入口。