SQL Antipatterns ch3 Naive Trees
- Naive Trees
- Objective: Store and Query Hierarchies
- Antipattern: Always Depend on One's Parent
- How to Recognize the Antipatterns
- Legitimate Uses of the Antipattern
- Solution: Use Alternative Tree Models
A hierarchy consists of entries and relationships. Model both of these to suit your work.
Naive Trees
comment_id | parent_id | comment |
---|---|---|
... |
- すぐ思いつくこの構造には問題がある
- 長いコメントチェーンを1クエリで取得するのが困難
- 子の取得はJOIN
- コメントチェーンの長さは無制限
- SQLのJOIN数は固定長
- 全エントリ取得してアプリケーション側で木を構築するのも計算量・リソース的に非現実
- 長いコメントチェーンを1クエリで取得するのが困難
Objective: Store and Query Hierarchies
- データに再帰関連をもたせるのは普遍的なアイデア
- 木
- ノード
- エントリ
- ルート
- 親のないエントリ
- リーフノード
- 子のないエントリ
- ノンリーフノード
- 中間のノード
- ノード
- 木構造データの例
- 組織図
- コメント返信スレッド
Antipattern: Always Depend on One's Parent
@startuml class 1 class 2 class 3 class 4 class 5 class 6 class 7 1 -- 2 2 -- 3 1 -- 4 4 -- 5 4 -- 6 6 -- 7 @enduml
- 隣接リスト
comment_id | parent_id | author | comment |
---|---|---|---|
1 | NULL | Fran | What's the cause of this bug? |
2 | 1 | Ollie | I think it's a null pointer. |
3 | 2 | Fran | No, I checked for that. |
4 | 1 | Kukla | We neet to check for invalid input. |
5 | 4 | Ollie | Yes, that's a bug. |
6 | 4 | Fran | Yes, please add a check. |
7 | 6 | Kukla | That fixed it. |
Query a Tree with Adjacency List
- JOIN句では固定の深さまでしかデータを取得できない
- 全データ取得してアプリケーション側で木を構築するのも非効率
- 部分木で十分
- 必要なのはレコードの中身ではなく集約した結果のみ
COUNT()
とか
Mantaining a Tree with Adjacency List
- いくつかの操作は単純に実現できる
- 葉ノードの追加
- 単ノードや部分木の再配置
- 削除は複雑
- 部分木のノードを特定
- 葉側から順に削除
- FK制約違反をさけるため
- 子孫を昇格したり再配置したりしないならば
ON DELETE CASCADE
で自動化できる
How to Recognize the Antipatterns
- こんなのが聞こえてきたら注意
Legitimate Uses of the Antipattern
Don't Over-Engineer
Solution: Use Alternative Tree Models
Which Design Should You Use?
設計 | テーブル数 | 子取得 | 部分木取得 | INSERT | DELETE | 参照整合性 |
---|---|---|---|---|---|---|
隣接リスト | 1 | easy | hard | easy | easy | yes |
再帰クエリ | 1 | easy | easy | easy | easy | yes |
パス列挙 | 1 | easy | easy | easy | easy | no |
入れ子集合 | 1 | hard | hard | hard | hard | no |
クロージャテーブル | 2 | easy | easy | easy | easy | yes |
- クロージャテーブルのテーブル構成
- Nodesテーブル
- TreePathsテーブル
- ノードの複数の木に所属させたりできる