共計 3481 個字符,預計需要花費 9 分鐘才能閱讀完成。
這期內容當中丸趣 TV 小編將會給大家帶來有關 MySQL 中 replace into 語句的作用是什么,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
在主庫上操作。
代碼如下:
root@test 12:36:51 show create table t1 \G
*************************** 1. row ***************************
Table: t1
Create Table: CREATE TABLE `t1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
root@test 12:37:41 insert into t1(name) values(a)
此時檢查主備庫上 t1 的表結構都是一樣的,AUTO_INCREMENT 都是 2。
代碼如下:
root@test 12:37:51 show create table t1 \G
*************************** 1. row ***************************
Table: t1
Create Table: CREATE TABLE `t1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
在主庫上進行進行 replace into 操作
root@test 12:37:58 replace into t1(name) values(a
root@test 12:38:40 replace into t1(name) values(a
root@test 12:38:49 select * from t1;
+—-+——+
| id | name |
+—-+——+
| 3 | a |
+—-+——+
1 row in set (0.00 sec)
此時檢查主備庫中 t1 表結構,請注意 AUTO_INCREMENT=4。
代碼如下:
root@test 12:38:51 show create table t1 \\G
*************************** 1. row ***************************
Table: t1
Create Table: CREATE TABLE `t1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
從庫上 t1 的表結構,AUTO_INCREMENT=2
代碼如下:
root@test 12:39:35 show create table t1 \G
*************************** 1. row ***************************
Table: t1
Create Table: CREATE TABLE `t1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
root@test 12:39:43 select * from t1;
+—-+——+
| id | name |
+—-+——+
| 3 | a |
+—-+——+
1 row in set (0.00 sec)
【分析】
表 t1 的表結構 AUTO_INCREMENT=2 而主庫上的 t1 表結構的 AUTO_INCREMENT=4. 原本 replace 操作是在自增主鍵的情況下,遇到唯一鍵沖突時執行的是 delete+insert, 但是在記錄 binlog 時, 卻記錄成了 update 操作,update 操作不會涉及到 auto_increment 的修改。備庫應用了 binlog 之后,備庫的表的 auto_increment 屬性不變。
三、風險點:
如果主備庫發生主從切換,備庫變為原來的主庫,按照原來的業務邏輯再往下會發生什么?
代碼如下:
root@test 12:40:46 replace into t1(name) values(a
Query OK, 2 rows affected (0.00 sec)
root@test 12:40:48 select * from t1;
+—-+——+
| id | name |
+—-+——+
| 2 | a | —id 由原來的 3 變成了 2.
+—-+——+
1 row in set (0.00 sec)
如果 t1 表本來就存在多條記錄,主從切換之后,應用寫新的主庫則會發生主鍵沖突,這個留給各位讀者自己測試一下。^_^
四、解決方法
推薦使用 insert into table values(,….) on duplicate key update 語法結構來解決業務需求。來避免 replace into 給含有自增主鍵的表帶來主從不一致情況。
代碼如下:
root@test 01:14:28 insert into t1(name) values(a
Query OK, 1 row affected (0.00 sec)
root@test 01:14:51 insert into t1(name) values(b
Query OK, 1 row affected (0.00 sec)
root@test 01:14:54 insert into t1(name) values(c
Query OK, 1 row affected (0.00 sec)
root@test 01:14:57 select * from t1;
+—-+——+
| id | name |
+—-+——+
| 1 | a |
| 2 | b |
| 3 | c |
+—-+——+
3 rows in set (0.00 sec)
root@test 01:16:17 show create table t1 \G
*************************** 1. row ***************************
Table: t1
Create Table: CREATE TABLE `t1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
root@test 01:16:26 insert into tt(name) values(a) on duplicate key update name= a
Query OK, 1 row affected (0.00 sec)
root@test 01:17:09 show create table t1 \G
*************************** 1. row ***************************
Table: t1
Create Table: CREATE TABLE `t1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
上述就是丸趣 TV 小編為大家分享的 MySQL 中 replace into 語句的作用是什么了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注丸趣 TV 行業資訊頻道。