SQLで階層構造を扱う方法とは

dtn.jpのディレクトリは、各カテゴリのhtmlが階層構造になっています。このカテゴリデータをSQLのテーブルに保存するためには、カテゴリ情報と一緒に、親子関係情報を持たせる必要があります。

例えば、下記のような階層構造をもつ情報をテーブルで保存する場合、

A 
├ ─ B
├ ─ C ─ F
├ ─ D ─ G
│     └ H
└ E

以下のような形でカテゴリの親子関係情報をもたせれば、後々プログラムを使って階層構造とすることができます。

idNAMEparent_id
1A
2BA
3CA
4DA
5EA
6FC
7GD
8HD

テーブルに保存するカテゴリの情報(カテゴリ名・カテゴリファイル名)に、親カテゴリのIDも持たせておけば、階層構造情報を二次元的に保持することができるといった感じです。

参考としたのがこちらの掲示板記事でした。

dtn.jpディレクトリのカテゴリ用テーブル

dtnディレクトリでも、各カテゴリには親となるカテゴリのidをもたせるよう、カテゴリ用テーブルを構成していました。

+-------------+----------------------+--------+
| cate_id | name | filename |parent |
+-------------+----------------------+--------+
| 1 | エンタメ | Entertainment | NULL |
| 2 | 芸術と人文 | Arts | NULL |
| 3 | ビジネスと経済 | Business_and_Economy | NULL |
| 4 | 音楽 | Music | 1 |
| 5 | お笑い、ユーモア | Humor__Jokes__and_Fun | 1 |
| 6 | 外国のアート | Countries_and_Cultures | 2 |

PHPで階層構造にhtmlを出力

このカテゴリテーブルの情報を元にして、HTMLファイルをディレクトリ構造で出力したり、下記のようなパンくずリストを生成したりしていました。

トップページ > コンピュータとインターネット > インターネット > ホームページ、ウェブサイト

階層構造をより複雑化させたい

ディレクトリ開設当初は、単純な階層構造をディレクトリに出力させるだけで満足していましたが、運用していくうちに少々欲がでてきました。

例えば、親カテゴリを持つものの、全く別のカテゴリにもリンクとして表示したいといったパターンです。

┬─趣味とスポーツ
│ └─自動車
│   └─★
│
├─ビジネスと経済
│ └─ショッピングとサービス
│   └─自動車、オートバイ
│      └─メーカー、ブランド(これを★に)
└─政治

「趣味とスポーツ > 自動車」下の★部分にも、異なるカテゴリにある「ビジネスと経済 > ショッピングとサービス > 自動車、オートバイ > メーカー、ブランド」を表示させたいといったパターンです。

色々考えましたが、結局はテーブル内にリンクを表示したい親ページを持たせておき、あとはプログラム側で解決することにしました。

+-------------+----------------------+--------+
| cate_id | name | filename | parent | link_parent |
+-------------+----------------------+--------+
| 693 | メーカー、ブランド | NULL | NULL | 48 |
| 688 | メーカー、ブランド | Makes_and_Models | 316 | NULL |

結果、このディレクトリ型検索エンジンdtn > 趣味とスポーツ > 自動車カテゴリの中に、親カテゴリが異なるカテゴリをリンクさせることができました。

テーブルに階層構造データさえ持たせておけば、プログラム側で色々とサイトを生成できるということがお分かりになったと思います。

おわりに

SQLには、階層構造データを保持することもできることが、お分かりいただけたと思います。この記事が、テーブル内で階層構造データを扱う最適な方策を検討することに役立つことを願っています。