5

単一リンク リスト (id、親) を実装したテーブルを使用しています。この実装は、リストが長くなり、ノードを個別にクエリしているため、最近パフォーマンスが耐えられなくなったことを除いて、うまく機能しています。

単一のクエリでこれをクエリする方法についての有望なブログを見つけました。http://explainextended.com/2009/03/25/sorting-lists/

SELECT  @r AS _parent,
        @r := (
        SELECT  id
        FROM    t_list
        WHERE   parent = _parent
        ) AS id
FROM    (
        SELECT  @r := 0
        ) vars,
        t_list

唯一のことは、私はMySQLを使用するのに十分なほど精通していないということです. 私が持っている質問は、ブログのコメントに投稿したものと同じです。どのレコード/ノードから開始するかを設定するには? 例のテーブルで id 3 から開始したい場合のように。また、リストの最後に到達して停止する必要があることをどのように判断するのでしょうか? 私はそれを試してみましたが、それは永遠に実行されます(おそらく前の質問に関連する不適切な使用が原因です)。

ありがとう。

4

1 に答える 1

5

The query works by iterating over the t_list table (the last line). For each row in this table, the sub-query in the SELECT clause re-queries the table, searching for the current row's child (WHERE parent = _parent -- but _parent is an alias for @r). At each iteration, the child's id is assigned to the @r variable.

To add boundaries, this variation should do the trick:

SELECT * FROM (
    SELECT
        @r AS _parent,
        @r := (
            SELECT id
            FROM t_list
            WHERE
                ( @c = 0 AND _parent IS NULL AND parent IS NULL ) -- special case if the first item is the root
                OR (parent = _parent)
        ) AS id,
        @c := @c + 1 AS rank
    FROM (
        SELECT @c := 0, @r := parent FROM t_list WHERE id = @start
    ) AS ini,
    (
        SELECT id FROM t_list LIMIT @limit
    ) AS lim
) AS tmp WHERE id IS NOT NULL;

Replace @start and @limit with the id of the first item, and the maximum number of items to retrieve, respectively. Please test it here.


Modeling such a data structure with a RDBMS is probably a bad idea altogether. Why not just use an "index" column? Getting the list then becomes instant:

SELECT * FROM list ORDER BY index_column ASC;

Maybe your list is meant to change frequently, but queries like this should be fairly fast unless the list grows really large:

-- insert an element at position X 
UPDATE list SET index_column = index_column +1 WHERE index_column > X ORDER BY index_column DESC;
INSERT INTO list VALUE (some_value, X);

-- delete an element at position X 
DELETE FROM list WHERE index_column = X;
UPDATE list SET index_column = index_column -1 WHERE index_column > X ORDER BY index_column ASC;
于 2013-07-08T22:53:54.187 に答える