请问如果一棵树存在数据表中,有没有办法将其一次查出?

2022-06-28 00:30:37 +08:00
 jackiejkl
也就是 SQL 可以写 DFS 吗?是不是需要用到存储过程?或者有更优解?
4738 次点击
所在节点    MySQL
35 条回复
kkkiio
2022-06-28 14:12:49 +08:00
@tabris17 我查一下,这个“左右值”方案英文叫 Nested Set Model ,有篇老文 http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/ 讲了这个,感觉很有意思,就是改结构时更新数据有点多。

Stack Overflow "Adjacency List Model vs Nested Set Model for MySQL hierarchical data?" 有个回答 https://stackoverflow.com/a/31642680/5008141 认为 Nested Set Model 过于复杂,推荐用 Recursive Common Table Expressions ,也就是楼上说的 Recursive CTE 。
tabris17
2022-06-28 14:23:32 +08:00
@kkkiio 这个“Nested Set Model”的优势是可以一条语句获取任意节点的全部子孙节点。适合树结构不庞大,且不会频繁修改插入的场景,比如栏目分类,部门组织什么的
banmuyutian
2022-06-28 14:25:13 +08:00
闭包表修改的时候麻烦点,查询的时候比较灵活
kkkiio
2022-06-28 14:52:12 +08:00
@tabris17 “一条语句”强调的是性能吗?感觉可以做个测试对比一下 Nested Set Model 和 Recursive CTE 的性能,个人猜测如果树结构不庞大,CTE 性能也不差
Vaspike
2022-06-28 15:31:51 +08:00
存进数据库的是完全展开的树信息,一行只有当前节点的父节点和自己节点的 id(自己节点的其他信息)
全量查,查出来后递归渲染这棵树
issakchill
2022-06-28 15:53:50 +08:00
弄个路径字段 每次插入更新路径
m16FJ06l0m6I2amP
2022-06-28 16:07:30 +08:00
如果需要移动节点路径的话真没啥万全法。
linuxyz
2022-06-28 16:57:15 +08:00
LLaMA2
2022-06-28 17:07:45 +08:00
https://typeorm.bootcss.com/tree-entities
看看 ORM 中怎么做的,然后自己取舍
linuxyz
2022-06-28 18:27:35 +08:00
@linuxyz 從首頁跳過來的,沒注意是在 MySQL 版, 看起來是樓主是問比較老版本的 MySQL 了, 看看能不能把數據導入内存重建 Tree ?
wxf666
2022-06-28 18:35:28 +08:00
@n0trace 邻接表类型,移动节点,不是一条 update xxx set parent_id = ? 即可吗
someonedeng
2022-06-28 18:54:22 +08:00
冗余 path

a,b,c,d

select a,b*
wxf666
2022-06-28 19:04:41 +08:00
@kkkiio 树结构庞大,CTE 比不过原因是啥?查 parent_id 索引难命中缓存?

那加个 root_id 字段,索引 (root_id, parent_id),是不是同一棵树的索引都尽量集中到一块儿去就好了
Nooooobycat
2022-06-28 19:08:26 +08:00
这种情况下,能否考虑一下图数据库?
pank
2022-07-15 10:21:28 +08:00
@Nooooobycat ,图数据库肯定可以做到,我之前写过一个 demo 专门测过,把部门和人全部导入到了 neo4j, 查询部门及子部门下所有用户,实测在本地性能并不高。也有可能是我本地电脑性能不够好。后来领导担心这个没人用过,而且有杀鸡用牛刀的嫌疑,就放弃这个方案了。这么多方案综合考虑下来,还是左右值编码的方案最简单,但是它也不完美,查询一批部门下的用户的时候,就需要用 or

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/862587

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX