避免特定时间间隔的重复数据


Avoid Duplicate data for specific time Interval

我有一个表,每隔几秒钟就会获取新数据。考虑我的表产品

+----+-------------+--------+--------------------------------+-------+--------+---------------------+
| id | business_id | name   | description                    | link  | status | created_at          |
+----+-------------+--------+--------------------------------+-------+--------+---------------------+
| 1  | 12          | qwerty | Description for product qwerty | zxcvb | 1      | 2015-12-07 23:49:33 |
+----+-------------+--------+--------------------------------+-------+--------+---------------------+
| 2  | 12          | abcde  | Description for product abcde  | mnopq | 0      | 2015-12-07 23:49:33 |
+----+-------------+--------+--------------------------------+-------+--------+---------------------+

名称和描述中的值是唯一的(我不确定这是否正确)。

我想要的条件:如果新数据与上次插入的数据相同,但时间戳大于 5 分钟,则执行更新或在表中插入新行。即使名称和描述是唯一的。

我试过的查询:

INSERT INTO product(business_id, name, description, link) 
VALUES ('$business_id' ,'$product_name','$product_description', '$short')
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id)

我应该改变哪种条件?我应该删除唯一键吗?

您希望

在重复的名称说明值的时间戳不比上次插入的记录晚 5 分钟时插入这些值。

有了这个要求,你有效地说名称和描述不是唯一的。因此,实际上,您必须删除这些字段上的unique键/索引才能实现这一点。

其次,您假设如果表中已存在新值,则它必须位于最后插入的记录中,但似乎无法保证这一点。您还应该处理以下可能性:首先插入值 A,然后在一分钟后插入值 B,然后在 10 分钟后再次插入值 A。

在您提供的逻辑中,最后一个操作将被检测为重复,并会转换为上次插入记录的更新。但这不是值 A 的记录。实际上,在这种情况下,您建议的ON DUPLICATE子句会产生自己的重复错误(id上重复)。

所以这是我建议做的:

删除名称和描述上的UNIQUE键/索引,但您仍然可以从使用非唯一索引中受益;

使用以下 INSERT 语句:

INSERT INTO product(business_id, name, description, link) 
SELECT :business_id, :name, :description, :link
FROM   product
WHERE  NOT (    name = :name 
            AND description = :description 
            AND created_on < DATE_ADD(NOW(), INTERVAL -5 MINUTE)
       )

:表示预准备语句中参数的占位符。您不应该像以前那样在 SQL 语句中插入字符串,因为这样您就容易受到 SQL 注入的攻击。阅读有关将代码转换为使用预准备语句的信息。

如果之前已经注册了名称和描述值组合,并且发生在 5 分钟前,则上述 INSERT 语句将不执行任何操作。

在这种情况下,您可以在 PHP 中测试没有使用 num_rows 方法插入任何记录。如果返回 0,则您将执行第二个 SQL 来执行更新:

UPDATE product
SET    link = :link
WHERE  name = :name 
   AND description = :description 
   AND created_on < DATE_ADD(NOW(), INTERVAL -5 MINUTE)

同样,您应该使用准备好的语句来执行此操作。

如果使用唯一描述,则无法插入具有相同描述的新记录。唯一应该在"id"处使用,所以是的,你应该在描述上删除唯一。

您可以使用if子句检查是否business_id是否相同并且create_at大于5分钟,然后更新或插入新行。