データベースにテーブルがあり、ハイブリッド入れ子集合(MPTT)モデル(lft
とrght
値を持つモデル)と隣接リストモデル(parent_id
各ノードに格納)を使用してツリー構造を格納しています。
my_table (id, parent_id, lft, rght, alias)
この質問は、ツリーのMPTTの側面のいずれにも関連していませんが、誰かがそれを活用する方法について良いアイデアを持っている場合に備えて、私はそれを残すと思いました。
エイリアスのパスを特定のノードに変換したい。例:"users.admins.nickf"
ルートにある「users」の子であるエイリアス「admins」を持つノードの子であるエイリアス「nickf」を持つノードを検索します。には一意のインデックスがあります(parent_id, alias)
。
まず、関数を記述して、その部分へのパスを分割し、データベースに1つずつクエリを実行することから始めました。
SELECT `id` FROM `my_table` WHERE `parent_id` IS NULL AND `alias` = 'users';-- 1
SELECT `id` FROM `my_table` WHERE `parent_id` = 1 AND `alias` = 'admins'; -- 8
SELECT `id` FROM `my_table` WHERE `parent_id` = 8 AND `alias` = 'nickf'; -- 37
しかし、その後、可変量のネストを使用して、単一のクエリでそれを実行できることに気付きました。
SELECT `id` FROM `my_table` WHERE `parent_id` = (
SELECT `id` FROM `my_table` WHERE `parent_id` = (
SELECT `id` FROM `my_table`
WHERE `parent_id` IS NULL AND `alias` = 'users'
) AND `alias` = 'admins'
) AND `alias` = 'nickf';
サブクエリの数はパスのステップ数に依存するため、サブクエリが多すぎるという問題が発生しますか?(そんなことがあったら)
このクエリを実行するためのより良い/よりスマートな方法はありますか?