sql - 通知的计数器功能未按预期工作
问题描述
我有通知表(category_id,user_id,seen)和计数器表:notifications_counter(user_id,未读)
当用户有新通知时(它插入到通知表中,see = false),他在通知计数器表中的 guid 的未读值必须增加。当用户将通知标记为已见 (notifications.seen=true) 时,它必须递减。
如果用户将 1 个通知标记为已见,则此方法有效。但是,如果他标记了许多(按 category_id),notifications_counter.unread 递减,但不是应有的 - 值仍然大于应有的值(例如,它是 2000,用户将通知标记为 category_id 看到的(标记了 600 个通知)它可以变成1900(必须是1400))。
功能:
CREATE OR REPLACE FUNCTION notifications.notify_seen_upd()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
begin
if new.seen = true and old.seen = false then
update notifications.notifications_counter
set unread =
(select unread
from notifications.notifications_counter
where notifications_counter.user_id = new.user_id) - 1
where notifications_counter.user_id = new.user_id;
end if;
if new.seen = false and old.seen = true then
update notifications.notifications_counter
set unread =
(select unread
from notifications.notifications_counter
where notifications_counter.user_id = new.user_id) + 1
where notifications_counter.user_id = new.user_id;
end if;
return new;
end;
$function$
;
扳机 :
create trigger z_notifications_upd after
update
on
notifications.notifications for each row execute function notifications.notify_seen_upd();
我在触发之前尝试过,结果是一样的
调用触发器的脚本示例:
UPDATE notifications.notifications AS t SET seen = true
WHERE (t.user_id = '6a16ca48-c215-4e9f-9d0f-cb78a0915192' and t.category_id = 1)
什么会导致这个麻烦?
解决方案
我将建议一种替代方法。不要试图保持一个总和,这比它的价值更麻烦。而是摆脱 notifications_counter 表。这也摆脱了状态变化的触发和相应的判断。现在创建一个 VIEW notifications_counter。您现在可以只计算看到与未看到提供相同和额外的信息,而工作量要少得多。见演示。
create view notifications_counter as
select user_id
, count(*) as total
, count(*) filter (where seen) as read
, count(*) filter (where not seen) as unread
from user_notifications
group by user_id ;
它还有一个优点是您不必担心通知被删除。
推荐阅读
- macos - 我可以使用通配符来阻止主机文件中的网站吗?
- python - ```time.perf_counter()``` 命令有什么作用?
- java - Java:如何将 0 到 1 之间的值四舍五入到至少 3 位小数?
- c# - 我在 Visual Studio 2013 的可扩展性选项卡中找不到添加自定义命令选项
- linux - CMake/CPack:将二进制文件从 Linux 部署到 Mac OSX
- asp.net-core - 基于策略的授权,仅允许作为资源所有者的用户能够查看/编辑
- python - 访问类外的类方法变量
- azure-devops - 如何在 azure DevOps YAML 管道中发送构建后消息?
- angular - 如何在ng中为每3个元素添加行和列
- r - blogdown hugo 删除社交链接