MySQL:插入更新语句 ON DUPLICATE KEY UPDATE

- 日理万妓 2023-06-20 11:59 154阅读 0赞

建立一张表node_status:

  1. +--------------+--------------+------+-----+---------+-------+
  2. | Field | Type | Null | Key | Default | Extra |
  3. +--------------+--------------+------+-----+---------+-------+
  4. | node_name | varchar(100) | NO | PRI | NULL | |
  5. | ip | varchar(100) | NO | | NULL | |
  6. | site | varchar(100) | NO | | NULL | |
  7. | frp_num | int(11) | NO | | NULL | |
  8. | home_free | bigint(20) | NO | | NULL | |
  9. | mem_use | varchar(100) | NO | | NULL | |
  10. | last_time | datetime | NO | | NULL | |
  11. | modify_time | datetime | NO | | NULL | |
  12. +--------------+--------------+------+-----+---------+-------+

该表中,将node_name即节点主机名称设为PRIMARY KEY。

一开始只是想到了用 if else 语句,判断主键是否存在,存在则更新,不存在则插入。

  1. if not exists (select node_name from node_status where node_name = target_name)
  2. insert into node_status(node_name,ip,...) values('target_name','ip',...)
  3. else
  4. update node_status set ip = 'ip',site = 'site',... where node_name = target_name

但是这么写出来,出现了两个问题:
1、效率太差,每次都需要执行两条SQL语句,一条语句用来判断node_name是否在表中已经存在,另一条语句用来插入或更新表中数据。
2、高并发的情况下数据会出问题,不能保证原子性。

那么有没有更优雅高效的方法呢,通过查阅资料,发现MySQL一条语句很好的解决了这个问题:ON DUPLICATE KEY UPDATE
该语句的语法如下:

  1. INSERT INTO tablename(field1,field2, field3, ...) VALUES(value1, value2, value3, ...) ONDUPLICATE KEY UPDATE field1=value1,field2=value2, field3=value3, ...;

这个语法的目的是为了解决重复性,当数据库中存在某个记录时,执行这条语句会更新它,而不存在这条记录时,会插入它。
该语句规则如下:如果你插入的记录导致一个UNIQUE索引或者primary key(主键)出现重复,那么就会认为该条记录存在,则执行update语句而不是insert语句,反之,则执行insert语句而不是更新语句。得到了这个插入语句的”八倍镜“,我们可以将原来那个很LOW的方式替换掉了:

  1. sql = """ INSERT INTO node_status(node_name,ip,site,frp_num, \
  2. + home_free,mem_use,last_time,modify_time) \
  3. + VALUES('%s','%s','%s','%d','%d','%s','%s','%s') \
  4. + ON DUPLICATE KEY UPDATE \
  5. + ip='%s', site='%s',frp_num='%d',home_free='%d', \
  6. + mem_use='%s',last_time='%s',modify_time='%s' """ % \
  7. + (id_value['host'], ip, site, frp_num, home_size, mem_use, last_time, modify_time),
  8. + ip, site, frp_num, home_size, mem_use, last_time, modify_time)

源:https://segmentfault.com/a/1190000014306692

发表评论

表情:
评论列表 (有 0 条评论,154人围观)

还没有评论,来说两句吧...

相关阅读