為了應對這種業務場景,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 語法的原因:
1、replace into 遇到已存在的記錄,會先刪除掉表中原有的記錄后,再插入新的記錄,
這樣會導致該記錄的主鍵發生變化,如果該表的主鍵和其它表有業務關聯,那么會導致關聯數據丟失。
2、replace into 插入的主鍵在某些時候不是連續自增的,這樣會導致主鍵增長的數據很快,有時候會超過 int(10) 的最大值