MySQL on duplicate key update 批量插入並更新已存在數據


業務上經常存在一種現象,需要批量往表中插入多條數據,但在執行過程中,很可能因為唯一鍵沖突,而導致批量插入失敗。
因此需要事先判斷哪些數據是重復的,哪些是新增的。
比較常用的處理方法就是找出已存在的數據,並將其與不存在的數據區分開,已存在的數據一條條的更新。不存在的數據則批量更新。
這種方法會導致代碼邏輯復雜,同時嚴重降低代碼效率。
為了應對這種業務場景,MySQL有一種專有語法(insert into ... on duplicate key update)批量插入並更新唯一鍵數據

CREATE TABLE `user_card` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主鍵',
  `uid` int(10) DEFAULT '0' COMMENT '用戶ID',
  `grade_id` int(10) DEFAULT '0' COMMENT '等級ID',
  `name` varchar(255) DEFAULT '' COMMENT '姓名',
  `money` decimal(10,2) DEFAULT '0.00' COMMENT '余額',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uid_gid` (`uid`,`grade_id`)    -- 業務上的唯一鍵
) ENGINE=INNODB DEFAULT CHARSET=utf8 ;

如上圖所示,批量插入的數據,遇到已存在記錄(根據唯一鍵,創表語句中的 UNIQUE KEY 判斷)時,自動更新已有的數據。
其中 money字段 以數據庫現有值為准不進行更新, name字段使用了關鍵字 VALUES() 以外部值為准進行更新。
如果表中有多個唯一鍵(可以是單列索引或復合索引),則任意一個唯一鍵(UNIQUE KEY)沖突時,都會自動更新數據。
通過 on duplicate key update 語法,可以指定哪些字段進行更新,哪些字段不進行更新。
所有操作均由SQL處理,不需要額外程序代碼分析,能夠大幅提高程序執行效率。

P.S:補充下不使用 replace into 語法的原因:
1replace into 遇到已存在的記錄,會先刪除掉表中原有的記錄后,再插入新的記錄,
這樣會導致該記錄的主鍵發生變化,如果該表的主鍵和其它表有業務關聯,那么會導致關聯數據丟失。
2replace into 插入的主鍵在某些時候不是連續自增的,這樣會導致主鍵增長的數據很快,有時候會超過 int(10) 的最大值


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM