为了避免重复插入,我知道我可以使用"插入IGNORE"或"插入...在 MySQL 中的重复密钥更新中。
但是我正在使用laravel,我知道firstOrCreate不会这样做。它首先进行 SELECT 以查看该条目是否存在,并且仅在 SELECT 未返回任何记录时才进行插入。我猜它是特定于MySQL的becauaseDUPLICATE KEY UPDATE
。
从性能的角度来看,我先选择然后插入真的很糟糕?与"插入忽略"或"插入...重复密钥更新"?
不首先使用或创建并将我自己的 php 代码编写为"插入 IGNORE"或"插入......重复密钥更新"?
假设您只需要INSERT INTO ... IGNORE
功能,我建议您只在有问题的表上创建一个唯一的索引。
ALTER TABLE yourTable ADD CONSTRAINT cnstr UNIQUE KEY (col1, col2, ...);
有了这个,任何插入重复记录的尝试都会导致 PHP 端的应用程序错误,您可以轻松捕获和处理。
在尝试插入之前先执行插入以检查是否存在重复项的问题在于,仅当您确保从选择到插入完成期间表中没有其他 DML 活动时,此类逻辑才有效。 否则,可能会出现类似以下内容的情况:
process1: SELECT to check if record exists (assume it does not)
process2: INSERT record (which process1 wants to insert)
process1: INSERT same record (now a duplicate exists)
换句话说,您的PHP应用程序会"认为"不存在重复项,并插入记录。 但是,在其选择和插入之间的时间内,另一个进程碰巧插入了相同的记录。
为了避免这种情况,我相信你需要一个类似可序列化事务的东西。 但是,使用唯一约束要干净得多,并且将此责任主要留给数据库来处理。
也许在 mysql 中尝试 REPLACE :
REPLACE ...