1. 程式人生 > 其它 >mysql、mybatis ON DUPLICATE KEY UPDATE

mysql、mybatis ON DUPLICATE KEY UPDATE

技術標籤:JAVA開發SQLmybatismysqlsql索引

1.首先建立表

CREATE TABLE `test_table` (  
  `id`  int(11) NOT NULL AUTO_INCREMENT ,  
  `var1`  varchar(100) CHARACTER SET utf8 DEFAULT NULL,  
  `var2`  tinyint(1) NOT NULL DEFAULT '0',  
  `var3`  varchar(100) character set utf8 default NULL, 
  `value1`  int(11) NOT NULL DEFAULT '1',  
  `value2`  int(11) NULL DEFAULT NULL,  
  `value3`  int(5) DEFAULT NULL,  
  PRIMARY KEY (`Id`),  
  UNIQUE INDEX `index_var` (`var1`, `var2`, `var3`)  
) ENGINE=MyISAM DEFAULT CHARACTER SET=latin1 AUTO_INCREMENT=1;

先建立一個表,並將表中var1、var2、var3這三個欄位組成一個唯一索引

2.進行測試

執行如下insert into table on duplicate key update語句

INSERT INTO `test_table`   
(`var1`, `var2`, `var3`, `value1`, `value2`, `value3`) VALUES  
('abcd', 2, 'xyz', 1, 2, 3)   
ON DUPLICATE KEY UPDATE value1=2,value2=3,value3=5;

第一次執行時,首先會在資料庫中插入資料,結果如下
在這裡插入圖片描述
再次執行這條語句,結果如下

在這裡插入圖片描述

結果很明顯,並沒有新插入一條資料,而是在原有資料的基礎上進行了更新,更新的欄位為UPDATE後面的欄位。
再次進行試驗

INSERT INTO `test_table`   
(`var1`, `var2`, `var3`, `value1`, `value2`, `value3`) VALUES  
('abcd', 5, 'xyz', 1, 2, 3)   
ON DUPLICATE KEY UPDATE value1=2,value2=3,value3=5;

改變唯一索引(var1、var2、var3)這三個欄位中的任意一個欄位,或者三個欄位都改變,則會往資料庫中新插入一條資料
在這裡插入圖片描述
結論


使用該條語句時,如果唯一索引的值被改變,那麼就會向資料庫中新插入資料,如果唯一索引的值沒有改變,則會修改原來資料的值,修改值為UPDATE後面指定的值

2.1.再次測試

如果在增加一個唯一索引,這個唯一索引由var1、var2、var3、var4這四個欄位組成呢?

//先給表增加一列
alter table test_table add var4 varchar(100)
//建立唯一索引
alter table test_table add UNIQUE INDEX var1_4 (var1,var2,var3,var4)

(1)這個時候,在進行測試,如果改變var1、var2、var3之中的任意一個值,那麼毫無疑問會新插入資料,因為這滿足了修改了唯一索引,但是,如果該改變了var4呢,經過實驗後,發現不起作用,也就是說,它只會將var4當作普通欄位,在var1、var2、var3不變的情況下,不會新插入資料,只會修改原來的資料;

INSERT INTO `test_table`   
(`var1`, `var2`, `var3`,`var4`, `value1`, `value2`, `value3`) VALUES  
('abcd', 5, 'xyz','k', 1, 2, 3)   
ON DUPLICATE KEY UPDATE value1=2,value2=3,value3=5;

這個結果,沒有在資料庫中新插入資料,也沒有更新原來的資料,因為var4的值沒有寫在UPDATE後面
(2)進一步測試,改變var1、var2、var3、var4建立唯一索引的順序

alter table test_table add UNIQUE INDEX var4_1 (var4,var2,var3,var1);

經過測試發現,還是跟上面結果一樣,將var4當成了普通欄位,知修改var4的情況下,不會插入資料,只會修改資料(注意:修改的資料一律是UPDATE後面的資料,在不插入的情況下var4的值不會改變依然是空值,因為var4欄位沒有寫在UPDATE後面)
(3)最終測試,將第一次那三個欄位建立的索引刪除掉,現在還有兩個四個欄位組成的唯一索引,這個時候,只要是修改var1-var4任意一個欄位的值,都會進行資料的新增,var1-var4的值沒有改變,只會修改資料
最終結論
如果有多個欄位組成的唯一索引,修改其中一個值都會導致新資料的插入;如果新建立了一個唯一索引包含了原來索引的所有欄位(在欄位層面可以看作包含了原來索引的所有欄位,也就是原來索引的父集),那麼後面這個新建立的索引比前面那個索引多出的欄位,跟普通欄位一樣不會起到任何作用。如果想要建立唯一索引,並且這個新建索引的所有欄位,都包含在第一個唯一索引裡面(在欄位層面可以看作為第一個索引的子集),這個時候,就會提示建立索引失敗。

3.應用場景

主要應用在:
有些欄位沒有更新時,則更新資料;例如在在主鍵id不變的情況下,使用該條sql插入的資料都會變成更新,如果主鍵有變化,則會新增資料。(因為主鍵也是唯一鍵,這條sql語句只會對唯一鍵索引起作用)