【发布时间】:2011-02-24 09:21:37
【问题描述】:
我在related question 中发布了一些关于 MVC 缓存的 cmets,但出现了一些关于实际实现的问题。如何实现模型级缓存,无需开发人员手动缓存即可透明地工作,但仍保持高效?
我会保留我的缓存 责任坚定地在 模型。它不是控制器的 或查看模型所在的业务 获取数据。他们关心的只是 当请求数据时,数据是 提供 - 这就是 MVC 范式应该可以工作。
(来源:Post by Jarrod)
我持怀疑态度的原因是,除非有真正的需要,否则通常不应进行缓存,也不应针对搜索结果之类的内容进行缓存。因此,模型本身必须以某种方式知道向它发出的 SELECT 语句是否值得缓存。模型是否必须非常聪明,和/或存储在很长一段时间内最常查询的内容的统计数据才能准确地做出决定?难道这一切的开销不会使缓存毫无用处吗?
您将如何从另一个查询(或更准确地说,从另一个结果集中的一个结果集)中唯一地标识一个查询?如果您使用准备好的语句,仅根据用户输入更改参数怎么办?
另一张海报这样说:
我建议使用 md5 哈希 您的查询与序列化的 输入参数的版本。
微不足道的碰撞几率值得担心吗?
从概念上讲,在模型中缓存对我来说似乎是一个好主意,但它似乎在实用性上,并且由于缓存的性质,开发人员应该直接控制它并将其明确编码到控制器逻辑中。
赏金更新
我确实使用了一个非常轻量级的 ORM,有点类似于 ActiveRecord,但它能够执行复杂的连接和子查询,而不会出现n^2 的问题。我自己构建的,所以它很灵活,在关系或列名方面没有限制,我只是想了解我应该如何实现缓存机制。
根据乐于助人的人的建议,我将查询的哈希(可能是 md5)与其参数列表连接起来,并将其用作该特定数据存储的键。我应该在需要缓存的模型类中单独实现缓存,还是应该作为 ORM 层的一部分?
我怎么知道什么时候应该失效?我是否必须手动解析 UPDATE/DELETE/INSERT 查询和子参数以找出正在修改的记录?或者更糟的是,每当修改数据时执行额外的查询以跟踪哪些内容发生了变化以及哪些内容应该失效?
我会将赏金奖励给任何能给我一个清晰的概念解释的人(无论这是否真的有必要/有效地以透明方式完成),如果是的话,有一些模型缓存的实现细节。如果这有助于缩小您的注意力,我正在使用 PHP 和 MySQL。
【问题讨论】:
-
(又迟到了。)我对你从谈论模型缓存到查询缓存的转变感到困惑。根据您的模型结构,模型缓存可以在“写入”时很好地处理 失效很少见。然后,您将讨论基于查询参数的缓存。这似乎比模型缓存高出一步。您是在寻找两者还是其中之一(如果是,是哪一个)?两者都是可行的,但有不同的答案。我很乐意提供帮助,但想先解决这个问题。
-
别担心,你没有迟到。这就是赏金的用途。根据我(可能被误导)的理解,模型缓存和查询缓存必须完全相关,因为对象关系阻抗不匹配。缓存模型没有完全意义,因为您只会缓存您必须跟踪的单个记录/对象,查询缓存是因为我将在中等规模的数据集上进行操作。但不知何故,你必须通过存储模型集来做到这两点。 (??)
-
好的,很好。大多数情况下,我们缓存在小(模型)端。缓存模型减轻了单一模型查找和数据库/行级写入/读取冲突的负担。由于极端变化,我们通常不会在查询端缓存。我们已经对我们的数据集进行了反规范化,以适应我们用来从缓存加载(以及扩展集合)的快速 ID 查找(和公共列)。当我们缓存聚合内容(跨模型、查询等)时,我们有唯一的 ID(每个查询的哈希值,很好)以及用于失效的辅助标签(模型 ID)。我们使用 Zend_Cache 来管理所有这些。
标签: php database model-view-controller caching