在《調用ZABBIX的API獲取節點主機信息小記》(傳送門:https://segmentfault.com/a/11...)這篇博客中,簡單闡述瞭如何利用zabbix-api庫來獲取ZABBIX監控各節點主機的信息。須要將獲取的信息錄入數據庫,因爲節點數目不斷增長,所以插入數據庫時,要判斷節點主機是否存在,存在則更新各主機信息,不存在則插入。node
首先須要創建一張表node_status:sql
+--------------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------------+--------------+------+-----+---------+-------+ | node_name | varchar(100) | NO | PRI | NULL | | | ip | varchar(100) | NO | | NULL | | | site | varchar(100) | NO | | NULL | | | frp_num | int(11) | NO | | NULL | | | home_free | bigint(20) | NO | | NULL | | | mem_use | varchar(100) | NO | | NULL | | | last_time | datetime | NO | | NULL | | | modify_time | datetime | NO | | NULL | | +--------------+--------------+------+-----+---------+-------+
該表中,將node_name即節點主機名稱設爲PRIMARY KEY。數據庫
一開始只是想到了用 if-else語句,判斷node_name是否存在,存在則更新,不存在則插入。segmentfault
if not exists (select node_name from node_status where node_name = target_name) insert into node_status(node_name,ip,...) values('target_name','ip',...) else update node_status set ip = 'ip',site = 'site',... where node_name = target_name
可是這麼寫出來,出現了兩個問題:
一、效率太差,每次都須要執行兩條SQL語句,一條語句用來判斷node_name是否在表中已經存在,另外一條語句用來插入或更新表中數據。
二、高併發的狀況下數據會出問題,不能保證原子性。api
那麼有沒有更優雅高效的方法呢,經過查閱資料,發現MySQL一條語句很好的解決了這個問題:ON DUPLICATE KEY UPDATE
該語句的語法以下:併發
INSERT INTO tablename(field1,field2, field3, ...) VALUES(value1, value2, value3, ...) ON DUPLICATE KEY UPDATE field1=value1,field2=value2, field3=value3, ...;
這個語法的目的是爲了解決重複性,當數據庫中存在某個記錄時,執行這條語句會更新它,而不存在這條記錄時,會插入它。
該語句規則以下:若是你插入的記錄致使一個UNIQUE索引或者primary key(主鍵)出現重複,那麼就會認爲該條記錄存在,則執行update語句而不是insert語句,反之,則執行insert語句而不是更新語句。
獲得了這個插入語句的」八倍鏡「,咱們能夠將原來那個很LOW的方式替換掉了:高併發
sql = """ INSERT INTO node_status(node_name,ip,site,frp_num, \ + home_free,mem_use,last_time,modify_time) \ + VALUES('%s','%s','%s','%d','%d','%s','%s','%s') \ + ON DUPLICATE KEY UPDATE \ + ip='%s', site='%s',frp_num='%d',home_free='%d', \ + mem_use='%s',last_time='%s',modify_time='%s' """ % \ + (id_value['host'], ip, site, frp_num, home_size, mem_use, last_time, modify_time), + (ip, site, frp_num, home_size, mem_use, last_time, modify_time)
一、https://blog.csdn.net/analogo...
二、https://blog.csdn.net/woshiha....net