MySQL记录存在则更新,不存在则插入

本文介绍了一种在MySQL中实现记录存在则更新,不存在则插入的方法。通过创建包含唯一约束的表,并利用ON DUPLICATE KEY UPDATE子句来实现这一功能。
Sql代码   收藏代码
  1. CREATE TABLE `tb_file_authorize` (  
  2.   `authorize_id` int(11) NOT NULL auto_increment,  
  3.   `str_id` int(11) default NULL COMMENT '用户标识',  
  4.   `file_id` int(11) default NULL COMMENT '文件标识',  
  5.   `right_id` int(11) default NULL COMMENT '权限标识',  
  6.   `catalog_id` int(11) default NULL COMMENT '目录标识',  
  7.   `catalog_index` varchar(100) character set utf8 collate utf8_bin default NULL COMMENT '目录索引标识',  
  8.   `expired_date` varchar(30) default NULL COMMENT '过期时间',  
  9.   `limit_times` int(11) default NULL COMMENT '限制次数',  
  10.   `open_times` int(11) default NULL COMMENT '已经打开次数',  
  11.   `start_date` varchar(30) default NULL COMMENT '开始时间',  
  12.   `end_date` varchar(30) default NULL COMMENT '结束时间',  
  13.   `grant_user` varchar(30) default NULL,  
  14.   PRIMARY KEY  (`authorize_id`),  
  15.   KEY `file_right_index` (`str_id`,`file_id`),  
  16.   UNIQUE KEY `update_or_insert` (`str_id`,`file_id`)  
  17. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;  

 

我遇到的问题:

   str_id标识用户的唯一标识,fiile_id为文件的唯一标识,此表为中间表str_id,与file_id确定right_id

当该表中存在str_id与file_id的记录时,更新right_id,否则插入一条新的记录,SQL语句如下:

 

Java代码   收藏代码
  1. INSERT into tb_file_authorize(str_id,file_id,right_id,catalog_id,catalog_index)  
  2. values ('35','20','2048','1','1') ON DUPLICATE KEY UPDATE right_id='1024'  

 

此sql的意思判断是否存在str_id为30,file_id为20的记录,存在则更新right_id为1024,否则插入新的记录.

 

注意:使用该方法,建表的时候要定义 UNIQUE KEY `update_or_insert` (`str_id`,`file_id`),这样才能保证语句能够正常执行。

MySQL 中实现存在更新存在插入操作并保证原子性,可采用以下方法: ### 使用 INSERT ... ON DUPLICATE KEY UPDATE 如果表中存在唯一索引或主键,当插入数据时遇到唯一键冲突,可使用 `INSERT ... ON DUPLICATE KEY UPDATE` 语句。示例如下,以引用[3]中的 `news_visite` 表为例: ```sql INSERT INTO news_visite (news_id, user_id, read_time) VALUES (1, 2, NOW()) ON DUPLICATE KEY UPDATE read_time = NOW(); ``` 在这个例子里,若 `news_id` 和 `user_id` 的组合在 `news_visite` 表中存在,就会插入一条新记录;若已存在,则会更新 `read_time` 字段。该语句本身就是原子操作,MySQL 会自动处理插入更新,保证操作的原子性。 ### 使用事务结合 `SELECT ... FOR UPDATE` 通过事务和 `SELECT ... FOR UPDATE` 可以实现存在更新存在插入并保证原子性。示例代码如下: ```sql START TRANSACTION; SELECT * FROM news_visite WHERE news_id = 1 AND user_id = 2 FOR UPDATE; -- 检查查询结果 IF ROW_COUNT() = 0 THEN INSERT INTO news_visite (news_id, user_id, read_time) VALUES (1, 2, NOW()); ELSE UPDATE news_visite SET read_time = NOW() WHERE news_id = 1 AND user_id = 2; END IF; COMMIT; ``` `START TRANSACTION` 开启一个事务,`SELECT ... FOR UPDATE` 对查询到的行加排它锁,防止其他事务修改这些行。若记录存在插入,若存在更新,最后 `COMMIT` 提交事务,从而保证操作的原子性。 ### 使用 INSERT ... SELECT ... WHERE NOT EXISTS 在插入之前先进行一次查询,确认数据存在后再插入,结合事务和适当的锁定机制确保操作作为一个原子操作完成。示例如下: ```sql START TRANSACTION; IF NOT EXISTS (SELECT * FROM news_visite WHERE news_id = 1 AND user_id = 2) THEN INSERT INTO news_visite (news_id, user_id, read_time) VALUES (1, 2, NOW()); ELSE UPDATE news_visite SET read_time = NOW() WHERE news_id = 1 AND user_id = 2; END IF; COMMIT; ``` 此方法同样利用事务保证操作的原子性,在事务中先检查记录是否存在,再进行相应的插入更新操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值