29518


親子関係のあるカテゴリー階層を categories テーブルと、ancestor, descendant, depth
を持つ閉包テーブルで表現しようとしています。  
depth は ancestor と descendant の距離を表していて、ancestor == descendant のとき 0（自分自身）で、子は
1 、孫は 2 です。

この設計で親を持たないルートカテゴリーを取得したいのですが表し方がわかりません。  
言葉で表すなら、depth が 0 のカテゴリーのうち descendant ととして参照されている数が ancestor == descendant
の１つしか無いカテゴリーになると思います。

無理にSQLで抽出せず、アプリケーションからの登録段階で「is_root」のようなカラムを用意してその値で判断する形にも出来ますがそうしたほうが良いのでしょうか？

RDB は MySQL を想定しています。


CC BY-SA 3.0
2016-05-24T01:43:23.707
25127
2016-10-15T01:48:55.137
2016-10-13T17:57:48.117
754
10083
question
mysql sql
MySQLの閉包テーブル（Closure Table）でルートを取得したい


下記のように、descendant に１つしか現れないカテゴリを取得するのはどうでしょうか。

[code]

    select descendant from 閉包テーブル group by descendant having count(descendant) = 1;
    
[/code]


CC BY-SA 3.0
2016-10-13T05:56:03.020
29518
2016-10-14T02:59:08.583
2016-10-14T02:59:08.583
19117
19117
25127
answer


SQL で計算してしまう方法については @tabata さんが記述しているのでそちらを。  
そもそも今回のテーブル設計ってなにが正しいんでしたっけ？に対しての自分の認識を。

閉包テーブルは、階層構造を RDB
において表現するための手段の一つであると認識しています。そして、それは基本的に、どのようにテーブルを参照したいかによって、この表現は変わってくる。閉包テーブルは、あるエントリーが対象階層（今回で言うカテゴリー）に属するかどうかを判定するのが得意な構造である。

やりたいことがいくつかの手段で実現できるのなら、あとはパフォーマンスとの兼ね合いだと考えられる。また、 Early Optimization is Evil
(でしたっけ？) という言葉もある。なので、自分だったら、ひとまず SQL を書いて済ませてしまって、あとで効率の問題が出てくるようなら `is_root`
を加える。とすると思います。


CC BY-SA 3.0
2016-10-15T01:48:55.137
29573
2016-10-15T01:48:55.137
754
25127
answer