代码之家  ›  专栏  ›  技术社区  ›  Ran Biron

数据库触发器/引用完整性和内存缓存

  •  5
  • Ran Biron  · 技术社区  · 14 年前

    您是否看到数据库触发器/引用完整性规则的使用方式会更改数据库中的实际数据(更改表X中的W行会导致表Z中的Y行发生更改)?

    如果是,这与内存缓存(memcache和friends)越来越流行有什么联系?毕竟,这些操作发生在数据库内部,但是缓存系统必须知道它们,以便反映到正确的状态(或者至少使可能更改的状态无效)。我发现很难相信这种情况下会实施回调。

    有没有人有过这样一个设置的真实世界经验/考虑这样一个设置并放弃它的真实世界经验(你走的是哪条路?如果是缓存,如何强制实现完整性?)

    1 回复  |  直到 14 年前
        1
  •  5
  •   amelvin    14 年前

    简单回答:

    • 参照完整性是 必须有
    • 缓存是 合格的必须有
    • 触发器是 很高兴

    更长的答案

    我从1993年开始就在关系数据库上开发应用程序(从你问起就是DEC RDB,在那之前是在平面文件系统上),触发器从来没有受到很多开发人员的欢迎,因为它们可以“删除你不想删除的东西”。引用完整性也经常受到开发人员的反对,因为具有适当引用完整性的第三种正常形式的数据库在几分钟内很难合并在一起。

    缓存通常也被认为很难做对,尽管我不知道为什么。

    虽然许多系统没有触发器就可以生存,但如果没有引用完整性,任何应用程序数据库都无法舒适地生存。看看这个问题上的标签,这个站点后面的数据库将有一个标签表(可能称为“标签”)和问题表(可能称为“问题”)。问题'将在标记表中有一个主键的外键,但由于问题可以有许多标记,标记可以有许多问题,因此我想关系如下:

       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添加标记。您添加了标记,它很可能会立即被持久化到数据库中——但是缓存会被更新吗?

    你所拥有的是一种权衡。在不知道你的新标签的情况下,网站能生存吗?如果是的话还要多久?从根本上讲,标签的生命周期是什么,从用户添加到数据库中,其他用户可以使用,其他用户可以使用?缓存将根据开发团队制定的规则重新构建——而该规则本质上是一个折衷方案,以便任何新的标记都能足够快地可用,而不会降低应用程序的速度。

    触发器可以强制引用完整性,比如您添加的标记是“垃圾”,但是当管理员看到它时,三个问题被标记为“垃圾”。然后管理员决定删除“垃圾”标签——但是用它标记的问题呢?如果在“tag”表上有一个触发器在删除时被激发,那么它可以围绕“question”表运行,并删除对“垃圾”的所有引用。这种方法有很多替代方法,其中很多都是程序化的工作循环,但是是否有更清洁的替代方法?

    在过去的20年里,我在很多网站上工作过,好的网站使用引用完整性和不断增长的缓存。匿名更改数据的触发器(它们基本上都是事件驱动的存储过程)不受欢迎,也越来越被误解,但仍具有一定的作用。

    缓存和引用完整性不能视为二者之一,开发团队必须设计应用程序,以便两者都可以合并。