使用嵌套集模型时跟踪更改

时间:2014-08-04 22:43:03

标签: mysql sql hierarchy nested-sets mysql-5.6

我正在考虑将我的组织heiarchy转换为我从here收集的嵌套集模型。我把它放在SqlFiddle中,希望有助于形象化。什么是简化的,有/将会有更多的水平,但这应该有助于解释。

在我的组织中,教练经常改变。每支球队每年平均会有2-3名新教练,教练会在组织中上下移动,存在很大的波动性。在教练之上,一切都会保持不变,但可以/将会发生变化。

使用我们的旧模型(邻接列表),我们可以通过触发器填充的其他表来跟踪更改,但是这个新模型将有新的需求来跟踪。我发现我们需要跟踪rgtlft号码,以及删除的日期和添加的日期。此外,我发现在任何给定日期或日期范围内“重建”树时会出现一些复杂情况。

我考虑的两个选项是:

首先,创建一个表来跟踪更改,跟踪rgtlft列以及日期值,然后从树中删除教练/团队。我认为这种方式很难“重建”历史查看。

其次,将“已删除”的教练/团队留在树中,向树中添加一个bool,指示教练/组织是否仍在使用中,并添加仅跟踪日期和前一个父级的更改表。这样可以使历史查找变得更容易(我看到日期范围方面很难),但是这棵树会变得杂乱无章。

哪个选项更好?有没有我错过的选项?

我们会经常使用历史查询,但对于一次性查询,所有汇总数据将在第二天按组织级别进行编译和存储。

1 个答案:

答案 0 :(得分:0)

实际上并不清楚您正在进行的跟踪和历史查询。但是我对你的问题有一个通用的答案。

嵌套集和邻接列表模型不是互斥的。这意味着您可以在表中使用它们,例如使用以下模式。

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;

使用此架构,可以轻松查询节点的子树,并使用lr对其进行计数。同时,使用node_idparent_id编写处理直接上升和后代节点的查询很容易。

因此,我建议您使用嵌套集标记扩展表,而不会消除父引用。因此,您可以继续使用现有的跟踪逻辑,并具有嵌套集模型的优势。