作/译者:叶金荣(Email: ),来源:http://imysql.cn,转载请注明作/译者和出处,并且不能用于商业用途,违者必究。
假设有一个表,结构如下:
mysql> CREATE TABLE `a` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT,`id2` int(10) unsigned NOT NULL DEFAULT '0',PRIMARY KEY (`id`)
) ENGINE=MyISAM;

该表中只有6条记录,如下:
mysql> select * from a;
+----+---------+
| id | city_id |
+----+---------+
|  2 |       2 |
|  3 |       3 |
|  5 |       5 |
|  4 |       4 |
|  6 |       6 |
|  7 |       7 |
+----+---------+

现在想要把id字段分别-1,执行以下语句,得到报错:
mysql> update a set id=id-1;
ERROR 1062 (23000): Duplicate entry '4' for key 'PRIMARY'

看看更新后的结果,可以看到:
mysql> select * from a;
+----+---------+
| id | city_id |
+----+---------+
|  1 |       2 |
|  2 |       3 |
|  5 |       5 |
|  4 |       4 |
|  6 |       6 |
|  7 |       7 |
+----+---------+

存储在最前面的2条记录更新成功了,后面的则失败,因为第三条记录如果也要更新,则会引发主键冲突。
这个时候,如果我们在更新时增加 ORDER BY 的话,则可以顺利更新成功。
mysql> update a set id=id-1 order by id;
Query OK, 6 rows affected (0.00 sec)
Rows matched: 6  Changed: 6  Warnings: 0

接下来,我们看看把它转成 innodb 表,结果会是怎样的。
mysql> alter table a engine = innodb;
Query OK, 6 rows affected (0.01 sec)
Records: 6  Duplicates: 0  Warnings: 0
mysql> select * from a;
+----+---------+
| id | city_id |
+----+---------+
|  2 |       2 |
|  3 |       3 |
|  4 |       4 |
|  5 |       5 |
|  6 |       6 |
|  7 |       7 |
+----+---------+

看到变化了吧,行数据按照 id 的顺序来显示了。
清空后,自己重新手工插入记录,再看看。
mysql> INSERT INTO `a` VALUES (2,2),(3,3),(5,5),(4,4),(6,6),(7,7);
Query OK, 6 rows affected (0.00 sec)
Records: 6  Duplicates: 0  Warnings: 0
mysql> select * from a;
+----+---------+
| id | city_id |
+----+---------+
|  2 |       2 |
|  3 |       3 |
|  4 |       4 |
|  5 |       5 |
|  6 |       6 |
|  7 |       7 |
+----+---------+

还是按照 id 的顺序来显示,然后我们再次执行之前的 update 语句:
mysql> update a set id = id - 1;
Query OK, 6 rows affected (0.00 sec)
Rows matched: 6  Changed: 6  Warnings: 0

可以看到,在 innodb 表的情况下,更新是可以成功的。
现在我们来分析下。
myisam表是堆组织表(Heap Organize Table, HOT),它的索引是采用 b-tree 方式存储的,数据显示时是随机顺序,而非按照主键的索引顺序来显示。
而innodb表是索引组织表(Index Organized Table, IOT),它的索引则是采用 clustered index 方式,因此主键会按照顺序存储,每次有记录有更新时,会重新整理更新其主键。因此无论是直接从 myisam 表转换过来的,还是后来插入的记录,显示时都会按照主键的顺序。
更新数据时,如果没有指定排序的字段或索引,则默认以随机顺序更新,所以 myisam 表如果不指定 ORDER BY 的话,则采用默认的存储顺序来更新,所以会发生主键冲突的情况。
而 innodb 表总是有主键(如果没有定义,则也有默认主键),如果更新时没有指定排序字段或索引,则按照主键顺序来更新,在上面的例子中,就是按照主键 id 的顺序来更新了,因此不会报错。
本文出自 “MySQL中文网”博客 http://www.imysql.cn/
 

