【问题标题】:MySQL - Prevent Insertion of Record if ID and Timestamp Unique Combo Constraint Within TimeframeMySQL - 如果 ID 和时间戳在时间范围内唯一的组合约束,则防止插入记录
【发布时间】:2019-01-24 01:37:24
【问题描述】:

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

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

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

我是否需要运行一项在几秒钟内删除条目的作业,或者有没有办法让 MySQL 以某种方式为我执行此操作?

表结构是这样的

entry_id host_id 日期时间

条目可能是

1 121 01/17/2019 02:38:04 上午

1 121 01/17/2019 02:38:05 AM

1 121 01/17/2019 02:36:04 上午

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

我的表中有更多的日期时间列,但不需要它们来理解这种情况。任何帮助表示赞赏。

【问题讨论】:

  • 了解使用正确数据类型的重要性
  • 一旦你解决了这个问题,作为 Barmar 建议的替代方案,你可以将逻辑绑定到 INSERT 本身
  • @Strawberry,不确定您的意思。我正在使用正确的数据类型。
  • 好的 - 但 2019 年 1 月 17 日看起来不像!

标签: mysql datetime constraints unique


【解决方案1】:

如果您使用的是 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 都更改为您想要使用的任何时间粒度。

【讨论】:

  • 你知道这是否适用于 MariaDB 吗?我似乎无法让它与 5.5 或 10.0.36 版一起使用。如果我能让它工作,这似乎是解决我的问题的正确方法。感谢您的帮助,并感谢您提出这个想法!
  • 它是在 MySQL 5.7 中添加的,这就是它不适用于 5.6 的原因。
  • mariadb.com/kb/en/library/generated-columns 说:虚拟列最早出现在 MariaDB 5.2 中。 MariaDB 10.2.1 中取消了其中的一些限制。
  • 更多:在 10.2.3 之前,只能索引 PERSISTENT 虚拟列。
  • 也许我应该升级到高于 10.2.1 的版本,因为当我尝试在 10.0.36 中运行它时,我得到以下信息: ALTER TABLE downtime ADD datetime_10sec AS (10 * ROUND(UNIX_TIMESTAMP (datetime)/10)) MySQL 说:文档 #1064 - 您的 SQL 语法有错误;检查与您的 MariaDB 服务器版本相对应的手册,以在第 2 行的“AS (10 * ROUND(UNIX_TIMESTAMP(datetime)/10))”附近使用正确的语法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-15
  • 2019-05-10
  • 1970-01-01
相关资源
最近更新 更多