/note/tech

だいたい同じだけど一部が異なるデータを持つデータ構造について4つのパターン分類してみた

要約:

■ 1. 問題の背景

  • アプリケーション開発においてだいたい同じだが一部が異なるデータを管理する必要がある場合がある
  • 具体例:
    • サイト全体の設定を元にプロジェクトごとに一部だけ変更した設定ファイル
    • 共通の契約書テンプレートデータを元に顧客ごとに特約を書き加えた契約書
  • これらは元となるテンプレートデータとそれを活用しつつ改変されたインスタンスデータの関係にある

■ 2. 分析の2つの軸

  • 連動性:
    • テンプレートデータの変更をインスタンスデータにどこまで自動で追従させるかという軸
    • 3つの段階がある:
      • テンプレートの変更がすべてのインスタンスに即座に反映される場合
      • まったく反映されない場合
      • 一部だけ反映される場合
  • データ効率:
    • テンプレートと同じ内容のデータの重複をどれだけ避けているかという軸
    • 効率が高い設計では同じデータを複数箇所に保存せず参照によって共有
    • 効率が低い設計ではデータを複製するため重複が多くなる

■ 3. パターン1:マスター型

  • 概要:
    • インスタンスデータはマスターデータを直接参照して活用
    • インスタンス側での改変は許容しない
    • 変更はすべてマスターデータの修正や追加で実現
  • 事例:
    • 料金管理における標準料金プランマスタと地域別料金プランマスタ
    • 地域別プランは基本的に標準プランを参照して使用
    • 地域固有のプランが必要な場合は子マスタに新規追加
    • 標準プランの価格改定などはすべての地域プランに自動反映
  • 特徴:
    • 連動性:マスターを更新すれば即座にすべてのインスタンスに反映される
    • インスタンス側で変更したい場合もマスターデータに変更を加える必要がある
    • データ効率:高い
    • データは一箇所に集約され重複がない
  • 使いどころ:
    • インスタンスのデータがマスターデータと連動して変更されてよい場合
    • インスタンスでの変更が少ない場合
  • 不適切な場合:
    • 計画と実行のようにインスタンスのデータを保存する必要がある場合
    • インスタンス側でマスターデータと異なるデータを多数作る場合

■ 4. パターン2:テンプレート型

  • 概要:
    • インスタンスデータは明示的に管理されたテンプレートデータを完全に複製して作成
    • 作成後はテンプレートデータとの関連性は一切なくなる
    • 完全に独立したデータとして管理と改変が行われる
  • 事例:
    • 顧客ごとの契約書
    • 共通の契約書テンプレートデータをコピーし顧客ごとに個別の契約書で契約を結ぶ
    • テンプレートを変えても過去や現在結んだ契約に影響がない
    • 顧客ごとに契約内容を調整しても問題ない
  • 特徴:
    • 連動性:コピー後はテンプレートデータとインスタンス側のデータの間に関係はない
    • テンプレートデータが更新されても既存のインスタンスには一切影響しない
    • インスタンス側はテンプレートの変更を気にせず自由に改変できる
    • データ効率:低い
    • コピーが増えるほど同じ内容のデータが重複する
  • 使いどころ:
    • テンプレートデータとインスタンスのデータが連動してはならない場合
    • 計画と実行という構造で実行時の履歴としてその時のテンプレートデータを保持する必要がある場合

■ 5. パターン3:テンプレートなし型

  • 概要:
    • 明示的に管理されたテンプレートデータが存在しないパターン
    • 2つの種類がある:
      • 過去に作成した実例をコピーしてベースに新しいデータを作成するパターン
      • 単純にテンプレートを管理していないパターン
  • 事例1:過去の実例を引用して再利用するケース
    • 業務報告における週報作成
    • 毎週フォーマットや構成がほぼ同じ週報において最新の週報をコピー
    • 日付や内容の一部だけを修正して今週分を作成
  • 事例2:単純にテンプレートを管理していないケース
    • 顧客管理における顧客データの新規作成
    • 各顧客が独自の会社名や住所や担当者や取引条件を持ち共通部分がほとんどない
    • テンプレートを作ってもほぼすべてのフィールドが個別に入力されるためテンプレート管理のコストに見合わない
  • 特徴:
    • 連動性:明示的に管理されたテンプレートデータが存在しないためテンプレートとの連動という概念自体がない
    • データ効率:低い
    • データをコピーして作成するため同じ内容のデータが重複する
  • 使いどころ:
    • テンプレートデータの管理をしたくない場合
    • 過去の実例を引用して再利用するケース
    • 運用をシンプルにしたい場合
    • テンプレートデータを管理する必要性がない場合

■ 6. パターン4:差分管理型

  • 概要:
    • 未改変の部分はテンプレートデータを参照し連動性を保つ
    • インスタンスに改変があった場合は改変された箇所だけをテンプレートからの差分データとして格納
  • 事例:
    • UI設定におけるユーザー別のダッシュボード設定
    • システムデフォルトのダッシュボードレイアウトテンプレートを持つ
    • ユーザーが一部のウィジェットのみ表示/非表示を変更する場合はその差分のみを保持
    • 未変更のウィジェットはテンプレートの更新(新機能追加など)に追従
  • 特徴:
    • 連動性:未改変部分のみがテンプレートの更新に追従
    • 未改変の部分はテンプレートの更新を自動で反映しつつ改変した部分は独立して管理できる
    • 柔軟性と連動性を両立できる
    • データ効率:高い
    • 差分データのみを格納するため重複が少ない
  • 使いどころ:
    • テンプレートデータとインスタンス側のデータの差分が何かを正確に管理したい場合
    • データ効率を重視するとき
  • 注意点:
    • システムの仕組みは煩雑なのでその実装難易度を許容する必要がある

■ 7. 4パターンのまとめ

  • マスター型:
    • 連動性:テンプレートの変更がすべてのインスタンスに即座に反映
    • データ効率:高い
    • 最適な選択基準:一貫性最優先で個別改変が基本的に不要な場合
  • テンプレート型:
    • 連動性:コピー後はテンプレートと無関係
    • データ効率:低い
    • 最適な選択基準:完全に独立した成果物が欲しい場合
  • テンプレートなし型:
    • 連動性:テンプレートが存在しないため無関係
    • データ効率:低い
    • 最適な選択基準:テンプレート管理の必要がなく実例コピーや独立したデータで十分な場合
  • 差分管理型:
    • 連動性:未改変部分のみテンプレートの更新に追従
    • データ効率:高い
    • 最適な選択基準:柔軟性とデータ効率の両立が必要な場合

■ 8. 考察

  • OOPの継承と合成の関係に似ている点が興味深い
  • テンプレートなし型の過去の実例を引用して再利用するケースに実務で出会ったことが記事執筆の経緯
  • テンプレートデータ管理自体が本当に必要なデータではないという事実がある
  • あくまで雛形が欲しいだけでありそのための管理にどこまで工数を投入するかは議論の余地がある