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語句只會對唯一鍵索引起作用)