sql >> データベース >  >> RDS >> Mysql

どの階層モデルを使用する必要がありますか?隣接、ネスト、または列挙?

    通常、階層には3種類のクエリがあり、問題が発生します。

    1. すべての祖先を返す
    2. すべての子孫を返す
    3. すべての子(直系の子孫)を返します。

    これは、MySQLのさまざまなメソッドのパフォーマンスを示す小さな表です。 :

                            Ancestors  Descendants  Children        Maintainability InnoDB
    Adjacency list          Good       Decent       Excellent       Easy            Yes
    Nested sets (classic)   Poor       Excellent    Poor/Excellent  Very hard       Yes
    Nested sets (spatial)   Excellent  Very good    Poor/Excellent  Very hard       No
    Materialized path       Excellent  Very good    Poor/Excellent  Hard            Yes
    

    childrenpoor/excellent つまり、答えは、メソッドを隣接リストと混合しているかどうかによって異なります。 e。 parentIDを保存する 各レコードで。

    タスクには、次の3つのクエリすべてが必要です。

    1. 地球/イギリス/デボンのことを示すすべての祖先
    2. 「ヨーロッパの目的地」(アイテム)を表示するすべての子供
    3. 「ヨーロッパの目的地」を表示するすべての子孫(カウント)

    この種の階層はめったに変更されないので、私は具体化された道を選びます(戦争、反乱などの場合のみ)。

    pathというvarchar列を作成します 、インデックスを作成し、次のような値を入力します:

    1:234:6345:45454:
    

    ここで、番号は適切な親の主キーであり、正しい順序になっています(1 ヨーロッパの場合、234 英国など)

    levelsというテーブルも必要になります 1からの数字を保持する 20へ (または必要な最大ネストレベル)。

    すべての祖先を選択するには:

    SELECT   pa.*
    FROM     places p
    JOIN     levels l
    ON       SUBSTRING_INDEX(p.path, ':', l.level) <> p.path
    JOIN     places pa
    ON       pa.path = CONCAT(SUBSTRING_INDEX(p.path, ':', l.level), ':') 
    WHERE    p.id = @id_of_place_in_devon
    

    すべての子とその中の場所の数を選択するには:

    SELECT  pc.*, COUNT(pp.id)
    FROM    places p
    JOIN    places pc
    ON      pc.parentId = p.id
    JOIN    places pp
    ON      pp.path BETWEEN pc.path AND CONCAT(pc.path, ':')
            AND pp.id NOT IN
            (
            SELECT  parentId
            FROM    places
            )
    WHERE   p.id = @id_of_europe
    GROUP BY
            pc.id
    


    1. Mysql-過去30日間

    2. 名前パターンに一致するMySQLデータベース内のすべてのテーブルを切り捨てます

    3. ファイルまたはアセンブリを読み込めませんでした'MySql.Data、Version =6.2.2.0

    4. MySQLクエリを最適化して、whereの使用を回避します。一時的な使用; filesortの使用