假設有一個表,結構如下:
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 的順序來顯示了。