Odoo中有很多层级关系的数据,比如:产品的分类,多层级的BOM,项目中的任务及其子任务等等。在数据库中快速存储更新这些有层级关系的数据,并能实现高效的查询是一个颇具挑战的任务。
Odoo一直以来采用的方法称为:MPTT (Modified Preorder Tree Traversal)。 比如对于下面层级树,在数据库中每个节点都记录了和信息:
这样的存储结构对于查询某节点的子孙节点或是祖先节点很方便。比如想要找出所有的子节点,只要查询, 位于8和19之间的节点就可以了。即:。效率非常高。
但是这样的数据结构对于插入,删除,移动节点等的操作是很低效的,要重算其他部分或全部节点的parent_left, parent_right值。具体算法请参照同事的博文:ODOO优化层级关系查询效率的方法
Odoo最近的这个提交意味着Odoo V12中将不再采用MPTT的算法来处理层级数据了,而是引入了一种新的算法:Materialized Path
这种新算法的原理很简单,就是在层级数据中增加一个字段:,在这个字段中记录层级路径:
所以一个的查询就变成了一个类似这样的字符串拼接的条件查询了。在Odoo的实现中主要在类中引入了四个以起始的函数:
: 用以一次性更新所有的字段的值,目前只有在测试用例中被调用过
: 在对象的方法中被调用,用以在创建记录时自动计算字段的值
: 用以返回`self`中那些需要更新值的记录, 在方法中被调用
: 在上面的函数所返回的记录上更新其值,在方法中被调用
有了的值,Odoo就可以很简单的实现, 这样的查询条件:
expression.py - child_of
expression.py - parent_of
Odoo使用Materialized Path算法来管理层级数据,使得对于层级数据的创建,更新,查询的效率有了较平衡的提高。
领取专属 10元无门槛券
私享最新 技术干货