我有一个在 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
叶节点上的值。可以假设叶节点将保留为叶节点,内部节点将保留为内部节点,整个事物将保留为一棵适当的树。
我曾经有过的一些想法:
- 完全失效,在任何更新后,重新计算一切(嗯......不)
- 在 items 表上设置触发器以更新已更新的任何行的父级
- 这将是递归的(更新触发更新,触发更新,...)
- 不起作用,MySQL 无法更新启动触发器的表
- 设置触发器以安排更新任何已更新行的父级
- 这将是迭代的(从计划中获取一个项目,处理它以安排更多项目)
- 这是什么开始?信任客户端代码来做对吗?
- 一个优点是,如果更新正确排序,则需要计算机计算的总和更少。但这种排序本身就是一个复杂的问题。
一个理想的解决方案将推广到其他“聚合不变量”
FWIW我知道这“有点过火”,但我这样做是为了好玩(有趣:动词,通过这样做找到不可能的事情。:-)