平时我们在设计数据库表的时候总会设计 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 ...'); }
但是这样写有两个问题
- 效率太差,每次执行都要执行2个sql
- 高并发的情况下数据会出问题,不能保证原子性
还好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;
INSERT INTO mRowUpdate(id,`value`) VALUES(3, 'SuperMan') ON DUPLICATE KEY UPDATE `value`='SuperMan';
INSERT INTO `table` (`a`, `b`, `c`) VALUES (1, 2, 3), (4, 5, 6) ON DUPLICATE KEY UPDATE `c`=VALUES(`a`)+VALUES(`b`);
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;