数据库触发器 / 参照完整性和内存缓存

5
你是否看到数据库触发器/引用完整性规则被用于改变数据库中的实际数据(改变表x中的行w会导致表z中的行y发生变化)?
如果是,这如何与内存缓存(memcache和其他类似工具)日益增长的流行相结合?毕竟,这些操作发生在数据库内部,但缓存系统必须意识到它们以便反映正确的状态(或至少使可能更改的状态无效)。我很难相信回调函数会为这种情况实现。
有没有人对这样的设置有真实的经验/考虑过这样的设置并放弃了(你选择了哪个方案?如果是缓存,你如何执行完整性?)
1个回答

5

简单回答:

  • 参照完整性是必须的
  • 缓存是一个有资格的必须品
  • 触发器是一种很好的东西

更长的回答:

自1993年以来,我一直在关系型数据库上开发应用程序(Dec RDB,之前是在平面文件系统上),由于触发器可以“删除您不想删除的内容”,因此许多开发人员从未喜欢过触发器。参照完整性也经常被开发人员所反对,因为在第三正规形式下具有适当的参照完整性的数据库很难在几分钟内组合在一起。

尽管许多系统可以在没有触发器的情况下运行,但我认为没有参照完整性,任何应用程序数据库都无法舒适地生存。看看这个问题的标签,这个网站背后的数据库将拥有一个标签表(可能称为“Tag”)和一个问题表(可能称为“Question”)。 “Question”将具有对Tag表主键的外键,但由于问题可以有多个标签,标签也可以有多个问题,因此我猜测关系如下:

   Question
   (TagId)         1 | Database triggers / referential integrity and in-memory caching
      |  
    -----
    | | |
  QuestionTag
 (QuestionId)       1 | 1  ... 1 | 2  ... 1 | 3 ...
    (TagId)
    | | |
    -----
      |
     Tag            1 | database ... 2 | referential-integrity ... 3 | triggers ...
   (TagId)

这种引用完整性是任何可靠应用程序的基础,不容许妥协。你可以看到它如何增加应用程序设计的可信度和对其长期性的信心。
SO上的缓存可能已经开启了标签等功能(虽然不能保证),所以假设标签已经被缓存在内存中,并且您拥有足够的声望来允许向SO添加标签。您添加了标签,它可能会立即持久化到数据库中,但缓存是否会被更新呢?
这是一个权衡。如果不知道您的新标签,该站点能否生存?如果可以,那么需要多久?从用户添加到数据库中,再到其他用户可用并被使用,标签的生命周期是什么?缓存将根据开发团队制定的规则进行重建,而这个规则本质上是一种权衡,以便任何新标签都可以在不减慢应用程序速度的情况下快速可用。
触发器可以强制执行引用完整性,例如您添加的标签是“垃圾”,但管理员看到它时,已经有三个问题被标记为“垃圾”。管理员随后决定删除“垃圾”标签,但标记为它的问题怎么办?如果在“标签”表上有一个触发器,在删除时触发,它可以绕过“问题”表并删除所有对“垃圾”的引用。有很多这种方法的替代方案,其中许多是编程解决方法,但是否有更简洁的解决方案呢?
在过去的20年里,我参与了许多网站的开发,好的网站都使用引用完整性和越来越多的缓存。更改数据的触发器(本质上只是事件驱动的存储过程)并不受欢迎,并且越来越被误解,但仍然有其作用。
缓存和引用完整性不能被视为二选一,开发团队必须设计应用程序,以便两者都可以被纳入其中。

哇,一个深思熟虑的答案。然而,我仍然不明白现成缓存解决方案如何与“幕后”更新配合工作。每次对数据库引用完整性规则的更改都可能在缓存解决方案中创建一个巨大的漏洞。这些要求(快速缓存,一致执行引用完整性)如何协调? - Ran Biron
缓存“现成的”是一个配置问题,数据库更改被批处理,并且缓存本身知道数据库中的引用完整性约束。这意味着即使缓存数据也会拒绝破坏引用完整性的尝试。 - amelvin
真的吗?现成的缓存解决方案知道引用完整性吗?我在流行的缓存系统中找不到任何关于这个的参考资料 - 你能指导我一个知道的吗? - Ran Biron
你希望使用哪种现成的缓存系统? - amelvin
实际上,我希望创建一个依赖于现有数据并且是“实时”的东西(在数据更改时更新),因此我正在探索如何使用缓存来实现它。 - Ran Biron

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