MySQL-如果ID和时间戳在时间范围内具有唯一的组合约束,则防止插入记录

时间:2019-01-24 01:37:25

标签: mysql datetime constraints unique

我有一个场景,其中3个独立代理正在报告各种主机的正常运行时间状态。如果主机出现故障并脱机,则应创建停机记录。不幸的是,由于座席完全在同一时间报告相同的信息,所以我看到间隔为1-2秒的重复条目。

我在表上为日期时间和主机ID创建了唯一约束。因此,它们不能相同。但是,如果来自代理的请求同时或相隔一秒出现,尽管代码检查正在寻找现有条目,但仍可能会创建重复项(在这种情况下,如果三个实例都尚未创建该条目,代理商同时报告)。唯一的约束也不会阻止重复,因为当PHP / MySQL调用完成处理时,日期时间可能比之前晚1秒或更多...

那么,处理这种情况的最佳方法是什么?在MySQL中是否有一种方法可以指定,如果唯一约束(包括datetime字段)在具有唯一约束的另一条记录的特定时间范围内,则不应允许它插入?

我是否需要运行一项可以在几秒钟之内删除条目的作业,还是有办法让MySQL以某种方式为我做到这一点?

表结构如下

entry_id host_id datetime

条目可能是

1121 01/17/2019 02:38:04 AM

1121 01/17/2019 02:38:05 AM

1121 01/17/2019 02:36:04 AM

我要防止插入粗体条目,因为它距插入的最后一个条目不到1秒。代码检查将不起作用,因为在检查代码时可能没有条目。我已经有一个代码检查在寻找现有条目,并且由于找不到一个条目,并且可以针对每个请求在同一时间运行代码,因此该检查失败,并说应创建一个新条目。

我的表中有更多的datetime列,但不需要了解这种情况。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:2)

如果您使用的是MySQL 5.7或更高版本,则可以定义一个生成的列,该列包含向下舍入为5或10秒范围的时间戳。然后,您可以在该列上定义一个唯一索引,因此,如果您尝试在同一时间段创建两个带有时间戳的记录,则会遇到约束冲突。

ALTER TABLE yourTable 
ADD datetime_10sec INT AS (10 * ROUND(UNIX_TIMESTAMP(datetime)/10)) PERSISTENT, 
ADD UNIQUE INDEX (host_id, datetime_10sec);

10都更改为您要使用的任何时间粒度。