经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » MongoDB » 查看文章
利用“海底捞算法”在MongoDB中优雅地存储一棵树
来源:cnblogs  作者:drinkjava2  时间:2018/10/26 10:05:31  对本文有异议

目前常见的树形结构数据库存储方案有以下四种,但是在处理无限深度、海量数据的树结构时,都存在一些问题:
1)Adjacency List(邻接表):每个节点仅记录父节点主键。优点是简单,缺点是访问子树需要递归遍历,对数据库压力大(即使是支持递归SQL的数据库)。
2)Path Enumerations( 路径枚举):用一个字符串记录当前节点所在路径。优点是查询方便,缺点是占用空间大,查询需要使用like模糊方法,效率低,插入新记录时要手工更改此节点以下所有路径,维护不便。
3)Closure Table(闭包表):专门一张表维护Path,缺点是占用空间大,操作不直观。
4)Nested Sets (嵌套集):记录左值和右值,优点是查询子树无需递归,缺点是非常复杂、难操作。

本文介绍的方案原理详见"基于前序遍历的无递归的树形结构的数据库表设计" ,在这里我给它名叫“海底捞算法”,这个比较形象,因为它要求插入一行EndTag在表格的底部(具有最大行号)。本文是这种算法在MongoDB中的实现示例。

这个算法的优点是简单,支持无限深度树、查询子树时无需递归、删除节点和偶尔插入节点时可以做到无需修改其它记录(行号跳号设计),从以下示例代码中就可以看出这种方案的简洁性:

  1. Books
  2. |-Programning
  3. | |-Languages
  4. | |-Databases
  5. | | |-MongoDB
  6. | | | |-MongoTree
  7. | | |-dbm
  8. |-Arts
  9.  
  10. db.book.insert({ _id: Books”, line:1000,level:1} );
  11. db.book.insert({ _id: Programming”, line:2000,level:2} );
  12. db.book.insert({ _id: Languages”, line:3000,level:3} );
  13. db.book.insert({ _id: Databases”, line:4000,level:3} );
  14. db.book.insert({ _id: MongoDB”, line:5000,level:4} );
  15. db.book.insert({ _id: MongoTree”, line:6000,level:5} );
  16. db.book.insert({ _id: dbm”, line:7000,level:4} );
  17. db.book.insert({ _id: Arts”, line:8000,level:2} );
  18. db.book.insert({ _id: EndTag”, line:10000,level:0} );
  19.  
  20. //查询节点 “Databases”下的所有子节点:
  21. db.book.createIndex( {line:1});
  22. var node = db.book.findOne( { _id: Databases } );
  23. var next=db.book.findOne( { $and: [ {line: {$gt:node.line}}, {level:{$lte: node.level }}] } );
  24. db.book.find( {$and: [{line: { $gt: node.line }}, {line: { $lt: next.line }}] } );
  25.  
  26. //插入一个新节点,不需要对其它行号执行加1操作,因为这个示例中行号是跳号设计的,节点可以插入在两个行号的中间
  27. db.book.insert({ _id: MySql”, line:6500,level:5} );
  28.  
  29. //删除一个节点,真接删就可以了
  30. db.book.remove({ _id: Languages”} );
 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号