she*_*run 11 postgresql performance caching
在我的数据库中我有tasks和comments表.每个任务都有很多评论.
我想创建tasks.comments_count一个可以由PostgreSQL自动更新的列,这样我就可以comments_count在选择所有任务时在O(1)时间内获取(并按其排序/过滤).
我知道有一些特定于语言的解决方案,比如ActiveRecord的计数器缓存,但我不想使用它们(我觉得它们很脆弱).我希望PostgreSQL能够处理这样的计数器缓存.
我也知道PostgreSQL支持触发器,但它们很难编写和使用(不是一个可靠的解决方案)
理想情况下,它将是PostgreSQL扩展或我不知道的一些本机功能.
懒惰计算这样的计数器将是一个很大的好处.
Nic*_*nes 18
如果你希望Postgres在插入/更新/删除的基础上自动执行某些操作 - 即如果你希望此操作触发其他操作 - 那么你需要编写一个触发器.
这很简单.很简单,我怀疑有人会打扰创建一个扩展(更不用说语言功能)来节省你的麻烦.而且,无论ActiveRecord在幕后发生什么,它肯定更简单(正如你所指出的那样,更安全).
这样的事情通常都需要(我没有测试过,所以你可能想要这样做......):
CREATE FUNCTION maintain_comment_count_trg() RETURNS TRIGGER AS
$$
BEGIN
IF TG_OP IN ('UPDATE', 'DELETE') THEN
UPDATE tasks SET comment_count = comment_count - 1 WHERE id = old.task_id;
END IF;
IF TG_OP IN ('INSERT', 'UPDATE') THEN
UPDATE tasks SET comment_count = comment_count + 1 WHERE id = new.task_id;
END IF;
RETURN NULL;
END
$$
LANGUAGE plpgsql;
CREATE TRIGGER maintain_comment_count
AFTER INSERT OR UPDATE OF task_id OR DELETE ON comments
FOR EACH ROW
EXECUTE PROCEDURE maintain_comment_count_trg();
Run Code Online (Sandbox Code Playgroud)
如果你希望它不透气,你需要额外的触发TRUNCATES上comments; 是否值得麻烦取决于你.
要处理tasks.id正在引用的值的更新(通过延迟约束或ON UPDATE操作),那么还有更多内容,但这是一种不常见的情况.
如果您的客户端库/ 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();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1615 次 |
| 最近记录: |