【发布时间】:2008-08-21 16:20:12
【问题描述】:
我有一个在 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 我知道这“有点过火”,但我这样做是为了好玩(有趣:动词,通过这样做找到不可能的事情。:-)
【问题讨论】:
标签: mysql algorithm data-structures invariants