mysql如何防止插入相同數(shù)據(jù)
一、建唯一索引的方式
mysql在存在主鍵沖突或者唯一鍵沖突的情況下,根據(jù)插入策略不同,一般有以下三種避免方法
- insert ignore
- replace into
- insert on duplicate key update
注意:除非表有一個(gè)PRIMARY KEY或UNIQUE索引,否則,使用以上三個(gè)語(yǔ)句沒(méi)有意義,與使用單純的INSERT INTO相同
表結(jié)構(gòu)
CREATE TABLE `ups_lower_electricity_data` ( `id` int(11) NOT NULL AUTO_INCREMENT, `componentInstanceId` int(11) DEFAULT NULL, `startTime` bigint(20) DEFAULT NULL, `endTime` bigint(20) DEFAULT NULL, `type` int(4) DEFAULT NULL, `electricity` decimal(8,2) DEFAULT NULL, `year` int(20) DEFAULT NULL, `month` int(20) DEFAULT NULL, `day` int(20) DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=164 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

insert ignore
insert ignore會(huì)忽略數(shù)據(jù)庫(kù)中已經(jīng)存在的數(shù)據(jù)(根據(jù)主鍵或者唯一索引判斷),如果數(shù)據(jù)庫(kù)沒(méi)有數(shù)據(jù),就插入新的數(shù)據(jù),如果有數(shù)據(jù)的話(huà)就跳過(guò)這條數(shù)據(jù)
沒(méi)有建索引插入
insert into ups_lower_electricity_data (componentInstanceId,startTime,endTime,type,electricity,year,month,day) values (499,1664121600000,1664146800000,3,18.00,2022,9,26)

建立索引進(jìn)行插入

insert ignore into ups_lower_electricity_data (componentInstanceId,startTime,endTime,type,electricity,year,month,day) values (499,1664121600000,1664146800000,3,18.00,2022,9,26)

replace into
replace into 首先嘗試插入數(shù)據(jù)到表中。 如果發(fā)現(xiàn)表中已經(jīng)有此行數(shù)據(jù)(根據(jù)主鍵或者唯一索引判斷)則先刪除此行數(shù)據(jù),然后插入新的數(shù)據(jù),否則,直接插入新數(shù)據(jù)
使用replace into,你必須具有delete和insert權(quán)限
replace into ups_lower_electricity_data (componentInstanceId,startTime,endTime,type,electricity,year,month,day) values (499,1664294400000,1664319600000,3,22.00,2022,9,28)

insert on duplicate key update
如果在insert into 語(yǔ)句末尾指定了on duplicate key update,并且插入行后會(huì)導(dǎo)致在一個(gè)UNIQUE索引或PRIMARY KEY中出現(xiàn)重復(fù)值,則在出現(xiàn)重復(fù)值的行執(zhí)行UPDATE;如果不會(huì)導(dǎo)致重復(fù)的問(wèn)題,則插入新行,跟普通的insert into一樣
使用insert into,你必須具有insert和update權(quán)限
如果有新記錄被插入,則受影響行的值顯示1;如果原有的記錄被更新,則受影響行的值顯示2;如果記錄被更新前后值是一樣的,則受影響行數(shù)的值顯示0
insert into ups_lower_electricity_data (componentInstanceId,startTime,endTime,type,electricity,year,month,day) values (499,1664294400000,1664319600000,3,22.00,2022,9,28) on duplicate key update day = day+1

INSERT…ON DUPLICATE KEY UPDATE產(chǎn)生死鎖
insert … on duplicate key 在執(zhí)行時(shí),innodb引擎會(huì)先判斷插入的行是否產(chǎn)生重復(fù)key錯(cuò)誤, 如果存在,在對(duì)該現(xiàn)有的行加上S(共享鎖)鎖,如果返回該行數(shù)據(jù)給mysql,然后mysql執(zhí)行完duplicate后的update操作, 然后對(duì)該記錄加上X(排他鎖),最后進(jìn)行update寫(xiě)入。
如果有兩個(gè)事務(wù)并發(fā)的執(zhí)行同樣的語(yǔ)句, 那么就會(huì)產(chǎn)生death lock,如:

解決辦法:
- 1、盡量對(duì)存在多個(gè)唯一鍵的table使用該語(yǔ)句
- 2、在有可能有并發(fā)事務(wù)執(zhí)行的insert 的內(nèi)容一樣情況下不使用該語(yǔ)句
結(jié)論:
- 這三種方法都能避免主鍵或者唯一索引重復(fù)導(dǎo)致的插入失敗問(wèn)題。
- insert ignore能忽略重復(fù)數(shù)據(jù),只插入不重復(fù)的數(shù)據(jù)。
- replace into和insert … on duplicate key update,都是替換原有的重復(fù)數(shù)據(jù),區(qū)別在于replace into是刪除原有的行后,在插入新行,如有自增id,這個(gè)會(huì)造成自增id的改變;insert … on duplicate key update在遇到重復(fù)行時(shí),會(huì)直接更新原有的行,具體更新哪些字段怎么更新,取決于update后的語(yǔ)句
二、INSERT INTO IF EXISTS
語(yǔ)法
INSERT INTO TABLE (field1, field2, fieldn) SELECT 'field1', 'field2', 'fieldn' FROM DUAL WHERE NOT EXISTS ( SELECT field FROM TABLE WHERE field = ? )
第一次執(zhí)行:Affected rows: 1,之后執(zhí)行都是Affected rows: 0,說(shuō)明實(shí)現(xiàn)了單條記錄的防重插入

總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
徹底搞懂?dāng)?shù)據(jù)庫(kù)操作truncate delete drop關(guān)鍵詞的區(qū)別
這篇文章主要為大家介紹了數(shù)據(jù)庫(kù)操作truncate delete drop關(guān)鍵詞的區(qū)別,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09
mybatis分頁(yè)插件pageHelper詳解及簡(jiǎn)單實(shí)例
這篇文章主要介紹了mybatis分頁(yè)插件pageHelper詳解及簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-05-05
MySQL的CONCAT函數(shù)實(shí)現(xiàn)方案
本文系統(tǒng)分析MySQL中的CONCAT字符串拼接函數(shù),從基礎(chǔ)語(yǔ)法、與CONCAT_WS的本質(zhì)區(qū)別、典型應(yīng)用場(chǎng)景到高級(jí)優(yōu)化策略,重點(diǎn)探討CONCAT的空值處理機(jī)制,感興趣的朋友跟隨小編一起看看吧2025-11-11
mysql和hive中幾種關(guān)聯(lián)(join/union)區(qū)別及說(shuō)明
本文主要介紹了MySQL和Hive中各種連接和合并操作的用法,包括INNER JOIN、LEFT JOIN、RIGHT JOIN、LEFT SEMI JOIN以及UNION和UNION ALL,同時(shí),也提到了Hive在處理連接時(shí)的一些特殊規(guī)則和限制2025-11-11
mysql too many open connections問(wèn)題解決方法
這篇文章主要介紹了mysql too many open connections問(wèn)題解決方法,其實(shí)是max_connections配置問(wèn)題導(dǎo)致,它必須在[mysqld]下面才會(huì)生效,需要的朋友可以參考下2014-05-05
MySQL配置文件my.cnf中文詳解附mysql性能優(yōu)化方法分享
Mysql參數(shù)優(yōu)化對(duì)于新手來(lái)講,是比較難懂的東西,其實(shí)這個(gè)參數(shù)優(yōu)化,是個(gè)很復(fù)雜的東西,對(duì)于不同的網(wǎng)站,及其在線(xiàn)量,訪(fǎng)問(wèn)量,帖子數(shù)量,網(wǎng)絡(luò)情況,以及機(jī)器硬件配置都有關(guān)系,優(yōu)化不可能一次性完成,需要不斷的觀(guān)察以及調(diào)試,才有可能得到最佳效果。2011-09-09
千萬(wàn)級(jí)用戶(hù)系統(tǒng)SQL調(diào)優(yōu)實(shí)戰(zhàn)分享
這篇文章主要介紹了千萬(wàn)級(jí)用戶(hù)系統(tǒng)SQL調(diào)優(yōu)實(shí)戰(zhàn)分享,用戶(hù)日活百萬(wàn)級(jí),注冊(cè)用戶(hù)千萬(wàn)級(jí),而且若還沒(méi)有進(jìn)行分庫(kù)分表,則該DB里的用戶(hù)表可能就一張,單表上千萬(wàn)的用戶(hù)數(shù)據(jù),下面我們就來(lái)學(xué)習(xí)如何讓優(yōu)化,需要的朋友可以參考一下2022-03-03
5招帶你輕松優(yōu)化MySQL count(*)查詢(xún)性能
最近在公司優(yōu)化了幾個(gè)慢查詢(xún)接口的性能,總結(jié)了一些心得體會(huì)拿出來(lái)跟大家一起分享一下,文中的示例代碼講解詳細(xì),希望對(duì)大家會(huì)有所幫助2022-11-11

