mysql duplicate key与replace into对比
【REDME】
有些業務場景如下:
對于數據已經存在的,則更新;否則新增;
怎么判定數據已經存在,通過主鍵或唯一索引來判斷;
業務場景:業務庫的全局參數表的參數值的新增或更新就是 有則更細無則插入的常見業務場景;
【1】2種實現方式
通常情況下,我們是先select,判斷數據是否存在;若不存在,則新增,否則更新;
要完成這個小小功能,我們需要寫3條sql,非常麻煩;
采用2種簡單方式(只需要寫1條sql):
- 方式1, duplicate key, insert into ...... on duplicate key update ...
- 方式2,replace into,
【1.1】duplicate key update
0. duplicate 官方文檔翻譯,參見? ?https://blog.csdn.net/PacosonSWJTU/article/details/120058725
1.duplicate顧名思義,有重復鍵則更新,否則插入;
2.語法如下:
如果指定 ON DUPLICATE KEY UPDATE 子句并且要插入的行會導致 UNIQUE 索引或 PRIMARY KEY 中出現重復值,則會發生舊行的 UPDATE。 例如,如果列 a 聲明為 UNIQUE 并包含值 1,則以下兩個語句具有類似的效果:
INSERT INTO t1 (a,b,c) VALUES (1,2,3)ON DUPLICATE KEY UPDATE c=c+1;UPDATE t1 SET c=c+1 WHERE a=1;3.測試案例
-- 表結構 CREATE TABLE `my_cust_warn_tbl` (`rcrd_id` varchar(64) NOT NULL COMMENT '記錄編號',`cust_num` varchar(50) NOT NULL COMMENT '客戶號',`cust_name` varchar(50) DEFAULT '' COMMENT '客戶姓名',`warn_times` int(11) DEFAULT NULL COMMENT '客戶預警次數',`create_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '創建時間',`last_modify_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '最后修改時間',PRIMARY KEY (`rcrd_id`),UNIQUE KEY `uni_cust_num` (`cust_num`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='客戶預警表'注意: 使用duplicate語法的數據庫表一定要設置唯一索引,以便于判斷數據是否存在;
統計客戶的預警次數,很顯然就是有著更新,沒有則新增;
INSERT INTO mybatis.my_cust_warn_tbl (rcrd_id, cust_num, cust_name, warn_times) VALUES('hand_11', 'hand_11_custnum', 'hand_11_custname', 0) on duplicate key update warn_times=warn_times+1, create_time = current_timestamp ;第一次執行上述sql,由于 hand_11_cust 不存在,則返回條數是1;
?第二次執行SQL如下 (注意,第一次與第二次的sql不一樣,主鍵不同,但客戶號相同,客戶號是唯一索引)
INSERT INTO mybatis.my_cust_warn_tbl (rcrd_id, cust_num, cust_name, warn_times) VALUES('hand_11_2', 'hand_11_custnum', 'hand_11_custname', 0) on duplicate key update warn_times=warn_times+1, create_time = current_timestamp ;由于 hand_11_cust 已經存在,更新條數返回2;
【1.2】replace into
1.replace顧名思義,替換,有則先刪除,后插入;沒有則直接插入;
步驟為:
- step1)delete 存在的記錄(通過主鍵或唯一索引來判斷);
- step2)重新插入新值;
為了演示效果,我們新建了一個主鍵自增的數據庫表;
drop table if exists my_cust_warn_autopk_tbl ; CREATE TABLE `my_cust_warn_autopk_tbl` (`rcrd_id` int primary key not null auto_increment COMMENT '記錄編號',`cust_num` varchar(50) NOT NULL COMMENT '客戶號',`cust_name` varchar(50) DEFAULT '' COMMENT '客戶姓名',`warn_times` int(11) DEFAULT NULL COMMENT '客戶預警次數',`create_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '創建時間',`last_modify_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '最后修改時間',UNIQUE KEY `uni_cust_num` (`cust_num`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='客戶預警表(自增)' ;2. 測試案例
REPLACE INTO mybatis.my_cust_warn_autopk_tbl (cust_num, cust_name, warn_times) VALUES('hand_12_custnum', 'hand_12_custname', 0) ;因為之前沒有存在的數據,故更新行數為1;
?剛剛插入的記錄的主鍵值為1 ; 如下;
?接著, 我們把客戶姓名字段設置為null看下; 發現更新行數為2;
REPLACE INTO mybatis.my_cust_warn_autopk_tbl (cust_num, cust_name, warn_times) VALUES('hand_12_custnum', null, 0) ;我們看下數據長什么樣子:僅有一個 主鍵值為2的記錄存在;
很顯然,因為存在客戶號為 hand_12_custnum的記錄,于是先刪除了 主鍵為1的記錄,然后再插入主鍵為2的記錄,如下:
?當然了,通過兩次sql的 create_time 也可以判斷出 第2次replace是 刪除舊記錄,然后重新新增一條數據,而不是在舊記錄上修改; 因為 兩次的create_time 不一樣;
【2】 兩者執行時間簡單對比
show variables like "%pro%"; set profiling=1; show profiles ;總結
以上是生活随笔為你收集整理的mysql duplicate key与replace into对比的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 三星i939电信版(三星i509电信版)
- 下一篇: (转)mysql查看连接客户端ip和杀死