MySQL_插入更新 ON DUPLICATE KEY UPDATE

bingguang1993發表於2018-05-07

平時我們在設計資料庫表的時候總會設計 unique  或者 給表加上 primary key 的限制條件.


此時 插入資料的時候 ,經常會有這樣的情況:

我們想向資料庫插入一條記錄:

  若資料表中存在以相同主鍵的記錄,我們就更新該條記錄。

  否則就插入一條新的記錄。


邏輯上我們需要怎麼寫:

$result = mysql_query('select * from xxx where id = 1');
$row = mysql_fetch_assoc($result);
if($row){
mysql_query('update ...');
}else{
mysql_query('insert ...');
}


但是這樣寫有兩個問題

1、效率太差,每次執行都要執行2個sql
2、高併發的情況下資料會出問題,不能保證原子性 


還好MySQL 為我們解決了這個問題:我們可以通過 ON DUPLICATE KEY UPDATE  達到以上目的, 且能保證操作的原子性和資料的完整性。


ON DUPLICATE KEY UPDATE 可以達到以下目的:

向資料庫中插入一條記錄:

若該資料的主鍵值/ UNIQUE KEY 已經在表中存在,則執行更新操作, 即UPDATE 後面的操作。

否則插入一條新的記錄。


示例:


Step1 . 建立表,插入測試資料

SET FOREIGN_KEY_CHECKS=0;


-- ----------------------------
-- Table structure for mRowUpdate
-- ----------------------------
DROP TABLE IF EXISTS `mRowUpdate`;
CREATE TABLE `mRowUpdate` (
  `id` int(11) NOT NULL,
  `value` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;


-- ----------------------------
-- Records of mRowUpdate
-- ----------------------------
INSERT INTO `mRowUpdate` VALUES ('1', 'sss');
INSERT INTO `mRowUpdate` VALUES ('2', 'szh');
INSERT INTO `mRowUpdate` VALUES ('3', '9999');
SET FOREIGN_KEY_CHECKS=1;





Step2 .測試 ON DUPLICATE KEY UPDATE 的使用方法:


INSERT INTO mRowUpdate(id,`value`) VALUES(3, 'SuperMan') ON DUPLICATE KEY UPDATE `value`='SuperMan';





Step3. 查詢資料的變化情況










==========================     話外篇   ===============================


技巧:

技巧 1 :

ON DUPLICATE KEY UPDATE 特別適用於多行插入。如:

INSERT INTO `table` (`a`, `b`, `c`) VALUES (1, 2, 3), (4, 5, 6) ON DUPLICATE KEY UPDATE `c`=VALUES(`a`)+VALUES(`b`);

          Tips: VALUES()函式只在INSERT…UPDATE語句中有意義,其它時候會返回NULL。





注意事項:

注意 1:

若多個索引都衝突,則只有一條記錄被修改。


create table test(
id int not null primary key,
num int not null UNIQUE key,
tid int not null
)
為了測試兩個唯一索引都衝突的情況,然後插入下面的資料


insert into test values(1,1,1), (2,2,2);
然後執行:


insert into test values(1,2,3) on duplicate key update tid = tid + 1;
因為a和b都是唯一索引,插入的資料在兩條記錄上產生了衝突,然而執行後只有第一條記錄被修改





相關文章