Views: 0
なぜRDB設計者に「1つの階層表」が重要なのか ― Structured Tidy Data(構造化Tidyデータ)
2026-09-06
リレーショナル・データベースは、業務システムのリアルタイム処理に非常に適しています。
現在のデータを更新し、正規化された複数の表をJOINし、整合性を保ちながらトランザクションを処理することは、RDBが最も得意とする領域です。
しかし、長期保存は別の問題です。
過去の取引を何年も後に再利用するためには、取引行だけを保存しておけばよいとは限りません。
その取引を正しく理解するには、当時のマスターデータ、スキーマ、コード表、JOIN条件、さらにアプリケーション固有のルールまで必要になることがあります。
Structured Tidy Data(構造化Tidyデータ)は、この異なる要求に対応するための表現です。
1. セマンティックなオブジェクトモデルから始める
ここでは、次の4つのクラスを例にします。
-
JournalEntry -
JournalLine -
TaxDetail -
Account
JournalEntry は1件以上の JournalLine を持ちます。
JournalLine は繰り返し可能な TaxDetail を持つことができ、1つの Account を参照します。
各クラスには、それぞれ entry_id、line_id、tax_id、account_id というunique identifierがあります。
意味の正本はこのセマンティックモデルです。
クラス、属性、カーディナリティ、関連をここで定義します。
問題は、このモデルから得られるデータを、どのように保存・交換するかです。
2. RDB設計者なら通常どうするか
通常のRDBでは、このモデルを複数のリレーションに分解します。
これは業務システムのデータベースとして自然な設計です。
2.1. JournalEntry
| entry_id | entry_date | journal_code | description |
|---|---|---|---|
|
H001 |
2026-09-01 |
SALES |
Sale of Product X |
|
H002 |
2026-09-02 |
PURCHASE |
Purchase of Material A |
2.2. JournalLine
| entry_id | line_id | debit_credit_code | account_id | amount |
|---|---|---|---|---|
|
H001 |
D001 |
debit |
1100 |
100.00 |
|
H001 |
D002 |
credit |
4000 |
100.00 |
|
H002 |
D003 |
debit |
5000 |
80.00 |
|
H002 |
D004 |
credit |
2100 |
80.00 |
2.3. TaxDetail
| entry_id | line_id | tax_id | tax_category | tax_rate | tax_amount |
|---|---|---|---|---|---|
|
H002 |
D003 |
T001 |
Standard |
10 |
8.00 |
2.4. Account
| account_id | account_name | account_type |
|---|---|---|
|
1100 |
Cash |
Asset |
|
4000 |
Sales |
Revenue |
|
5000 |
Purchases |
Expense |
|
2100 |
Accounts Payable |
Liability |
アプリケーションの永続化には、この分解が最適である場合が多いでしょう。
各クラスを別の表に置き、外部キーで関係を再構成できます。
しかし、交換や長期保存を考えると、別の問題が生じます。
一つの業務記録の意味が、複数の表やファイルに分散するからです。
3. 歴史データの長期保存は別の問題
過去の JournalLine に、次の情報しか保存されていないとします。
account_id = 1100
amount = 100.00
何年か後にこのデータを正しく解釈するには、1100 がその当時何を意味していたかを示す Account マスターも必要です。
同じ問題は次のようなデータにもあります。
-
税コード
-
取引先
-
通貨
-
商品
-
組織
-
その他の参照マスター
Header と Line も、整合した一式として保存されていなければなりません。
片方だけ復元しても、参照切れや不完全な取引記録になる可能性があります。
データベースのバックアップを保存すれば、その状態自体を残すことはできます。
しかし将来再利用するためには、正しい
-
データベース・バージョン
-
スキーマ
-
マスターデータ
-
コード表
-
アプリケーション・ロジック
-
JOINルール
まで復元しなければならないことがあります。
これは障害復旧には適しています。
しかし、持ち運び可能な長期保存形式として常に最適とは限りません。
|
Important
|
正規化は業務処理には非常に有効です。しかし、正規化されたデータベースが、そのまま自己完結した歴史記録になるとは限りません。 長期保存では、取引を理解するために必要な情報を、業務システム内では複数表に分かれていても、一緒に保存できることが重要です。 |
4. では、全部をフラットにすればよいのか
別の方法として、JournalEntry の属性をすべて JournalLine の各行にコピーしたCSVを作ることができます。
しかし、今度は別の問題が生じます。
| entry_id | entry_date | description | line_id | account_id | amount |
|---|---|---|---|---|---|
|
H001 |
2026-09-01 |
Sale of Product X |
D001 |
1100 |
100.00 |
|
H001 |
2026-09-01 |
Sale of Product X |
D002 |
4000 |
100.00 |
entry_date や description が明細行ごとに繰り返されます。
TaxDetail が複数あれば、重複はさらに増えます。
矩形の表としては読みやすくなりますが、どの属性がどのクラスに属するのかが曖昧になります。
本来 JournalEntry に属する値が、物理的には JournalLine の各行にコピーされてしまいます。
構造化Tidyデータは、この二つの極端な方法を避けます。
-
セマンティッククラスごとに必ず別の物理表を要求しない
-
親クラスの属性を子クラスの行に繰り返さない
5. 構造化Tidyデータ とは何か
構造化Tidyデータ は、複数のセマンティッククラスのoccurrenceを、1つの疎な表に格納する、モデル管理された表形式です。
基本原則は単純です。
-
1行は1つのclass occurrenceを表す。
-
属性値は、その属性を所有するクラスの行にだけ記録する。
-
繰り返しクラスは、
Tax1、Tax2、Tax3のような番号付き列ではなく、追加の行として表す。 -
階層occurrence列で親子関係を保持する。
-
参照関係は明示的に保持する。
-
空欄は構造的な意味を持つ。通常は「値が不明」ではなく、「この列は別のクラスに属する」ことを示す。
簡略化した例を示します。
| class | dEntry | dLine | dAccount | dTax | entry_id | entry_date | line_id | debit_credit | amount | tax_id | tax_rate | tax_amount | account_id | account_name |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
JournalEntry |
1 |
H001 |
2026-09-01 |
|||||||||||
|
JournalLine |
1 |
1 |
D001 |
debit |
100.00 |
|||||||||
|
Account |
1 |
1 |
1 |
1100 |
Cash |
|||||||||
|
JournalLine |
1 |
2 |
D002 |
credit |
100.00 |
|||||||||
|
Account |
1 |
2 |
1 |
4000 |
Sales |
|||||||||
|
JournalEntry |
2 |
H002 |
2026-09-02 |
|||||||||||
|
JournalLine |
2 |
1 |
D003 |
debit |
80.00 |
|||||||||
|
TaxDetail |
2 |
1 |
1 |
T001 |
10 |
8.00 |
||||||||
|
Account |
2 |
1 |
1 |
5000 |
Purchases |
|||||||||
|
JournalLine |
2 |
2 |
D004 |
credit |
80.00 |
|||||||||
|
Account |
2 |
2 |
1 |
2100 |
Accounts Payable |
|
Note
|
class 列は、説明のために、各行がどの Class に属するかを示したものです。実データに存在する列ではありません。 |
RDB設計者には、この表は見慣れない形に見えます。
複数のセマンティッククラスが1つの物理表の中に共存しているからです。
しかし、これは意図した設計です。
この表は業務DBを置き換えるためのものではありません。
セマンティックなデータセットを持ち運ぶための表現です。
|
Note
|
次の例では、TaxDetail および Account Class は繰り返しがないため、上位の JournalEntry と同じ行に記録しています。Class の階層は維持されますが、繰り返しのない Class のために別の物理行を設ける必要はありません。 |
| class | dEntry | dLine | entry_id | entry_date | line_id | debit_credit | amount | tax_id | tax_rate | tax_amount | account_id | account_name |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
JournalEntry |
1 |
H001 |
2026-09-01 |
|||||||||
|
JournalLine |
1 |
1 |
D001 |
debit |
100.00 |
1100 |
Cash |
|||||
|
JournalLine |
1 |
2 |
D002 |
credit |
100.00 |
4000 |
Sales |
|||||
|
JournalEntry |
2 |
H002 |
2026-09-02 |
|||||||||
|
JournalLine |
2 |
1 |
D003 |
debit |
80.00 |
T001 |
10 |
8.00 |
5000 |
Purchases |
||
|
JournalLine |
2 |
2 |
D004 |
credit |
80.00 |
2100 |
Accounts Payable |
6. なぜこの形式が重要なのか
この見慣れない形によって、次の3つを同時に実現できます。
-
1つの持ち運び可能なデータセット
完全な業務記録を、アプリケーション固有の複数リレーションではなく、1つの管理された表として受け渡せます。 -
親属性を重複させない
JournalEntryの属性はJournalEntry行にだけ存在し、各JournalLineにコピーしません。 -
階層と参照関係を明示的に保持する
JournalEntry、JournalLine、TaxDetail、Accountの関係を、表形式のまま機械的に追跡できます。
RDB設計者にとって重要なのは、目的が違うという点です。
| 業務用RDB | 構造化Tidyデータ |
|---|---|
|
現在のトランザクション処理に最適化 |
交換、確認、長期保存、分析に最適化 |
|
複数の正規化された物理表 |
複数のセマンティッククラスを1つの疎な表に収容可能 |
|
JOINによって関係を再構成 |
occurrence contextと明示的参照で階層を保持 |
|
マスターデータは別の場所に存在することがある |
解釈に必要な参照情報を同じデータセットに含められる |
|
運用DBのスキーマやアプリケーション規約に依存 |
共有セマンティックモデルによって管理 |
7. AIにとってもなぜ有用なのか
構造化Tidyデータは、取引を理解するために必要な情報を、1つのモデル管理されたデータセットとして保存できるため、AIによる分析にも適しています。
通常の正規化RDBでは、AIが過去の取引を正しく理解するために、取引行だけでなく、
-
データベーススキーマ
-
主キー・外部キー関係
-
当時のマスターデータ
-
コード表
-
JOINルール
-
アプリケーション固有の知識
まで必要になることがあります。
account_id = 1100 という値だけでは意味は十分ではありません。
その歴史時点で 1100 が Cash を意味し、Asset に分類されていたことも分からなければなりません。
構造化Tidyデータでは、JournalEntry、JournalLine、TaxDetail、Account などの関連クラスを同じデータセットに含めることができます。
各値は、その値を所有するクラスの行にだけ記録され、階層occurrence情報によって行同士の関係を保持します。
したがって AI にとっての利点は、単に「表の方がデータベースより読みやすい」ということではありません。
|
Important
|
より重要なのは、データを解釈するために必要なセマンティック・コンテキストを、保存データと一緒に持ち運べることです。 |
AIは、元の業務データベースとそのJOINを完全に再構築しなくても、過去の取引を調べることができます。
8. まとめ
構造化Tidyデータは、RDBを否定する考え方ではありません。
リアルタイムの業務処理には、RDBが引き続き適しています。
構造化Tidyデータの目的は異なります。
長期保存、交換、検証、分析、AIによる歴史データの解釈のために、持ち運び可能で、自己完結性が高く、セマンティックモデルによって管理された表現を提供します。
RDB設計者から見ると、この表の形は一見不自然です。
しかし、それは正規化を捨てるためではありません。
セマンティックな分離を保ちながら、過去の業務記録全体を一緒に保存・移送できるようにするための設計です。



コメントを残す