MySQL自增列使用replace into的風險

最近在排查問題時,發現一個表自增列的值不連續。在排除了刪除、更新的場景後,懷疑與replace into語句有關。特地重現了下。

如果一個表,同時存在自增主鍵和唯一鍵。replace into時,如果一行數據中唯一鍵是存在的,該行數據指定了新的主鍵值或不指定主鍵值,會導致主鍵被更新成新值。

下面用例子演示一下問題。

初始化測試表和數據

/** 1.1 創建測試表,含自增主鍵、唯一鍵 */
mysql> create table test_replace (id int not null auto_increment, code char(1), title varchar(64), primary key (id), unique key key_code(code)); 
Query OK, 0 rows affected (0.03 sec)

/** 1.2 插入測試數據,自增主鍵 */
mysql> insert into test_replace (code, title) values ('a', 'first record'), ('b', 'second record');
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from test_replace;
+----+------+---------------+
| id | code | title         |
+----+------+---------------+
|  1 | a    | first record  |
|  2 | b    | second record |
+----+------+---------------+
2 rows in set (0.00 sec)

重現風險

/** 2.1 執行replace into,唯一鍵已存在、但主鍵是新生成的 */
mysql> replace into test_replace values (3, 'a', 'first record replaced');
Query OK, 2 rows affected (0.01 sec)

mysql> select * from test_replace;
+----+------+-----------------------+
| id | code | title                 |
+----+------+-----------------------+
|  2 | b    | second record         |
|  3 | a    | first record replaced |
+----+------+-----------------------+
2 rows in set (0.00 sec)

/** 2.2 執行replace into,唯一鍵已存在、但主鍵未指定,由數據庫處理 */
mysql> replace into test_replace values (null, 'a', 'first record replaced 2');
Query OK, 2 rows affected (0.01 sec)

mysql> select * from test_replace;
+----+------+-------------------------+
| id | code | title                   |
+----+------+-------------------------+
|  2 | b    | second record           |
|  4 | a    | first record replaced 2 |
+----+------+-------------------------+
2 rows in set (0.00 sec)

嚴格來講這個瓜是replace into的,但是MySQL的自增實在是有太多的坑和細節了,我就是想吐槽AUTO_INCREMENT。 當然自己去實現自增器,也不見得比MySQL做得好。

MySQL自增列使用可參考《MySQL自增列AUTO_INCREMENT詳解(含NULL值、初始值、指定值等說明)》


以上。感謝您的閱讀。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章