独特的索引,可在连续几天内保证唯一性

时间:2014-03-15 11:38:08

标签: database unique-constraint

我想向用户发送友情提醒电子邮件。例如,当用户连续30天没有登录时(我们发送电子邮件时有多种不同的情况)。

每天晚上我都会检查不同的条件并发送电子邮件,我会为每封发送的电子邮件创建一个数据库条目。现在有了改变:我希望保证单个用户不会在连续7天内收到多封电子邮件

有解决这个问题的聪明,通用的方法吗?基本上我需要以某种方式转换当前日期时间,即转换后的datetime和userid的组合在接下来的7天内(或者通常,在给定的时间跨度内)将是唯一的。

我能想到的“最接近的”是使用当年的当前一周。但这有两个问题:这是一个特例(仅适用于7天的特殊情况),更重要的是,这只能保证每周一封电子邮件,但不能连续几天。例如。用户星期六收到一封电子邮件,星期一收到另一封电子邮件。

注意:请不要建议依赖于在应用程序级别强制执行此约束的解决方案(例如将当前日期时间与数据库中的最新日期时间进行比较)。我想要一个干净的解决方案,保证数据库级别的唯一性。

编辑:我没有提到我正在使用的数据库系统,因为它应该是一个通用的解决方案,它完全依赖于支持唯一索引。我不能使用触发器之类的东西。

到目前为止的想法

这是我在发布问题后提出的问题。我对他们不满意。

  1. 发送电子邮件时,批量插入七个数据集。如果失败,请不要发送电子邮件。这需要索引(用户,日)。插入的记录基本上会阻止未来七天内的任何尝试。

  2. 没有唯一索引。我们每个用户需要一个条目。我们在发送电子邮件之前更新条目。伪SQL UPDATE email_lock WHERE user=[user] and last_send + 7 DAY < NOW() SET last_send = NOW()。如果更新记录的数量为0,请不要发送电子邮件。这将起作用并且是原子的。

1 个答案:

答案 0 :(得分:0)

这应该可以解决问题:

select user_id, MAX(send_date) as last_send_date from emails 
group by user_id
having MAX(send_date) < NOW() - INTERVAL '7 days';

它会返回您可以向其发送电子邮件的用户。

小提琴:http://sqlfiddle.com/#!15/d2a51/3