1. 背景
場景: 向表admin插入一條數(shù)據,如果business_id字段如果有重復的,則is_update置為1
- create_sql
CREATE TABLE `admin` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主鍵',
`business_id` bigint(20) DEFAULT NULL COMMENT '業(yè)務id',
`name` varchar(64) NOT NULL DEFAULT '' COMMENT '名稱',
`is_update` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否修改 0否 1是',
PRIMARY KEY (`id`),
UNIQUE KEY `uq_name` (`name`),
UNIQUE KEY `uk_business_id` (`business_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='測試表';
2. 執(zhí)行sql
insert into admin(business_id) values (12345) on duplicate key update is_update = 1;
3. 發(fā)現(xiàn)問題
表中business_id有12345的重復數(shù)據,執(zhí)行之后發(fā)現(xiàn)執(zhí)行成功,但是該數(shù)據的is_update并沒有改變。
4. 過程分析
發(fā)現(xiàn)因為name字段是唯一索引,并且默認填充為'',所以只插入business_id,表中已經存在name為''的數(shù)據就會造成name重復導致插入失敗,而這個插入失敗并不是business_id字段重復造成的,所以就沒有is_update字段的更改。
- 由此分析出
unique key的異常級別高于duplicate key的重復判斷。執(zhí)行過程是先確保insert語句可執(zhí)行,之后再判斷duplicate key。insert操作異常反饋的重復字段如果不在sql中,則不會執(zhí)行后續(xù)的update。
5. 解決辦法
在執(zhí)行
insert duplicate key語句的時候,盡量使用主鍵作為判斷,主鍵的重復判斷優(yōu)先級比其他字段的unique key優(yōu)先級高,所以在執(zhí)行插入重復的時候能正常觸發(fā)update。