您是否看到数据库触发器/引用完整性规则以更改数据库中实际数据的方式使用(更改表 x 中的行 w 会导致表 z 中的行 y 发生更改)?
如果是,这与日益流行的内存缓存(memcache 和 friend )有什么关系?毕竟,这些操作发生在数据库内部,但缓存系统必须知道它们才能反射(reflect)正确的状态(或至少使可能更改的状态无效)。我很难相信回调是针对这种情况实现的。
有没有人有这样的设置的真实经验/考虑这样的设置并放弃它的真实经验(你走哪条路?如果缓存,你如何强制完整性?)
最佳答案
简单答案:
- 参照完整性是必须具备的
- 缓存是合格的必须品
- 触发器很不错
更长的答案
自 1993 年以来,我一直在关系数据库上开发应用程序(自从你问起是 Dec RDB,在那之前是在平面文件系统上)并且触发器从未受到许多开发人员的欢迎,因为它们可以“删除你不想要的东西”删除'。参照完整性也经常遭到开发人员的反对,因为具有适当参照完整性的第三范式数据库很难在几分钟内融合在一起。
缓存通常也被认为“很难”正确执行,尽管我不确定原因。
虽然许多系统可以在没有触发器的情况下生存,但我要说的是,没有引用完整性,任何应用程序数据库都无法轻松生存。查看这个问题的标签,这个站点后面的数据库将有一个标签表(可能称为“标签”)和问题(可能称为“问题”)。 '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 年里,我在很多网站上工作过,好的网站使用参照完整性和越来越多的缓存。匿名更改数据的触发器(它们从根本上讲都是事件驱动的存储过程)并不流行,而且越来越多地被误解,但仍然发挥着作用。
缓存和引用完整性不能被视为非此即彼的选择 - 开发团队必须设计应用程序以便将两者结合起来。
关于数据库触发器/参照完整性和内存缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2450870/