📘

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

に公開

この記事は レバテック開発部 Advent Calendar 2025 6日目の記事です。

はじめに

アプリケーション開発において、だいたい同じだけど、一部が異なるデータを管理しなくてはならないときがあります。

例えば、以下のような要件に遭遇することがあります。

  • サイト全体の設定を元に、プロジェクトごとに一部だけ変更した設定ファイル。
  • 共通の契約書のテンプレートデータを元に、顧客ごとに特約を書き加えた契約書。

これらはすべて、元となるテンプレートデータと、それを活用しつつ改変されたインスタンスデータの関係にあります。

本記事では、この課題を解決するためのデータ構造を4つのパターンに分類し、設計の際の判断軸である連動性のトレードオフを分析します。

4パターンの分類と分析軸

だいたい同じだけど一部が異なるデータを持つデータでは、テンプレートデータの変更をインスタンスデータにどこまで反映させるかという連動性をどう表現すべきかという問題と、インスタンスデータが増えるとデータ効率が悪化するという問題があります。

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

このテンプレートデータとインスタンスデータの連動性とデータ効率の二つの観点から、4つのデータパターンを提案します。

1. マスター型

概要

インスタンスデータはマスターデータを直接参照して活用します。インスタンス側での改変は許容せず、変更はすべてマスターデータの修正や追加で実現します。

事例

料金管理: 標準料金プランマスタと地域別料金プランマスタ

標準料金プランマスタを基本的なマスターとしつつも、地域別料金プランマスタも同列で用意します。地域別プランは基本的に標準プランを参照して使用しますが、まれに地域固有のプランが必要な場合は子マスタに新規追加できます。標準プランの内容変更(価格改定など)は、それを参照しているすべての地域プランに自動反映されます。

特徴

  • 連動性: マスターデータを直接参照するため、マスターを更新すれば即座にすべてのインスタンスに反映されます。一方で、インスタンス側で変更したい場合であっても、マスターデータに何らかの変更を加える必要があります。
  • データ効率: 高い。データは一箇所に集約され重複がありません。マスターデータを直接参照するため、同じデータを複数箇所に保存する必要がなく、高いデータ効率と一貫性を保てます。

使いどころ

  • インスタンスのデータがマスターデータと連動して変更されていい場合は適切です。逆に言えば、計画と実行のようにインスタンスのデータを保存する必要がある場合は、この手法は不適切です。
  • インスタンスでの変更が少ない場合が適切です。もしも、インスタンス側でマスターデータと異なるデータを多数作る場合、マスターデータが多くなります。このような場合、管理が煩雑なのでこのデータパターンは不適切です。

2. テンプレート型

概要

インスタンスデータは、明示的に管理されたテンプレートデータ完全に複製して作成されます。作成後は、テンプレートデータとの関連性は一切なくなり、完全に独立したデータとして管理・改変されます。

事例

顧客ごとの契約書

共通の契約書テンプレートデータをコピーし、顧客ごとに個別の契約書で契約を結びパターンです。テンプレートを変えても過去や現在結んだ契約に影響がないです。また、顧客ごとに契約内容を調整しても問題ないです。

特徴

  • 連動性: 最初の作成時に、テンプレートデータをコピーしてインスタンスデータが作成されたら、以後はテンプレートデータとインスタンス側のデータの間に関係はないです。テンプレートデータが更新されても既存のインスタンスには一切影響しません。このため、インスタンス側はテンプレートの変更を気にせず自由に改変できます。
  • データ効率: 低いです。コピーが増えるほど同じ内容のデータが重複します。各インスタンスがテンプレートデータの完全な複製を持つため、テンプレートと同じ内容のデータが多数重複し、データ効率は低くなります。

使いどころ

  • テンプレートデータとインスタンスのデータが連動してはならない場合です。例えば、計画と実行という構造だと、実行時の履歴としてその時のテンプレートデータを保持する必要があるかと思います。そのような場合はテンプレート型が適切です。

3. テンプレートなし型

概要

