REPLACE INTO
1.前言
replace into 可以說是 insert 的增強版,但由於其獨特的特性,誤用會帶來一些副作用,
其功能與 insert 功能類似,不同點是replace into 首先嚐試插入數據到表中
- 如果數據已經存在(根據主鍵或者唯一索引判斷)則先刪除此行數據,然後插入新的數據(特性:先刪除再插入) ;
- 否則,直接執行插入新數據;
官方介紹
簡譯
- REPLACE與INSERT工作方式基本相同。不同點在於如果表中舊行與主鍵或唯一索引列具有相同的值,則插入新行之前刪除該舊行。
CREATE TABLE `insert_relpace_into_test` (
`id` int(10) NOT NULL AUTO_INCREMENT COMMENT '自增ID',
`uniq_id` varchar(32) COMMENT '字段 a',
`filed_a` varchar(32) DEFAULT '' COMMENT '字段 b',
`filed_b` varchar(32) DEFAULT '' COMMENT '字段 c',
`version` int(10) DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `uniq_uniq_id` (`uniq_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='REPLACE INTO 語法測試表';
2.使用方式
創建測試表
CREATE TABLE `insert_relpace_into_test` (
`id` int(10) NOT NULL AUTO_INCREMENT COMMENT '自增ID',
`uniq_id` varchar(32) DEFAULT NULL COMMENT '字段 a',
`filed_a` varchar(32) DEFAULT '' COMMENT '字段 b',
`filed_b` varchar(32) DEFAULT '' COMMENT '字段 c',
`version` int(10) DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `uniq_uniq_id` (`uniq_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='REPLACE INTO 語法測試表';
2.1. replace into values
注:支持單個或批量
REPLACE INTO insert_relpace_into_test
( uniq_id, filed_a, filed_b, version )
VALUES
( '1003', '字段 a', '字段 b', 1 ),
( '1005', '字段 _2_2', '字段 b_2', 1 );
2.2. **replace into select **
REPLACE INTO insert_relpace_into_test ( uniq_id, filed_a, filed_b, version )
SELECT uniq_id, filed_a, filed_b, version FROM insert_relpace_into_test2;
2.3. replace into set
REPLACE INTO insert_relpace_into_test
SET uniq_id='1003',filed_a='字段 _2_2',filed_b='字段 b_2';
注:INTO 關鍵句可以省略,建議加上,更通俗易懂
3.常見問題
3.1.數據已經存在但沒有執行替換邏輯 ;
- 檢查字段中是否包含唯一索引列,若沒有唯一索引或主鍵列則會一直新增下去 ;
3.2.自增主鍵不連續;
- 由於存在則刪除後新增的特性,在執行插入,則會造成自增ID一直增大,出現不連續的問題 ;
4.總結
1.由於若存在,則刪除後新增的特性,插入新記錄只是插入了某些業務指定字段,還存在一些原先不想更新的字段,若執行了,刪除後新增則會導致部分數據丟失。
2.若表的自增ID與其它表有關聯,刪除後新增並生成新的id後,會導致關聯丟失 。
3.而且使用replace into會導致自增主鍵id一直增大,很容易導致id值存在跳躍,範圍不夠使用了 。
4.若主從關係數據庫,在主機器上進行了replace into操作之後,從機器上對應表的AUTO_INCREMENT是不會更新,導致從機器轉爲主機器時,新插入數據會出現異常,直到AUTO_INCREMENT增加到原來主機器的值爲止。