V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
wxy1991
V2EX  ›  MySQL

mysql 树形结构存储查询方案

  •  
  •   wxy1991 · 2022-01-21 17:02:06 +08:00 · 4113 次点击
    这是一个创建于 1068 天前的主题,其中的信息可能已经有所发展或是发生改变。
    大家常见的树形结构是如何设计存储的,查询,修改的时候方便吗?
    之前我一直使用的是 id ,name ,parent_id 的方案,但是后来发现查询子节点的时候特别不方便,哪怕最优的方案也需要查询 n(树的层数)次,不知道大家有没有什么好的查询策略或者数据存储方案
    18 条回复    2022-01-24 14:57:05 +08:00
    hidemyself
        1
    hidemyself  
       2022-01-21 17:04:33 +08:00
    闭包表?
    zxabition
        2
    zxabition  
       2022-01-21 17:07:32 +08:00
    加个 path 字段?,然后维护好这个字段?
    这种:
    id code path
    1348900982112034817 100101 [0],[1348900982044925953]
    1348900982195920898 10010101 [0],[1348900982044925953],[1348900982112034817]
    1348900982275612674 10010102 [0],[1348900982044925953],[1348900982112034817]
    1348900982497910786 100102 [0],[1348900982044925953]
    1348900982565019649 10010201 [0],[1348900982044925953],[1348900982497910786]
    1348900982632128513 10010202 [0],[1348900982044925953],[1348900982497910786]
    1348900982699237377 100103 [0],[1348900982044925953]
    Bronya
        3
    Bronya  
       2022-01-21 17:14:38 +08:00
    用 Path Enumerations 方式比较方便查子节点,可以看看这个:

    https://www.zhihu.com/question/20417447/answer/15078011
    815979670
        4
    815979670  
       2022-01-21 17:22:31 +08:00   ❤️ 1
    我上个月刚写了一篇文章:《 MySQL Tree 存储方案 》 https://www.dbkuaizi.com/archives/142.html
    wxy1991
        5
    wxy1991  
    OP
       2022-01-21 17:23:47 +08:00
    多谢楼上的各位大佬,我参考下看看我们项目适合哪种
    hteen
        6
    hteen  
       2022-01-21 17:36:31 +08:00
    数据少 闭包表
    数据多 path 字段+fullindex
    wxy1991
        7
    wxy1991  
    OP
       2022-01-21 17:42:55 +08:00
    @hteen 数据多 path 字段会超长吧
    fmumu
        8
    fmumu  
       2022-01-21 17:54:24 +08:00
    数据不多,就一次查出来,程序里递归处理
    数据多就懒加载呗
    要不就和行政区划一样,上级 id 做下级的前缀
    mx1700
        9
    mx1700  
       2022-01-21 19:07:39 +08:00 via Android
    Mysql 8 支持递归查询,如果深度不深效率还可以
    golangLover
        10
    golangLover  
       2022-01-21 19:10:26 +08:00 via Android
    用 json, 存 string
    rabbbit
        11
    rabbbit  
       2022-01-21 19:23:43 +08:00
    搭车问个问题:
    这种 parentId 存树形结构的怎么查询比较快?
    树不限深度, 总节点数在 1 万个左右.直接写 SQL 还是全查出来然后用 Java 处理,
    rabbbit
        12
    rabbbit  
       2022-01-21 19:25:17 +08:00
    说错了,不是 1 万个节点.是查出来的数据量有 1 万条左右.
    pelloz
        13
    pelloz  
       2022-01-21 19:28:25 +08:00
    一般来说,数据不会有很多层,那么上级 id 做下级的前缀其实很可行
    garfeildma
        14
    garfeildma  
       2022-01-21 20:47:07 +08:00
    推荐《 SQL 反模式》,里边专门一章讲这个问题的
    RuLaiFo
        15
    RuLaiFo  
       2022-01-22 09:49:34 +08:00 via Android
    可以去了解一下 mptt 查询很快,但是添加删除会更新整个树,根据业务看你的树有多大(没测试过性能极限值),几百个节点应该还是可以的。
    Akiya
        16
    Akiya  
       2022-01-22 12:40:49 +08:00 via iPhone
    图数据库了解一下
    Akiya
        17
    Akiya  
       2022-01-22 12:45:01 +08:00 via iPhone
    @rabbbit 一万条直接全读出来在内存里面处理就行了
    wxy1991
        18
    wxy1991  
    OP
       2022-01-24 14:57:05 +08:00
    @rabbbit 你是要查询整个树,还是查询某个节点的父子节点,如果查询整个树,建议一次全查出来,用代码计算树的结构,后续可以存到 redis 中,只要树结构发生变更时更新下 redis 数据就行。如果是查询父子节点,那只能一层一层递归查询了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4961 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 01:12 · PVG 09:12 · LAX 17:12 · JFK 20:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.