UPDATE 时主键冲突引发的思考相关推荐

  1. mysql主主 主键冲突_mysql主从复制原理,主主复制时主键冲突解决

    主从复制原理: 1.master的增删改记录写入binlog: 2.slave的I/O Thread(负责读取master的binlog)读取binlog并将记录写入relaylog: 3.slave ...

  2. mysql insert 主键冲突_insert 时防止出现主键冲突错误的方法

    最近几天,产品上线比较多,从内网测试库导出表的部分内容到线上也就比平时频繁多了,这时候可能会出现主键冲突: Error Code : 1062 Duplicate entry '1' for key ...

  3. insert时出现主键冲突的处理方法【转载】

    原文出处:http://hi.baidu.com/ytjwt/blog/item/1ccc2c26022b0608908f9d8c.html 使用"insert into"语句进行 ...

  4. sqoop从hive导入数据到mysql时出现主键冲突

    今天在将一个hive数仓表导出到mysql数据库时出现进度条一直维持在95%一段时间后提示失败的情况,搞了好久才解决.使用的环境是HUE中的Oozie的workflow任何调用sqoop命令,该死的o ...

  5. 批量插入数据表数据时,主键冲突的解决

    2.使用普通的insert into on conflict合并写入,存在写入放大思路: 大量数据,批量插入到数据表中时,很容易造成主键冲突,重复数据有唯一约束插入不进去表中,报错的问题出现. 排查错 ...

  6. mysql 主从,主主,主主复制时的主键冲突解决

    原理:slave 的i/o thread ,不断的去master抓取 bin_log, 写入到本地relay_log 然后sql thread不断的更新slave的数据 把主服务器所有的数据复制给从服 ...

  7. django使用postgresql时提示主键冲突

    在django使用postgresql数据库时,当你使用默认主键,但当你手动使用添加记录到相关数据库时(非insert操作,如使用navicate直接在表中复制粘贴记录),此时django在插入数据时 ...

  8. Mysql从库主键卡住_从库宕机引发的主键冲突

    刚刚接到报警短信,从库宕机,马上通知机房重启,在检查MySQL时,发现同步挂了,报主键冲突,询问开发是不是有往里面写数据,回答没有.这就奇怪了,怎么会无缘 刚刚接到报警短信,从库宕机,马上通知机房重启 ...

  9. DB2添加数据时主键、唯一键冲突的解决方法

    DB2添加数据时主键.唯一键冲突的解决方法 参考文章: (1)DB2添加数据时主键.唯一键冲突的解决方法 (2)https://www.cnblogs.com/equation/articles/91 ...

最新文章

  1. 081_Introducing trigger handler class
  2. linux Fedora搭建hadoop平台总结
  3. C#如何测试代码运行时间
  4. JavaScript数组常用的方法总结
  5. 移动云帮我养出了一片致富鱼塘
  6. 马云终于露面了!发表千字演讲
  7. 设置按钮背景为透明去掉button按钮左右两边的留白
  8. 中rsa非对称加密_HTTP的数据传输中,对称加密和非对称加密的区别是什么?
  9. combobox的method是get为什么发的请求是post_深入理解http get和post请求的区别,读完之后,大部分程序员收藏了...
  10. 圈圈教你学USB第一章
  11. android 反编译 签名,Android反编译及重签名命令
  12. Javaweb 九大内置对象
  13. 从C到C++ 番外const的用法
  14. 希尔伯特的23个数学问题
  15. 二极管钳位、稳压二极管的应用
  16. php发邮件附件,PHP使用PHPMailer发送邮件和附件的方法
  17. 自然语言生成技术现状调查:核心任务、应用和评估(3)
  18. java中appletviewer是什么意思_自动生成供AppletViewer运行Java Applet的HTML文件
  19. HDMI传输设备上的ARC和EARC代表哪些功能?
  20. Knime北京房价工作流建立

热门文章

  1. SQLyog普通版与SQLyog企业版对比分析
  2. Android SDK上手指南:虚拟与物理设备
  3. [Hadoop][笔记]4个节点搭建Hadoop2.x HA测试集群
  4. poj1236(强连通缩点)
  5. php ×××号码效验码生成函数
  6. 留念,第一次在C中调用lua成功!
  7. SCRUM的三个工件
  8. 本地事务和分布式事务工作实践
  9. 九章算法【总结】Java 搞定链表-面试常考题目精选
  10. Android Context activity实例使用