需求:如果表中存在某行,那麼更新即可;不存在某行,那麼就新增一條。通常是將主鍵索引或唯一索引作爲判斷條件。
思路:可以使用Mysql的INSERT ... ON DUPLICATE KEY UPDATE或REPLACE或UPDATE實現。如果希望一條語句實現,可以考慮前兩種實現
創建一張表,表中包含自增Id和唯一索引email。
CREATE TABLE `user_info` (
`Id` smallint(6) NOT NULL AUTO_INCREMENT,
`email` varchar(10) NOT NULL DEFAULT '' COMMENT '郵箱',
`name` varchar(10) DEFAULT '' COMMENT '用戶名',
`phone` varchar(20) DEFAULT NULL COMMENT '手機號',
`desc` text COMMENT '備註',
PRIMARY KEY (`Id`),
UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 COMMENT='用戶信息表';
實現一:INSERT ... ON DUPLICATE KEY UPDATE
使用前提:需要有主鍵索引或唯一索引。
參考資料:https://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html(可以先查詢自己使用的Mysql版本,將鏈接中的5.7改爲自己的版本)
1)INSERT INTO user_info (`email`,`name`,`phone`) VALUES ('333','abcd','18292') ON DUPLICATE KEY UPDATE `name` = VALUES(`name`),`phone` = VALUES(`phone`);
說明:此句中會根據唯一索引email判斷user_info表中是否存在,不存在的話表中就會新加一條記錄;存在的話就執行UPDATE後面的語句name=abcd,phone=18292。注意了,假如表中已經存在該email,執行一次該語句,主鍵Id就會加1,好像就是先給表中新增一條,然後和有衝突的行進行合併,然後將新增的記錄刪除。可以根據圖中操作直觀感受,注意主鍵Id是不連續的。至於該語句執行後返回結果有0,1,2,可參考官網得到答案:With ON DUPLICATE KEY UPDATE, the affected-rows value per row is 1 if the row is inserted as a new row, 2 if an existing row is updated, and 0 if an existing row is set to its current values.
2)INSERT INTO user_info (`Id`,`desc`) VALUES ('5','hello world') ON DUPLICATE KEY UPDATE `desc` = VALUES(`desc`);
說明:此句會根據主鍵Id判斷user_info表中是否存在,不存在的話表中就會新加一條記錄;存在的話就執行UPDATE後面的語句desc=hello world。注意了,這裏與1)有所不同,不管表中是否存在該Id對應記錄,自增Id都不會加1。
3)如有需求在一句中有多個唯一索引等進行更新或新增,可詳見官網說明,不過一般需避免這種情況:In general, you should try to avoid using an ON DUPLICATE KEY UPDATE
clause on tables with multiple unique indexes。
實現二:REPLACE
爲了避免寫入重複數據,建議使用REPLACE時最好考慮唯一索引或主鍵索引的存在。
參考地址:https://dev.mysql.com/doc/refman/5.7/en/replace.html
1)REPLACE INTO user_info(`email`,`name`,`phone`) VALUES ('77777', 'yaya','2222');
可對比實現一,REPLACE的工作方式與INSERT完全相同,不同之處在於,如果表中的舊行與UNIQUE KEY的新行具有相同的值,則在插入新行之前會刪除該舊行。體會一下與實現一的1)的區別:該方式也會造成主鍵Id變化,不過是插入新行之前先刪除舊行。
2)REPLACE INTO user_info(`Id`,`desc`) VALUES (9, 'welcome');
說明:此句會根據主鍵Id判斷user_info表中是否存在,不存在的話表中就會新加一條記錄;存在的話就執行UPDATE後面的語句desc=welcome。注意了,這裏與1)有所不同,不管表中是否存在該Id對應記錄,自增Id都不會加1。
實現三:UPDATE
上面兩種實現都極有可能存在自增Id不連續的情況。
參考地址:https://dev.mysql.com/doc/refman/5.7/en/update.html
可以先使用UPDATE更新,不存在的話會返回影響行數0,可以判斷是不存在該記錄的,可以繼續INSERT INTO;存在的話會更新同時返回影響行數。