Mysql 5.7实现存在则更新,不存在则新增

需求:如果表中存在某行,那么更新即可;不存在某行,那么就新增一条。通常是将主键索引或唯一索引作为判断条件。

思路:可以使用Mysql的INSERT ... ON DUPLICATE KEY UPDATEREPLACEUPDATE实现。如果希望一条语句实现,可以考虑前两种实现

创建一张表,表中包含自增Id和唯一索引email。

CREATE TABLE `user_info` (
  `Id` smallint(6) NOT NULL AUTO_INCREMENT,
  `email` varchar(10) NOT NULL DEFAULT '' COMMENT '邮箱',
  `name` varchar(10) DEFAULT '' COMMENT '用户名',
  `phone` varchar(20) DEFAULT NULL COMMENT '手机号',
  `desc` text COMMENT '备注',
  PRIMARY KEY (`Id`),
  UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 COMMENT='用户信息表';

实现一:INSERT ... ON DUPLICATE KEY UPDATE

使用前提:需要有主键索引或唯一索引。

参考资料:https://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html(可以先查询自己使用的Mysql版本,将链接中的5.7改为自己的版本)

1)INSERT INTO user_info (`email`,`name`,`phone`) VALUES ('333','abcd','18292')  ON DUPLICATE KEY UPDATE `name` = VALUES(`name`),`phone` = VALUES(`phone`); 

说明:此句中会根据唯一索引email判断user_info表中是否存在,不存在的话表中就会新加一条记录;存在的话就执行UPDATE后面的语句name=abcd,phone=18292。注意了假如表中已经存在该email,执行一次该语句,主键Id就会加1,好像就是先给表中新增一条,然后和有冲突的行进行合并,然后将新增的记录删除。可以根据图中操作直观感受,注意主键Id是不连续的。至于该语句执行后返回结果有0,1,2,可参考官网得到答案:With ON DUPLICATE KEY UPDATE, the affected-rows value per row is 1 if the row is inserted as a new row, 2 if an existing row is updated, and 0 if an existing row is set to its current values.

2)INSERT INTO user_info (`Id`,`desc`) VALUES ('5','hello world') ON DUPLICATE KEY UPDATE `desc` = VALUES(`desc`);

说明:此句会根据主键Id判断user_info表中是否存在,不存在的话表中就会新加一条记录;存在的话就执行UPDATE后面的语句desc=hello world。注意了,这里与1)有所不同,不管表中是否存在该Id对应记录,自增Id都不会加1。

3)如有需求在一句中有多个唯一索引等进行更新或新增,可详见官网说明,不过一般需避免这种情况:In general, you should try to avoid using an ON DUPLICATE KEY UPDATE clause on tables with multiple unique indexes。

实现二:REPLACE

为了避免写入重复数据,建议使用REPLACE时最好考虑唯一索引或主键索引的存在。

参考地址:https://dev.mysql.com/doc/refman/5.7/en/replace.html

1)REPLACE INTO user_info(`email`,`name`,`phone`) VALUES ('77777', 'yaya','2222');

可对比实现一,REPLACE的工作方式与INSERT完全相同,不同之处在于,如果表中的旧行与UNIQUE KEY的新行具有相同的值,则在插入新行之前会删除该旧行。体会一下与实现一的1)的区别:该方式也会造成主键Id变化,不过是插入新行之前先删除旧行。

2)REPLACE INTO user_info(`Id`,`desc`) VALUES (9, 'welcome');

说明:此句会根据主键Id判断user_info表中是否存在,不存在的话表中就会新加一条记录;存在的话就执行UPDATE后面的语句desc=welcome。注意了,这里与1)有所不同,不管表中是否存在该Id对应记录,自增Id都不会加1。

实现三:UPDATE

上面两种实现都极有可能存在自增Id不连续的情况。

参考地址:https://dev.mysql.com/doc/refman/5.7/en/update.html

可以先使用UPDATE更新,不存在的话会返回影响行数0,可以判断是不存在该记录的,可以继续INSERT INTO;存在的话会更新同时返回影响行数。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章