🕰️

履歴データの管理方法を考える

2025/04/12に公開

はじめに

本稿は、履歴データの管理方法について学習した内容を整理した備忘録となります。

こちらの記事を大いに参考にさせていただきつつ、他のパターンも追加する形で整理してみました(ご覧になっていない方はぜひお読みください)
https://user-first.ikyu.co.jp/entry/history-table

各方法のサンプルとして、簡略化したドキュメント管理システムを題材としました。

1. バージョンを管理したい場合

ドキュメントの各バージョンを独立したレコードとして保存し、特定のバージョンを容易に参照できるようにしたい場合に適した方法です。

バージョン情報を別テーブルに分離し、documentsテーブルには常に最新のデータのみを保持する設計も考えられます。

2. 操作記録を追跡したい場合

2-1. データの更新を許容しない(イミュータブルデータモデル)

一度書き込まれたデータを変更せず、変更や削除は新しいレコードを追加することで表現するモデルです。

全ての操作(CREATE、UPDATE、DELETE)を単一のテーブルにまとめ、操作種別を示すカラムを持たせるパターンもありえます。

documentsテーブルは常に最新の状態を保持しつつ、別のテーブルに操作履歴を残す方法もあります。この場合はメインのテーブルは更新されるため、イミュータブルとは言えない表現方法になります。なお下記の例では、documents_deletesテーブルは追加の情報を持っていませんが、実際には削除者の情報を格納するなどのケースが考えられます。

2-2. 有効期間を管理する(テンポラルデータモデリング)

各レコードに「有効期間」を持たせ、データが有効であった期間を記録するモデルです。ある時点でのデータ状態を効率的に参照したい場合に適しています。

documentsテーブルは最新状態のみを保持し、履歴情報を別テーブルで管理する方法もあります。

業務上の有効期間とシステム上の記録期間の二つの時間軸を管理するパターンもあります(バイテンポラルデータモデリング)。

一部のRDBMS(SQL ServerやMariaDBなど)では、有効期間の管理をデータベース機能として提供しており、アプリケーション側での実装を簡略化できます。

3. 操作記録を追跡したいが、RDBで管理する必要性はない場合

操作記録を追跡したいが、アプリケーションの主要機能で頻繁に履歴データを参照する必要がない場合、RDBに全ての履歴を保持するのではなく、データウェアハウスなどに転送する方法も有効です。

おわりに

履歴データを管理するためのデータベース設計パターンについて、いくつかの代表的なアプローチをまとめました。何かしら新しい気づきがありましたら幸いです。

参考資料

冒頭で挙げた一休さんの記事以外に、下記資料を参考にさせていただきました。
https://qiita.com/yterui/items/2fc2dd707704edfd93d6
https://zenn.dev/zahn/articles/6a3d2138e9fe68
https://scrapbox.io/kawasima/イミュータブルデータモデル

Discussion