Performance PostgreSQL中的计数器缓存列

Performance PostgreSQL中的计数器缓存列,performance,postgresql,caching,Performance,Postgresql,Caching,在我的数据库中,我有任务和注释表。每个任务都有许多注释 我想创建将由PostgreSQL自动更新的任务.comments\u count列,这样我可以在选择所有任务时在O(1)时间内获得注释\u count(并按其排序/筛选) 我知道有一些特定于语言的解决方案,比如ActiveRecord,但我不想使用它们(我发现它们很脆弱)。我希望PostgreSQL能够处理这些计数器缓存 我也知道PostgreSQL支持触发器,但它们很难编写和使用(不是一个可靠的解决方案) 理想情况下,它应该是一个Post

在我的数据库中,我有
任务
注释
表。每个任务都有许多注释

我想创建将由PostgreSQL自动更新的
任务.comments\u count
列,这样我可以在选择所有任务时在O(1)时间内获得
注释\u count
(并按其排序/筛选)

我知道有一些特定于语言的解决方案,比如ActiveRecord,但我不想使用它们(我发现它们很脆弱)。我希望PostgreSQL能够处理这些计数器缓存

我也知道PostgreSQL支持触发器,但它们很难编写和使用(不是一个可靠的解决方案)

理想情况下,它应该是一个PostgreSQL扩展或一些我不知道的本机特性


延迟计算此类计数器将是一个巨大的好处。

如果您希望Postgres根据插入/更新/删除自动执行某些操作,即,如果您希望此操作触发其他操作,则需要编写触发器

这很简单。很简单,我怀疑是否有人会费心创建一个扩展(更不用说语言特性)来为您省事。而且它肯定比引擎盖下的ActiveRecord更简单(正如您所指出的,更安全)

通常只需要这样做(我还没有对此进行测试,所以您可能希望这样做……):

如果你想让它是密封的,你需要一个额外的触发器来触发
注释上的
截断
s;麻烦值不值得由你决定

要处理对正在引用的
tasks.id
值的更新(通过延迟约束或更新
操作时的
),则需要更多,但这种情况并不常见

如果您的客户端库/ORM足够幼稚,可以发送每个
UPDATE
语句中的每个字段,那么您可能需要一个单独的
UPDATE
触发器,该触发器仅在值实际更改时触发:

CREATE TRIGGER maintain_comment_count_update
AFTER UPDATE OF task_id ON comments
FOR EACH ROW
WHEN (old.task_id IS DISTINCT FROM new.task_id)
EXECUTE PROCEDURE maintain_comment_count_trg();

为什么不计算查询中每个任务的注释数,而不必在数据库表中维护该数字?另一个选项可能是使用触发器并使用添加或删除的每个新注释更新任务。注释计数。@ydaetskcoR我提供了一个简单易懂的示例。在实际应用中,有多个计数器,并且需要通过它们进行高级排序/过滤/分组,所以在查询中计算关联记录并不是一个有效的解决方案。假设在表中存储计数器缓存是客户机的要求。我以前没有遇到过“计数器缓存”,但是,如前所述,如果要将性能影响转移到写入而不是读取,我可能会在插入/删除注释时使用触发器来实现这一点。它也是一个可移植的解决方案。您所说的“[触发器]很难编写和使用(不是一个固态解决方案)”是什么意思?触发器并不比其他任何东西更难编写或使用。你说的“懒惰计算”是什么意思?你好,尼克,你能解释一下
的必要性吗(旧的.task\u id和新的.task\u id不同)
@lessless:我更新了我的答案,以便更好地解释这个问题。谢谢!将CC下推到数据库级别是一个非常非常明智的选项:)不起作用:(它说函数在没有返回的情况下完成了它需要一个声明和返回
CREATE TRIGGER maintain_comment_count_update
AFTER UPDATE OF task_id ON comments
FOR EACH ROW
WHEN (old.task_id IS DISTINCT FROM new.task_id)
EXECUTE PROCEDURE maintain_comment_count_trg();