【发布时间】:2021-01-16 05:05:48
【问题描述】:
我正在构建一个事件提醒页面,人们可以在其中为某些事件设置提醒。用户可以选择在需要通知之前设置多长时间。它存储在notification_time 和notification_unit 中。 notification_time 跟踪他们想要收到通知之前的时间,notification_unit 跟踪他们选择时间的 PHP 日期格式,例如。 i 分钟,H 小时。
例如。 notification_time - 2 和notification_unit - H 表示需要提前2小时通知。
我在后台运行 Cron 作业来处理通知。此功能每分钟触发一次。
Reminder::where(function ($query) {
$query->where('event_time', '>=', now()->subMinutes(Carbon::createFromFormat('i', 60)->diffInMinutes() - 1)->format('H:i:s'));
$query->where('event_time', '<=', now()->subMinutes(Carbon::createFromFormat('i', 60)->diffInMinutes())->format('H:i:s'));
})
在这个函数中,我对'i', 60 进行了硬编码,而它应该从数据库中获取。 event_time 也是同一张表的一部分
表格看起来像这样 -
idevent_time...notification_unitnotification_timecreated_atupdated_at
有什么办法可以解决这个问题吗?是否可以用 SQL 做同样的逻辑?
【问题讨论】:
-
有什么理由不能只存储
notify_at列,以及他们想要收到通知的日期时间吗?您可以在创建记录时存储它,而不是存储时间和单位。我认为你过于复杂了。我不知道有什么方法可以在 SQL 中做到这一点(我相信你可以),而 Laravel 解决方案将涉及加载所有记录,解析时间,然后过滤掉那些不t align,这是一个非常强大的功能。 -
@TimLewis 需要比这复杂得多,提醒可以是每年一次的重复类型,因此将特定日期存储为
notify_at根本不合逻辑。加载所有记录是巨大的,因为该函数每分钟运行一次。想象一下有一个包含 10k+ 条记录的数据库。哦,我的案子也有 6 张桌子做同样的事情。 -
该响应是有道理的 :) 我只是问是否可以使用静态列而不是尝试以编程方式创建它。不幸的是,我仍然没有办法,但我会密切关注这个问题;看起来很有趣
-
你的问题很有趣。我会试着把事情混在一起。一个表格用于提醒您的实际配置,另一个表格用于通知。第二个表应该预先计算了
notify_at。您可能还需要一个sent标志。每次发送通知后,您都需要插入下一个通知,并再次预先计算所有内容。这样,您的 cronjob 将非常轻量级,因为您只会获取这一分钟的通知。不要忘记为dispatch_at和sent创建索引。