明示的に管理されたテンプレートデータが存在しないパターンです。このパターンはさらに2つの種類があります。

  • 過去に作成した実例を引っ張ってきてコピーし、それをベースに新しいデータを作成するパターンです。この場合、コピー元の実例が実質的にテンプレートの役割を果たします。
  • 単純にテンプレートを管理していないパターンです。各データの差分が多すぎてテンプレートを作る意味がない場合です。テンプレートを作っても、ほとんどのフィールドが個別に変更されるため、テンプレート管理のコストに見合わないケースです。

事例

このパターンは、コピー元の選択や目的によって以下の2つの主要なケースに分けられます。

過去の実例を引用して再利用するケース

業務報告: 先週の週報をコピーして作成

毎週フォーマットや構成がほぼ同じ週報において、最新の週報をコピーし、日付や内容の一部だけを修正して今週分を作成します。

単純にテンプレートを管理していないケース

顧客管理: 顧客データの新規作成

各顧客が独自の会社名、住所、担当者、取引条件などを持ち、共通部分がほとんどありません。テンプレートを作っても、ほぼすべてのフィールドが個別に入力されるため、テンプレート管理のコストに見合いません。

特徴

  • 連動性: そもそも明示的に管理されたテンプレートデータが存在しないため、テンプレートとの連動という概念自体がありません。
  • データ効率: 低いです。データをコピーして作成するため、同じ内容のデータが重複します。

使いどころ

  • テンプレートデータの管理をしたくない場合や、過去の実例を引用して再利用するケースに有効です。
  • とにかく運用をシンプルにしたい場合やテンプレートデータを管理する必要性がない場合、単純にテンプレートを管理していないケースに有効です。

4. 差分管理型

概要

未改変の部分はテンプレートデータを参照し、連動性を保ちます。インスタンスに改変があった場合、改変された箇所だけを、テンプレートからの差分データとして格納します。

事例

UI設定: ユーザー別のダッシュボード設定

システムデフォルトのダッシュボードレイアウトテンプレートを持ち、ユーザーが一部のウィジェットのみ表示/非表示を変更する場合、その差分のみを保持します。未変更のウィジェットはテンプレートの更新(新機能追加など)に追従します。

特徴

  • 連動性: 未改変部分のみがテンプレートの更新に追従します。未改変の部分はテンプレートの更新を自動で反映しつつ、改変した部分は独立して管理できるため、柔軟性と連動性を両立できます。

  • データ効率: 高いです。差分データのみを格納するため重複が少なくなります。インスタンス側で改変していない部分については、テンプレートを参照するだけで共通するデータを格納しないため、高いデータ効率を保てます。

使いどころ

  • テンプレートデータとインスタンス側のデータの差分が何かを正確に管理したい場合や、データ効率を重視するときはこの方式が有効です
  • システムの仕組みは煩雑なので、その実装難易度を許容する必要があります。

まとめ

ここまでに提示した4パターンを表にまとめました。

これらは連動性とデータ効率のトレードオフがあります。さらに、いつ何が連動していいのかどうかも重要です。これらを意識しながら、最適な手法を選択する必要があるでしょう。

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

あとがき

今回はデータの差分管理を4つのパターンに分類してみました。これはOOPの継承と合成の関係にも似ていると感じており、そこが興味深かったです。

私が知らないだけかもしれませんが、このような差分管理について分類した記事を読んだ覚えがないので、今回はまとめてみました。MECEにあまりならなかったのが心引っ張られますが、誰かの参考になれば幸いです。

ちなみに、この記事を書いた経緯は、テンプレートなし型の過去の実例を引用して再利用するケースに実務で出会ったからでした。

最初はテンプレートデータ管理の方が望ましいと思っていたのですが、データの雛形として過去事例を引っ張ってきたいというだけにテンプレートデータ管理はやりすぎなことがあるのではないかと考え直しました。

もっと考えていくと、テンプレートデータ管理自体が本当に必要なデータではないという事実に気がつきました。あくまで雛形が欲しいだけであり、そのための管理をどこまで工数を投入するのかは議論の余地があると感じました。

レバテック開発部

Discussion