閉包テーブルとは?階層データを高速・柔軟に扱うためのデータベース設計手法をわかりやすく解説【RDBでツリー構造を扱う】
フォルダ階層、カテゴリ分類、組織図、メニュー構造など、**ツリー状のデータ(階層構造)**をデータベースで管理したい場面は多くあります。
しかし、リレーショナルデータベース(RDB)では階層構造の取り扱いが苦手です。
そこで登場するのが 閉包テーブル(Closure Table) という設計手法です。
閉包テーブルを使うと、階層データを高速・柔軟に扱うことができ、大規模データでも効率よく構造を維持できます。
この記事では、閉包テーブルとは何か、メリット、使いどころ、具体的なデータ構造まで初心者にもわかりやすく解説します。
◆ 閉包テーブルとは?
閉包テーブル(Closure Table)とは、
階層構造(親子関係)を持つデータの全ての祖先・子孫関係を別テーブルに保存する方法
のことです。
つまり、「親 → 子」だけでなく、
親 → 孫、親 → 曾孫 など “すべての関係” を記録する のが特徴です。
◆ 階層構造を表すデータベース方式の中での位置づけ
階層データの管理には複数の方法があります。
| 方式 | 特徴 |
|---|---|
| 隣接リスト方式(Adjacency List) | 単純だが階層検索が遅い |
| 経路列挙方式(Path Enumeration) | 経路を文字列で保存、更新が大変 |
| 入れ子集合(Nested Set) | 読み取りは速いが更新が重い |
| 閉包テーブル(Closure Table) | 読み取り・更新どちらも柔軟で高速 |
閉包テーブルは 読み取り・更新のバランスが最も良い方式 とされ、多くのシステムで採用されています。
◆ 閉包テーブルの基本構造
閉包テーブル方式では、次の2つのテーブルを用います。
● 1. ノード(実体)テーブル
例:カテゴリテーブル
id | name
-----------
1 | 家電
2 | テレビ
3 | 液晶テレビ
● 2. 閉包テーブル(祖先・子孫関係を格納)
閉包テーブルの例:
ancestor | descendant | depth
--------------------------------
1 | 1 | 0
1 | 2 | 1
1 | 3 | 2
2 | 2 | 0
2 | 3 | 1
3 | 3 | 0
● depth
- 0 = 自分自身
- 1 = 直接の子
- 2 = 孫
- それ以上 = 子孫関係
このように、階層の「全ての経路」を保存します。
◆ 閉包テーブルのメリット
● 1. 階層検索が高速
「あるノードのすべての子や孫を取得」
「すべての親階層を一覧表示」
などが 1クエリで可能。
● 2. 木構造の再構成が容易
階層構造を復元するための計算が簡単。
● 3. 更新操作が柔軟
- 子ノードの追加
- 親ノードの変更
- サブツリーの移動
などが比較的低コストで行える。
● 4. 入れ子集合方式より圧倒的に扱いやすい
入れ子集合は更新が重いが、閉包テーブルは変更に強い。
◆ 閉包テーブルのデメリット
- 関係数が多いほどテーブルが肥大化する
- データの追加・削除には複数行の更新が発生する
- 小規模データにはオーバースペックになりがち
しかし、階層が深い大規模データでは非常に有用です。
◆ 閉包テーブルはどこで使われる?
● 大規模カテゴリ管理
- ECサイトの商品カテゴリ
- メニュー構造
- コンテンツ管理システム(CMS)
● 組織図
複雑な部署や階層の構造管理に合う。
● フォルダツリー
ファイル管理・権限管理システムなど。
● グラフ構造
祖先・子孫の関係が曖昧な複雑グラフにも応用される。
◆ 閉包テーブルのクエリ例(SQL)
● すべての子孫を取得
SELECT descendant
FROM closure_table
WHERE ancestor = 1;
● すべての親階層を取得
SELECT ancestor
FROM closure_table
WHERE descendant = 3;
◆ 他の階層管理方式との比較まとめ
| 方式 | 読み取り | 更新 | データ量 | 特徴 |
|---|---|---|---|---|
| 隣接リスト | 遅い | 速い | 小さい | 単純 |
| 経路列挙 | 速い | 遅い | 中 | 経路管理が必要 |
| 入れ子集合 | 速い | 非常に遅い | 中 | 読取最速 |
| 閉包テーブル | 速い | 中 | 大きい | 読取と更新のバランス最良 |
◆ まとめ:閉包テーブルは階層データ管理の決定版
閉包テーブルは、
- 階層データのすべての親子関係を保存
- 読み取りが高速
- サブツリーの移動も容易
- 大規模かつ深い階層に対応
- 隣接リスト・入れ子集合より柔軟
という特徴を持ち、階層構造を扱うデータベース設計として非常に優秀です。


