更新闭包表的最佳方法是什么?

5
我是一位有用的助手,可以为您翻译文本。以下是需要翻译的内容:

我有一个使用邻接表方法(表格A)关联记录的表格,以及另一个使用闭包表关联相同记录的表格(表格B)。它们都捕获了相同的图形,因此它们都需要保持同步。

问题是,更新闭包表的最佳方法是什么?

在我看来,有三种选择:

  1. 触发器。在对 A 进行 INSERT/UPDATE/DELETE 时,运行一个计算新闭包的存储过程。缺点:A 的更改将导致长时间同步的(锁定?)操作;可能会出现死锁(?)。
  2. 应用程序代码。将 A 中的更改限制为添加/更新/删除方法(例如仓储模式),并重载它们以调用计算新闭包的存储过程。缺点:需要额外的往返数据库的过程;如果另一个线程同时以相反的方式修改了 AB,可能会出现完整性问题;如果另一个应用程序决定修改 A 而不是 B,也可能会出现完整性问题。
  3. 后台更新程序。编写一个连续查找 A 更新并进行相应更新到闭包表的辅助进程。缺点:复杂(需要编写和管理额外服务);无同步窗口。

即使没有“最佳”选项,任何关于权衡的想法都将不胜感激!

1个回答

4
如果您的层次结构与我处理过的大多数层次结构一样静态,那么我可能会选择触发器。这实际上取决于更新频率和读取负载。

谢谢您的评论!我很想听听有关更新频率和负载如何影响我的选择,特别是与前两个选项相关的内容。顺便说一下,我预计表A会相当频繁地更改:每秒钟几次,变化深度均匀分布(即一些接近叶子,一些接近根部,一些在中间)。 - ladenedge
@ladenedge 这不是很静态。这是什么层次结构?绝大多数读取是否都通过闭包表进行,写入则通过邻接表进行? - Cade Roux
@Cade Roux:这是一个基本的分层文件系统。对闭包表的写入仅通过我们选择的任何同步方法进行,但两个表在树方面都有相当大的读取量。如果有帮助的话,我们可以将与树相关的读取从邻接表移动到闭包表中..? - ladenedge
2
@ladenedge 我越想越觉得,你只需要优化触发器中的闭包编辑,因为如果闭包正在改变,你确实希望读者被阻塞。如果你可以允许读者有点不同步,你可以对整个闭包进行快照构建,开始阅读旧版本闭包的读者在新版本闭包被组装时不会受到影响。然后可以在单独的过程中删除闭包表中的旧版本。 - Cade Roux
@Cade Roux:优化触发器似乎是一个不错的开始。同时,也许我会多了解一下快照更新。感谢您的时间! - ladenedge
2
@ladenedge 像是使用'INSERT INTO Closure (RevisionId, ...)'进行追加,使用'SELECT * FROM Closure WHERE RevisionId = (SELECT MAX(RevisionId) FROM Closure)'进行选择,每小时使用'DELETE FROM Closure WHERE RevisionId < (SELECT MAX(RevisionId) FROM Closure)'进行清除。 - Cade Roux

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接