階層型DBMSの深淵:論理関係(Logical Relationship)がもたらす物理の呪縛からの解放
こんにちは。チーフアーキテクトの私だ。
今日のコードレビューで、また「物理階層の制約」に縛られた窮屈なスキーマ定義を見かけた。
「親セグメントの下に子をぶら下げる」――これは階層型DBMS(IBM IMSなど)の基本中の基本だが、実務の現場でそれだけをやっているようでは、二流のモデラーと言わざるを得ない。
現実世界のデータは、きれいに一本の木(ツリー)構造には収まらない。顧客(Customer)が複数の注文(Order)を持ち、注文が複数の商品(Product)を参照するような「多対多(M:N)」や「ネットワーク型」の要件に直面したとき、君たちはどうする? すべてを物理的なツリーにねじ込もうとして、データの冗長化や更新異常の沼にハマっていないか?
今回は、物理的な制約を超えて異なるセグメントを接続する「論理関係(Logical Relationship)」、そしてそれを実現する `LCHILD` および `SEGM` 文の極意を授けよう。物理の呪縛を断ち切り、堅牢で拡張性の高いスキーマを設計するための実践知を解説する。
—
1. なぜ「論理関係」が必要なのか? ―― 物理ツリーの限界
階層型DBMSの本質は、ポインタによる高速なレコードナビゲーションにある。物理的な親子関係(Physical Parent / Physical Child)は、ストレージ上でデータが物理的に隣接、あるいはダイレクトポインタで結ばれているため、トラバーサル(走査)のオーバーヘッドが極限まで少ない。
しかし、これには致命的な欠点がある。
- データの重複保持: 例えば、「顧客データベース」に属する「注文」セグメントから、「製品マスター」の情報を参照したい場合、物理ツリーの制約上、製品データを注文セグメントの配下にコピー(冗長化)して持たざるを得なくなる。
- 更新異常(Anomalies): 製品の価格や名称が変わったとき、すべての顧客ツリー配下にある重複データを更新しなければならない。これはバッチ処理の悪夢だ。
ここで登場するのが論理関係(Logical Relationship)である。データを物理的に複製するのではなく、ポインタ(Logical Pointer)を介して別のデータベースのセグメントを「論理的」に結合する。これにより、物理構造の美しさと、リレーショナルモデルのような柔軟な参照関係を共存させることが可能になる。
—
2. DDLの核心:LCHILD と SEGM 文の正しいマッピング
論理関係を定義するためには、DBD(Database Description)のスキーマ定義において、論理親(Logical Parent: LP)と論理子(Logical Child: LC)の関係を正確にマッピングする必要がある。
実務で最も頻出する「M:Nの関係(例:顧客と受講コース)」を例に、DBD生成マクロのコードを見てみよう。
実装パターン:論理親・論理子のDBD定義
- =====================================================================
- 1. 物理データベース 1: 顧客マスター (CUSTDB)
- =====================================================================
DBD NAME=CUSTDB,ACCESS=HDAM,RMNAME=(DFSHDC40,1000,500)
SEGM NAME=CUSTOMER,BYTES=100,PTR=TB
FIELD NAME=(CUSTID,SEQ,U),BYTES=10,START=1
- — ここが論理親(Logical Parent)となるセグメント —
SEGM NAME=CUSTREG,PARENT=CUSTOMER,BYTES=50,PTR=T
FIELD NAME=(REGID,SEQ,U),BYTES=5,START=1
DBDGEN
FINISH
END
- =====================================================================
- 2. 物理データベース 2: コースマスター 兼 論理関係定義 (COURSEDB)
- =====================================================================
DBD NAME=COURSEDB,ACCESS=HIDAM
SEGM NAME=COURSE,BYTES=200,PTR=TWIN
FIELD NAME=(COURSEID,SEQ,U),BYTES=8,START=1
- — 論理子(Logical Child)の定義 —
- LCHILD文で、別DB(CUSTDB)のCUSTREGを論理親として指定する
SEGM NAME=ENROLL,PARENT=COURSE,BYTES=20,
PTR=(LPARNT,TWIN),
LCHILD=(CUSTREG,CUSTDB)
- — ペアとなるポインタの定義(双方向論理関係) —
LCHILD NAME=(ENROLL,COURSEDB),POINTER=SNGL
DBDGEN
FINISH
END
チーフアーキテクトのコードレビュー:ここを見極めろ
1. `LCHILD=(CUSTREG,CUSTDB)` の指定:
`COURSEDB` 側のセグメント `ENROLL` が、`CUSTDB` 内の `CUSTREG` セグメントを「論理親」として指している。これにより、コース側から顧客の登録情報を論理的に引くことができる。
2. ポインタ指定(`PTR`)の妙:
`PTR=(LPARNT,TWIN)` に注目しろ。論理子セグメントは、物理的な親(コース)へのポインタだけでなく、論理親(顧客登録)へのポインタ(Logical Parent Pointer)を保持する必要がある。ここをケチると、逆方向の走査でパフォーマンスが崩壊する。
3. 双方向(Bi-directional)の構築:
実務では単方向の参照だけでなく、顧客側からも「自分がどのコースに申し込んでいるか」を双方向で引きたいケースがほとんどだ。そのため、物理親側にも `LCHILD` 文を置き、ペアリングを完結させる。
—
3. 堅牢な設計パターン:論理関係における「削除規則(Rules)」の罠
論理関係を設計する際、ジュニアエンジニアが最もやりがちなミスが「削除規則(Delete Rules)」の設計漏れだ。
物理的な親子関係であれば「親が消えれば子はカスケード削除」で済むが、論理関係はデータベースを跨ぐため、片方のデータを消したときの整合性を厳密に定義しなければならない。
DBDの `RMBN` や `RULES` パラメータで指定する削除規則には、以下の3つがある。
| 削除規則 | 動作概要 | 実務での推奨ユースケース |
| :— | :— | :— |
| VIRTUAL (V) | 論理親側が削除されても、論理子は物理的に残る(ポインタが無効化されるか、参照不可になる)。 | マスターデータに対するトランザクション参照など、履歴を保持すべき場合。 |
| LOGICAL (L) | 論理親の削除に伴い、論理子側も連動して削除される。 | 強い従属関係にあるM:Nのマッピングデータ。 |
| RESTRICT (R) | 論理子が残っている状態では、論理親の削除を拒否する。 | 整合性を最優先し、誤削除を防ぎたいマスター間の結合。 |
【アーキテクトからの戒め】
金融や基幹システムの勘定系において、安易に `LOGICAL` 削除を採用するな。ある日突然、親側のバッチ処理で意図せぬデータが消え、参照していた別の業務システムのトランザクションデータまで連鎖消滅した……なんて障害を起こしたら、君のエンジニア生命に関わる。基本は `RESTRICT` または厳格なアプリケーション制御を前提に設計しろ。
—
4. パフォーマンス上の注意点:論理パス(Logical Path)のコスト
「論理関係を使えば何でもスマートに繋げる」と勘違いしてはいけない。構造が美しくなる一方で、パフォーマンスの代償を払っていることを忘れるな。
1. I/Oコストの増大
物理データベースが別々(異なるVSAMデータセット)に存在する場合、論理親を辿る(Logical Pathを解決する)ためには、追加のダイレクトアクセスやI/Oが発生する。同一物理ツリー内のトラバーサルに比べ、数倍から数十倍のコストがかかることがある。
2. 再編成(Reorganization)の複雑化
論理関係で結ばれたデータベースは、一方だけを単体でアンロード/ロード(再編成)することが極めて困難になる場合がある。ポインタが別のDBDを指しているため、構造変更の際は両方のデータベースを同時に、あるいは整合性を保った順序で再編成しなければならない。運用フェーズでのバッチウインドウ圧迫要因ワースト常連だ。
—
5. まとめ
階層型DBMSにおける論理関係(Logical Relationship)は、物理的な制約という「檻」の中で、リレーショナルな柔軟性を手に入れるための、先人たちの美しくも執念深い発明品だ。
- 物理的な重複を排除し、M:Nの複雑な関係を表現するために `LCHILD` と `SEGM` を使いこなせ。
- 双方向ポインタのコストと、データベースを跨ぐ削除規則(`RESTRICT` / `LOGICAL`)の選択には細心の注意を払え。
- 構造の美しさと引き換えになる「I/Oコスト」と「再編成の複雑性」を常に念頭に置け。
単に動くコードを書くだけなら誰でもできる。だが、ハードウェアの制約とデータ構造の整合性を極限までチューニングし、10年後も耐えうるスキーマを描き切ることこそが、我々プロフェッショナルなアーキテクトの仕事だ。
次回のコードレビューでは、今日話した論理関係の設計思想が反映された、美しいDBD定義書を持ってくることを期待している。
コメント