CREATE TABLE `table_test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `my_key` int(11) NOT NULL DEFAULT '0', `value` varchar(21) NOT NULL DEFAULT '', `count` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`id`), UNIQUE KEY `my_key` (`my_key`), UNIQUE KEY `value` (`value`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8
對於這樣一個表.當要記錄my_key=1,value='a',count=0時,一般的處理流程是:先select,查看是否存在my_key=1的數據:如果有,則使用update進行更新;如果沒有,則使用insert進行插入。
(1) 上述操作流程可以歸納為: key存在則更新,不存在則插入,采用以下sql語句可以實現:
insert into .... on duplicate key update
注意:key需要是唯一索引。
對於需要根據原記錄進行操作的。如表中count字段用於計數,當沒有記錄時,插入的value為0;當有記錄時,value需要更新為value+1,sql語句為:
insert into table_test set my_key=1,value='a',value=1 on duplicate key update value=value+1;
(2) 不過在大並發量的數據操作時,可能有時一個有主鍵的select查詢耗時較長,如果對舊數據不關心,可以采用先disable即刪除原來my_key=1的數據,再插入新的數據。使用replace一個語句可以完成上述操縱流程的功能,其語法與insert差不多。可以寫為replace into table_test set ikey=1,value='a',icount=0;則表中有my_key=1時,先刪除舊數據,然后插入新數據.否則直接插入數據,sql語句如下:
replace into table_test set my_key=1,value='a',count=0;
需要注意的是:如果表中有多個唯一索引,例如:my_key和value字段都是unique key,replace會把所有與其唯一索引值相同的數據項刪除,再插入新記錄。如表中有兩個記錄,replace into table_test set my_key=5,value='c',count=0;會將兩條數據同時刪除再插入;
mysql> select * from table_test; +----+--------+-------+-------+ | id | my_key | value | count | +----+--------+-------+-------+ | 10 | 5 | a | 0 | | 11 | 3 | c | 0 | +----+--------+-------+-------+ 2 rows in set (0.04 sec)
mysql> replace into table_test set my_key=5,value='c',count=0; Query OK, 3 rows affected (0.04 sec) mysql> select * from table_test; +----+--------+-------+-------+ | id | my_key | value | count | +----+--------+-------+-------+ | 12 | 5 | c | 0 | +----+--------+-------+-------+ 1 row in set (0.04 sec)
(3)對比 replace into 和 insert into on duplicate key:
replace into table_test set my_key=1,value='a',count=0;會把表中的兩條記錄都刪除,然后插入新記錄;
而insert into table_test set my_key=1,value='a',count=0 on duplicate key update count=count+1則只更新一條記錄.其效果相當於
if (exist){
update table_test set count=count+1where my_key=1or value='a'limit1;
}else{
into table_test set my_key=1,value='a',count=0
}
replace into 跟 insert 功能類似,不同點在於:replace into 首先嘗試插入數據到表中, 1. 如果發現表中已經有此行數據(根據主鍵或者唯一索引判斷)則先刪除此行數據,然后插入新的數據。 2. 否則,直接插入新數據。
要注意的是:插入數據的表必須有主鍵或者是唯一索引!否則的話,replace into 會直接插入數據,這將導致表中出現重復的數據。
MySQL replace into 有三種形式:
1. replace into tbl_name(col_name, ...) values(...)
2. replace into tbl_name(col_name, ...) select ...
3. replace into tbl_name set col_name=value, ...
前兩種形式用的多些。其中 “into” 關鍵字可以省略,不過最好加上 “into”,這樣意思更加直觀。另外,對於那些沒有給予值的列,MySQL 將自動為這些列賦上默認值。
REPLACE INTO tb_test_replace SET id='456',busNo='貴456',plateColor='456',speed=45;