我正在考虑将我的组织层次结构切换为我从 here 收集的嵌套集模型。 。我把它放在 SqlFiddle 中希望能帮助想象它。那里的内容已经简化,有/将会有更多级别,但这应该适合帮助解释。
在我的组织中,教练经常更换。每支球队平均每年会有2-3名新教练,教练在组织中会上下变动,存在很大的波动性。在教练之上,一切几乎都会保持不变,但变化可能/将会发生。
使用我们的旧模型(邻接列表),我们可以通过触发器填充的其他表来跟踪更改,但这个新模型将有新的跟踪要求。我发现我们需要跟踪 rgt
和 lft
数字,以及删除日期和添加日期。此外,我发现在任何给定日期或日期范围“重建”树时会出现一些复杂情况。
我考虑过的两个选择是:
首先,创建一个表来跟踪更改,跟踪 rgt
和 lft
列以及日期值,然后从树中删除教练/团队。我认为这种方式很难“重建”历史查找。
其次,将“已删除”的教练/团队保留在树中,向树中添加一个 bool 值,指示教练/组织是否仍在使用中,并添加一个仅跟踪日期和上一个父级的更改表。这将使历史查找变得更容易(我认为日期范围方面很困难),但会使树变得困惑和膨胀。
哪个选项会更好?我是否缺少一个选项?
我们会经常使用历史查询,但对于一次性查询,所有聚合数据将在第二天按组织级别进行编译和存储。
最佳答案
实际上并不清楚您具体在做什么跟踪和历史查找。不过,我对你的问题有一个一般性的答案。
嵌套集和邻接表模型并不相互排斥。这意味着您可以在表中使用两者,如以下架构所示。
CREATE TABLE `node` (
`node_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`parent_id` int(10) unsigned DEFAULT NULL,
`l` int(10) unsigned NOT NULL,
`r` int(10) unsigned NOT NULL,
`name` varchar(32) NOT NULL,
PRIMARY KEY (`node_id`),
KEY `l` (`l`),
KEY `r` (`r`),
KEY `parent_id` (`parent_id`),
CONSTRAINT `node_has_node` FOREIGN KEY (`parent_id`)
REFERENCES `node` (`node_id`)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=InnoDB;
使用此模式,可以轻松查询子树中的节点并使用 l
和 r
对它们进行计数。同时,使用 node_id
和 parent_id
编写处理直接上升和下降节点的查询也很容易。
因此,我建议您使用嵌套集标记来扩展表格,而无需删除父引用。因此您可以继续使用现有的跟踪逻辑,并具有嵌套集模型的优点。
关于mysql - 使用嵌套集模型时跟踪更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25128709/