问题描述
我有一个包含 id
和 parentId
列的表:我将此结构称为邻接表。
所以,现在我想获得任意 id 的所有孩子。此问题的经典解决方案使用递归,例如 here is Postgres procedure or CTE implementation。
我目前正在使用 Spring Webflux 和 Spring Data R2DBC + Postgres R2DBC 驱动程序(尚不支持存储过程)。
我怎样才能以反应式的方式解决这个问题?甚至有可能还是我错过了概念上错误的东西?
更新 1:
让我们想象一下我们拥有的数据:
+-------------+---------+
|id |parent_id|
+-------------+---------+
|root |NULL |
|id1 |root |
|dir1 |root |
|dir1_id1 |dir1 |
|dir1_dir1 |dir1 |
|dir1_dir1_id1|dir1_dir1|
+-------------+---------+
现在我想在 ReactiveCrudRepository 中有一个方法,它将返回所提供 id 的所有子项。
例如,使用示例数据:通过提供 id='dir1',我想获得具有 ids 的孩子:['dir1_id1',"dir1_dir1","dir1_dir1_id1"]。
解决方法
我认为最好的 sql 方法是递归 CTE(公用表表达式),您尝试过吗?我从来没有尝试过很多行。
WITH recursive nodes AS (
SELECT id,parent_id
FROM t
WHERE parent_id = 'dir1'
UNION ALL
SELECT t.id,t.parent_id
FROM nodes n
INNER JOIN t ON t.parent_id = n.id
)
SELECT id
FROM nodes;
parent_id = 'dir1' 的输出
id |
---|
dir1_id1 |
dir1_dir1 |
dir1_dir1_id1 |
使用 proc 或 cte 与全扫描无关。
在您的情况下,您只需要使用递归 cte ,但是在 id,parentid 上添加索引肯定会有所帮助
create index idx_name on tablename (parentid,id);
还有 10k 行并不是那么大,索引肯定会提高很多。