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

时间:2016-03-19 06:43:44

标签: php mysql

我有一个每隔几秒就能获得新数据的表。考虑我的表 PRODUCT

+----+-------------+--------+--------------------------------+-------+--------+---------------------+
| 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 |
+----+-------------+--------+--------------------------------+-------+--------+---------------------+

name description 中的值是唯一的(我不确定这是对的)。

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

我已经尝试过查询:

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)

我应该改变哪种情况?我应该删除唯一键吗?

2 个答案:

答案 0 :(得分:1)

您希望在时间戳晚于最后插入记录的时间戳不超过5分钟时插入重复的名称 description 值。

根据此要求,您有效地说名称描述 唯一。因此,实际上,您必须删除这些字段上的unique键/索引才能实现此目的。

其次,假设如果表中已经存在新值,那么它必须是最后插入的记录,但似乎无法保证。您还应该处理插入第一个值A的可能性,然后是一分钟后的值B,然后在10分钟后再次计算值A.

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

所以我建议这样做:

UNIQUE密钥/索引放在名称 description 上,但您仍然可以从使用非唯一索引中受益;

使用以下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 injection的攻击。阅读converting your code to use prepared statements

如果之前已经注册了名称 description 值组合,并且发生的时间超过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)

同样,你应该用准备好的陈述来做这件事。

答案 1 :(得分:0)

如果您将描述用作唯一,则无法插入具有相同描述的新记录。唯一应该使用“id”,所以是的,你应该删除唯一的描述。

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