开发者社区> 问答> 正文

如何在MySQL数据库中维护递归不变式?

我有一棵树在MySQL数据库中编码为边:

CREATE TABLE items ( num INT, tot INT, PRIMARY KEY (num) ); CREATE TABLE tree ( orig INT, term INT FOREIGN KEY (orig,term) REFERENCES items (num,num) ) 对于树中的每片叶子,items.tot都是由某人设置的。对于内部节点,items.tot需要为其子节点的总和。重复运行以下查询将产生所需的结果。

UPDATE items SET tot = ( SELECT SUM(b.tot) FROM tree JOIN items AS b ON tree.term = b.num WHERE tree.orig=items.num) WHERE EXISTS (SELECT * FROM tree WHERE orig=items.num) (请注意,这实际上是行不通的,但这不重要)

假设数据库存在并且不变量已经满足。

问题是:

在满足此要求的同时更新数据库的最实用方法是什么?更新可能会tot在叶节点上移动节点或更改叶节点上的值。可以假设叶节点将保留为叶节点,内部节点将保留为内部节点,而整个对象将保留为适当的树。

我有一些想法:

完全无效,进行任何更新后,重新计算所有内容(嗯...否) 在项目表上设置触发器以更新任何已更新行的父级 这将是递归的(更新触发更新,触发更新...) 不起作用,MySQL无法更新启动触发器的表 设置触发器以计划对已更新的任何行的父级进行更新 这将是迭代的(从计划中获取一个项目,对其进行处理以计划更多项目) 是什么开始的呢?信任客户端代码以使其正确吗? 一个优点是,如果正确订购了更新,则需要的计算机数量更少。但是,排序本身就是一个复杂问题。 理想的解决方案将推广到其他“聚合不变式”

FWIW我知道这有点“过分”,但是我这样做很有趣(有趣:动词,通过这样做发现不可能。:-)

问题来源于stack overflow

展开
收起
保持可爱mmm 2019-11-15 15:39:50 537 0
1 条回答
写回答
取消 提交回答
  • 您遇到的问题很明显,SQL递归。您需要获取叶子的父对象的父对象并更新其总数(减去旧的并添加新的,或重新计算)。您需要某种形式的标识符来查看树的结构,并获取所有子节点的节点以及要更新的叶的父节点/路径的列表。

    此方法增加了恒定的空间(表中有2列-但您只需要一个表,否则可以稍后进行联接)。我之前玩过一种结构,该结构使用了使用“左”和“右”列(显然不是那些名称)的分层格式,分别通过前遍历和后遍历计算得出-不用担心这些不需要每次都重新计算。

    如果您不喜欢此方法作为答案,我将让您看一下在mysql中使用此方法的页面,而不是继续进行此讨论。但是,如果您喜欢,请发表/编辑,我将花一些时间进行澄清。

    2019-11-15 15:40:01
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
重新出发:阿里云数据库开源整体策略 立即下载
阿里云数据库案例集下载 立即下载
传统数据库上云三部曲 立即下载