如何避免将重复项插入MySQL?

时间:2016-07-22 16:39:18

标签: php mysql mysqli

我有一个分析平台,拥有大量用户和数百次插入点击/分钟。

有时候我会看到完全相同的点击在同一秒内被插入到数据库中,它变成了另一个的副本。

我有一个系统,可以检查表是否具有相同的值,如果找到的话,则不会插入另一个。

然而在这种情况下,它在我看来它们以完全相同的毫秒插入数据库。

我可以在这做什么?

2 个答案:

答案 0 :(得分:2)

我的最爱:insert ignore myTable (col1, col2, ...) ...

其中唯一键事先设置为禁止插入。看起来你并不在乎以前插入过多,因为你关心的是最终的结果不是欺骗。

注意:唯一键可以是多列键(复合词)

关于insert ignore的警告:如果不仔细考虑敏感系统的后果需要知道该行确实存在,就不应该实施。它非常适合"确保它在那里"。

选项B:可以查看意图锁,例如here,但是针对您的特定用例进行了设计。转向快速的INNODB行级锁定,当然不是表锁。大多数事情都需要权衡。锁定的缺点是并发性降低。

选项C:对于胆小的人(有时是我)。如果被雇用并且希望以后不会引起同行反对,我就会这样做。执行Insert ... on Duplicate Key UpdateIODKU),并有一个像touches这样的虚假列,它是为IODKU的Update部分递增的int。示例如下:

insert myTable (col1, col2, col3) values (p1,p2,p3) 
on duplicate key update touches=touches+1;

以上将是最简约的形式。下面的视图是我在C#中使用的内容,我关心IODKU"的更新部分中的更多列,但只是为了表明,如果它有益于任何人:

enter image description here

关于IODKU的最后想法:必须有一个唯一的密钥(主要或唯一的)导致"冲突"发生。因此,该语句知道是否执行插入或更新。如果没有这种唯一的密钥冲突,将插入一个新行。

回到操作问题,系统可能已经存在行的原因是由于高并发使用而没有锁定。

答案 1 :(得分:0)

如果系统的架构允许,我会创建双层解决方案。首先,将插入重复数据的临时表。临时表的名称可以包含分片参数,例如小时数。系统将定期将临时表中的数据导出到主存储表中,丢弃重复数据。然后它可以丢弃临时表。

相关问题