平時我們在設計數據庫表的時候總會設計 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;


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都是唯一索引,插入的數據在兩條記錄上產生了沖突,然而執行后只有第一條記錄被修改