更新闭包表的最佳方法是啥?
Posted
技术标签:
【中文标题】更新闭包表的最佳方法是啥?【英文标题】:What's the best way to update a closure table?更新闭包表的最佳方法是什么? 【发布时间】:2011-04-08 23:10:10 【问题描述】:我有一个使用adjacency list 方法关联记录的表(表A),还有另一个使用closure table 关联相同记录的表(表B) .它们都捕获相同的图表,因此它们都需要保持同步。
问题是,更新闭包表的最佳方法是什么?
在我看来,有三种选择:
-
触发器。在 A 的 INSERT/UPDATE/DELETE 上,运行一个计算新闭包的 sproc。 缺点:对A的更改会导致长时间的同步(锁定?)操作;可能的死锁 (?)。
应用程序代码。将 A 中的更改缩小到添加/更新/删除方法(例如存储库模式),并通过调用计算新闭包的 sproc 来重载它们。 缺点:额外往返数据库;如果另一个thead同时以相反的方式修改A或B,可能会出现完整性问题;例如,如果另一个应用程序决定修改 A 而不是 B,则可能存在完整性问题。
后台更新程序。编写一个辅助进程,不断寻找 A 的更新并对闭包表进行相应的更新。 缺点:复杂(编写和管理的额外服务);没有同步的窗口。
即使没有“最佳”选项,任何关于权衡的想法都将不胜感激!
【问题讨论】:
【参考方案1】:如果您的层次结构像我处理过的大多数情况一样大部分是静态的,我可能会使用触发器。真的取决于更新频率和读取负载。
【讨论】:
感谢您的评论!我很想听到更多关于更新频率和负载应该如何影响我的选择的信息,尤其是关于前两个选项。 FWIW,我希望表 A 会相当频繁地更改:比如说每秒几次,变化深度均匀分布(即一些靠近叶子,一些靠近根部,一些在中间)。 @ladenedge 这不是很静态。这是一种什么样的层次结构,大多数都是通过闭包表读取并写入邻接表? @Cade Roux:这是一个基本的分层文件系统。对闭包表的写入仅通过我们选择的任何同步方法发生,但是相对于树,两个表都被大量读取。如果有帮助,我们可能会将与树相关的读取从邻接表移动到闭包表..? @ladenedge 我想的越多,我认为你只需要优化触发器中的闭包编辑,因为如果闭包发生变化,你确实希望读者被阻止。如果您可以让读者有点不同步,您可以对整个闭包进行快照构建,并且开始阅读闭包旧版本的读者在组装新版本时不会受到影响。然后可以在单独的过程中删除关闭表中的旧修订。 @ladenedge 天真,例如附加 'INSERT INTO Closure (RevisionId, ...)',选择 'SELECT * FROM Closure WHERE RevisionId = (SELECT MAX(RevisionId) FROM Closure)',清除每小时,比如说,'DELETE FROM Closure WHERE RevisionId以上是关于更新闭包表的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章