業務を「1つの入れ子ドキュメント」で表す — LCデータモデルと簡易形式
受注も定期も、関連する項目を一つのドキュメントにまとめて整合を取る。そして、読むときは扱いやすい形に開く。
MODELなぜ1件を1ドキュメントにまとめるのか
通販基幹の業務エンティティ — 受注、定期、見積 — は、ヘッダ・明細・金額・配送・状態といった多くの関連項目からなります。これらを複数テーブルに分割すると、1件の全体像を組み立てるたびに結合が必要になり、更新時の整合も分散します。そこで私たちは、業務エンティティを「LC」と呼ぶ1つの入れ子ドキュメントで表現する方針を採りました。関連する項目が同じ器に収まっていれば、1件を読めば全体が揃い、書き込みも1トランザクションの中で整合を取れます。
- 器の単位は業務の1件(1受注、1定期)。整合の境界と一致させる。
- 状態遷移や金額計算のように「まとめて正しくあるべき」情報を、1ドキュメントに閉じ込める。
STRUCTUREセクション・項目・状態の入れ子
LCの中身はセクションの配列で構成します。たとえば受注ヘッダを表す s_ord_bs[] のようなセクションがあり、その中に短い物理名を持つ項目オブジェクト(i_*)と、さらに深い子セクション(s.s_*)が入れ子になります。重要なのは、各ノードが自分の識別子 sid と状態 stat を持つことです。これにより、ドキュメント全体だけでなく、明細1行やサブブロック単位でも「今どの状態か」を表現できます。
SCHEMAスキーマは定義として外出しする
ドキュメント本体には値だけを持たせ、構造の意味は定義として外に置きます。どのセクションにどの項目が来るかを表す構造定義と、各項目の型・制約を表す項目定義です。項目名は保存効率と安定性のために短い物理名にしていますが、それだけでは人にもAIにも読めません。そこで物理名と論理名を対応づける辞書を定義側に持ち、可読性を補います。定義駆動にすることで、項目の追加は「定義を足す」だけで済み、本体の器はそのまま使えます。
ACCESS読むときは平坦化、書くときは入れ子のまま
保存に適した形と、処理に適した形は違います。取得時には入れ子のLCを平坦化した簡易形式に変換し、業務ロジックやAIが直接扱いやすいフラットなキー・値の集合にします。逆に書き込み時は入れ子のまま扱い、1ドキュメントの中で整合を取ります。読み取りビューと保存モデルを分けることで、両者の都合を独立に最適化できます。
TRADEOFF利点と、割り切るところ
この設計の利点は明確です。1ドキュメントで関連項目の整合を取りやすく、定義駆動なので項目追加が容易で、1件を読めば全体像が揃います。一方でトレードオフもあります。短縮物理名は生では読みにくく、辞書での補完が前提になります。1件に情報を集めるほどドキュメントは肥大し、頻繁に読む項目だけを扱いたい場面では平坦化のコストが乗ります。さらに、入れ子の一部だけを更新する部分更新は、境界とロック単位を意識した設計が要ります。器を大きくする判断は、整合の取りやすさと引き換えであることを忘れないことが肝心です。
- 可読性 ↔ 保存効率:物理名の短さは辞書で補う。
- 全体像の揃いやすさ ↔ ドキュメント肥大:境界を業務の1件に合わせる。
{
// LC = 1件の業務ドキュメント(受注)
"sid": "ord-0001",
"stat": "active",
"s_ord_bs": [
{
"sid": "bs-0",
"stat": "fixed",
"i_ord_no": "...", // 論理名: 受注番号(辞書で対応)
"i_amt": 0, // 論理名: 合計金額
"s": {
"s_ord_dt": [ // 子セクション: 受注明細
{
"sid": "dt-0",
"stat": "open",
"i_itm": "...", // 論理名: 商品
"i_qty": 1 // 論理名: 数量
}
]
}
}
]
}業務の1件を「セクション配列に項目と子セクションを入れ子にした1ドキュメント=LC」で表すと、整合の境界がはっきりし、定義駆動で項目追加も容易になる。保存は入れ子のまま、取得時は簡易形式に平坦化して見せ分ける。代償は物理名の可読性・肥大・部分更新の設計であり、器のサイズは整合性との取引だと意識して選ぶ。