btd*_*btd 5 mysql sql linked-list
我正在使用一个实现了单链表(id,父级)的表。这个实现一直运行良好,只是最近性能变得难以忍受,因为我的列表变得很长并且我一直在单独查询节点。
\n\n我发现了一个很有前途的博客,介绍如何在单个查询中对此进行查询。http://explainextend.com/2009/03/25/sorting-lists/
\n\nSELECT @r AS _parent,\n @r := (\n SELECT id\n FROM t_list\n WHERE parent = _parent\n ) AS id\nFROM (\n SELECT @r := 0\n ) vars,\n t_list\nRun Code Online (Sandbox Code Playgroud)\n\n唯一的问题是我对 MySQL 不够了解,甚至无法使用它。我的问题与我在博客评论中发布的问题相同。如何设置从哪个记录/节点开始?就像我想从示例表中的 id 3 开始一样。它如何知道何时到达列表末尾并应该停止?我\xe2\x80\x99已经尝试过它,它只是永远运行(可能是由于与前一个问题相关的使用不当)。
\n\n谢谢。
\n该查询通过迭代表t_list(最后一行)来工作。对于该表中的每一行,子句中的子查询SELECT会重新查询该表,搜索当前行的子行(WHERE parent = _parent--but_parent是 的别名@r)。在每次迭代中,孩子的变量id都会被分配给该@r变量。
要添加边界,这种变化应该可以解决问题:
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;
Run Code Online (Sandbox Code Playgroud)
分别将@start和替换@limit为id第一个项目的 和要检索的最大项目数。请在这里测试一下。
使用 RDBMS 建模这样的数据结构可能完全是一个坏主意。为什么不只使用“索引”列呢?然后立即获取列表:
SELECT * FROM list ORDER BY index_column ASC;
Run Code Online (Sandbox Code Playgroud)
也许您的列表应该经常更改,但是这样的查询应该相当快,除非列表变得非常大:
-- 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;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4765 次 |
| 最近记录: |