处理选择+插入以避免重复错误的正确方法

法布里佐

您好,我有一个仅两个字段的简单MySQL InnoDB表:

  • id-自动增量主索引
  • 名称-唯一索引

我要从各种来源并行导入一些数据,并且需要确保在插入时不重复这些数据,因此我需要执行以下操作:

SELECT `id` FROM `table` WHERE `name` = <name>;
 if `id` <= 0
  INSERT INTO `table` SET `name` = "<name>";
  return AUTO_INCREMENT
 else return `id`

这可以工作99.9999%的时间,但是由于两个SELECT都返回id<= 0,所以两个或多个不同的脚本正在插入相同的数据,这可能会发生(并且发生在我身上),因此INSERT都会发生,并且其中一个会引发错误。

我有两个可能的解决方案,但我不确定哪种方法最有效。

另外一条信息:最初导入不会在表中找到元素,但是随着插入更多元素,被发现的可能性会增加。经过一番粗略的计算,决赛桌将有大约7到1千万条记录:

SELECT `id` FROM `table` WHERE `name` = <name>;
if `id` <= 0
 INSERT IGNORE INTO `table` SET `name` = "<name>";
 get AUTO_INCREMENT
  if AUTO_INCREMENT <=0
   SELECT `id` FROM `table` WHERE `name` = <name>;
   return `id`
  else return AUTO_INCREMENT
else return `id`

或者

INSERT IGNORE INTO `table` SET `name` = "<name>";
get AUTO_INCREMENT
 if AUTO_INCREMENT <=0
  SELECT `id` FROM `table` WHERE `name` = <name>;
  return `id`
 else return AUTO_INCREMENT
琼斯

您遇到了比赛情况。当您的代码检测到有必要进行新的插入时,那么您的两个客户就争先成为第一个插入该值的客户。这是赢家通吃的。您需要编写代码来避免这种竞争情况。幸运的是,SQL是专门设计的,因此可以做到这一点。

在这里,您有两种选择,这两种选择都特定于MySQL的SQL方言。

一种是使用内置功能LAST_INSERT_ID()它达到了我相信您的意思get AUTO_INCREMENT

另一种是使用INSERT ... ON DUPLICATE KEY UPDATE

您的逻辑似乎打算做两件事:

  1. 确保该name值在表中,如果尚未在表中,则将其放置在表中。
  2. 返回id与名称值关联的值。

您可以这样做。

INSERT IGNORE INTO `table` (name) VALUES (<name>);
SELECT id FROM `table` WHERE name = <name>;

注意,该INSERT IGNORE操作不会被命中数据库的不同程序之间的竞争条件所捕获,因为它是一条SQL语句。

您可以使用进行优化LAST_INSERT_ID()

INSERT IGNORE INTO `table` (name) VALUES (<name>);
if (LAST_INSERT_ID()=0) then do the select.

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

处理数组以避免错误

来自分类Dev

提高选择然后插入的性能以避免重复记录(在mysql和php中)?

来自分类Dev

处理程序中的Golang抽象,以避免代码重复

来自分类Dev

如何正确处理我的 WebGL 上下文以避免 16 个 WebGL 上下文错误?

来自分类Dev

处理NSTokenField中的重复选择

来自分类Dev

在Scala中选择正确的异常处理

来自分类Dev

批处理脚本未选择正确的条件

来自分类Dev

VBA选择性错误处理

来自分类Dev

Scala错误处理:尝试还是选择?

来自分类Dev

处理对话框中的错误选择

来自分类Dev

处理每个对象的多个选择的最佳方法

来自分类Dev

批处理编码-选择命令未返回正确答案

来自分类Dev

在闭包中正确处理维护的引用,以避免内存泄漏

来自分类Dev

正确处理闭包中维护的引用,以避免内存泄漏

来自分类Dev

您如何有选择地处理JavaScript承诺中的错误?

来自分类Dev

错误级别的批处理选择命令不起作用

来自分类Dev

选择分组形状阵列的错误处理失败

来自分类Dev

模式避免重复处理

来自分类Dev

模式避免重复处理

来自分类Dev

处理导航项目选择的最佳方法是什么?

来自分类Dev

从随机选择避免重复

来自分类Dev

处理重复的UDP DNS请求的正确方法?

来自分类Dev

如何处理巨大的numpy数组上的计算以避免内存分配错误?

来自分类Dev

如何在 Swagger 中处理非必需参数以避免丢失位置参数错误?

来自分类Dev

仅比较循环中选择的值,以避免出现错误消息

来自分类Dev

处理许多全屏png以避免OOM

来自分类Dev

处理许多全屏png以避免OOM

来自分类Dev

选择随机数组元素以避免排除列表的最佳方法

来自分类Dev

Java:method()处理错误调用的正确方法

Related 相关文章

热门标签

归档