Mysql處理Duplicate entry ‘6‘ for key ‘PRIMARY‘問(wèn)題及解決
Mysql處理Duplicate entry ‘6‘ for key ‘PRIMARY‘
在業(yè)務(wù)中app和設(shè)備都需要調(diào)用ip查詢對(duì)應(yīng)城市的天氣接口,出現(xiàn)了ip這個(gè)唯一索引引起的插入沖突。
以前單系統(tǒng)處理這種主鍵沖突或唯一索引沖突,都是先查詢后插入。
使用 if-else語(yǔ)句,判斷dp_city是否存在,若存在則更新,不存在則插入。
if not exists (select ip from dp_city where ip = adress) ? ? ? insert into dp_city (ip ,name,...) values(adress,name,...) else ? ? ? update dp_city set name= 'name',... where ip = adress
但這樣寫不僅效率太差,每次都需要執(zhí)行兩條SQL語(yǔ)句,一條語(yǔ)句用來(lái)判斷dp_city是否在表中已經(jīng)存在,另一條語(yǔ)句用來(lái)插入或更新表中數(shù)據(jù)。
而且在高并發(fā)的場(chǎng)景下,兩個(gè)請(qǐng)求同一時(shí)刻都查到數(shù)據(jù)不存在,一個(gè)請(qǐng)求先插入數(shù)據(jù),另一個(gè)請(qǐng)求再插入數(shù)據(jù)時(shí)就會(huì)出現(xiàn)主鍵或索引沖突的異常,也不能保證原子性。
解決這個(gè)問(wèn)題最常規(guī)的做法是:加鎖
加數(shù)據(jù)庫(kù)悲觀鎖太影響性能;加數(shù)據(jù)庫(kù)樂(lè)觀鎖,基于版本號(hào)判斷,一般用于更新操作,像這種插入操作基本上不會(huì)用。
另一種辦法是使用redis加入基于redis的分布式鎖,鎖定已存在的ip。但也如果過(guò)度依賴redis,若是出現(xiàn)網(wǎng)絡(luò)超時(shí),服務(wù)就悲劇了。
那么有沒(méi)有更優(yōu)雅高效的方法呢,通過(guò)查閱資料,發(fā)現(xiàn)MySQL一條語(yǔ)句很好的解決了這個(gè)問(wèn)題:ON DUPLICATE KEY UPDATE
該語(yǔ)句的語(yǔ)法如下:
INSERT INTO tablename(field1,field2, field3, ...) VALUES(value1, value2, value3, ...) ON DUPLICATE KEY UPDATE field1=value1,field2=value2, field3=value3, ...;?
這個(gè)語(yǔ)法的目的是為了解決重復(fù)性,當(dāng)數(shù)據(jù)庫(kù)中存在某個(gè)記錄時(shí),執(zhí)行這條語(yǔ)句會(huì)更新它,而不存在這條記錄時(shí),會(huì)插入它。
該語(yǔ)句規(guī)則如下:
如果你插入的記錄導(dǎo)致一個(gè)UNIQUE索引或者primary key(主鍵)出現(xiàn)重復(fù),那么就會(huì)認(rèn)為該條記錄存在,則執(zhí)行update語(yǔ)句而不是insert語(yǔ)句,反之,則執(zhí)行insert語(yǔ)句而不是更新語(yǔ)句。
mysql1062錯(cuò)誤:Duplicate entry ‘...‘ for key ‘PRIMARY
問(wèn)題解釋
Duplicate entry ‘…’ for key ‘PRIMARY,即插入數(shù)據(jù)時(shí),要插入數(shù)據(jù)的主鍵數(shù)據(jù)(…)已經(jīng)存在,不能再重復(fù)添加了。
例:Duplicate entry ‘0’ for key ‘PRIMARY是指主鍵為0的數(shù)據(jù)已經(jīng)存在,不能再插入主鍵值為0的數(shù)據(jù)了。
問(wèn)題解決
在執(zhí)行插入操作insert前,可以先執(zhí)行一遍該主鍵值的查找操作select
【簡(jiǎn)單的來(lái)說(shuō),就是這個(gè)語(yǔ)句已經(jīng)執(zhí)行過(guò)了,無(wú)需重復(fù)執(zhí)行】
1062、1060報(bào)錯(cuò)都是一樣的


以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
MySQL表聚合與聯(lián)合查詢的實(shí)現(xiàn)
MySQL聚合與聯(lián)合查詢是數(shù)據(jù)庫(kù)查詢中常用的技術(shù),它們能夠從多個(gè)數(shù)據(jù)源中提取和組合數(shù)據(jù),以獲得有用的信息和結(jié)果,本文就來(lái)介紹下MySQL聚合與聯(lián)合查詢,感興趣的可以了解一下2023-10-10
MySQL數(shù)據(jù)庫(kù)連接異常匯總(值得收藏)
這篇文章主要介紹了MySQL數(shù)據(jù)庫(kù)連接異常匯總,幫助大家更好的理解和學(xué)習(xí)mysql,感興趣的朋友可以了解下2020-08-08
SQL Server 完整備份遇到的一個(gè)不常見(jiàn)的錯(cuò)誤及解決方法
這篇文章給大家介紹了SQL Server 完整備份遇到的一個(gè)不常見(jiàn)的錯(cuò)誤及解決方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2019-05-05
細(xì)談Mysql的存儲(chǔ)過(guò)程和存儲(chǔ)函數(shù)
存儲(chǔ)函數(shù)與存儲(chǔ)過(guò)程作用類同,不同的是存儲(chǔ)過(guò)程只能使用CALL語(yǔ)句來(lái)調(diào)用存儲(chǔ)過(guò)程,只能用輸出變量返回值,而存儲(chǔ)函數(shù)可以從語(yǔ)句外調(diào)用(即通過(guò)引用函數(shù)名),也能返回標(biāo)量值。下面小編給大家詳細(xì)講一講2019-05-05
詳解MySQL中事務(wù)隔離級(jí)別的實(shí)現(xiàn)原理
這篇文章主要介紹了MySQL中事務(wù)隔離級(jí)別的實(shí)現(xiàn)原理,幫助大家更好的理解和使用MySQL數(shù)據(jù)庫(kù),感興趣的朋友可以了解下2021-01-01
MySQL存儲(chǔ)過(guò)程的傳參和流程控制示例講解
這篇文章主要介紹了MySQL存儲(chǔ)過(guò)程的傳參和流程控制示例講解,?repeat和Loop區(qū)別是repeat有自己退出循環(huán)的語(yǔ)句until,Loop使用的是if判斷語(yǔ)句,本文結(jié)合示例代碼詳細(xì)講解,需要的朋友可以參考下2023-02-02

