mysql中INSERT IGNORE的高效插入策略
引用
作為一個軟件開發(fā)人員,特別是要與數(shù)據(jù)庫打交道的靚仔,你就不可避免的要遇到數(shù)據(jù)重復(fù)插入的問題,如果你沒有唯一鍵或者主鍵之類的,那無話可說,但是你很好的設(shè)計了數(shù)據(jù)庫唯一索引和主鍵,哪當(dāng)我們插入數(shù)據(jù)的時候,你就必須做好去重處理。
代碼里面有很多方法,預(yù)檢查,分布式鎖等等;但是有一些場景,我們要快速遷移大量的數(shù)據(jù),有的時候會分批次多階段的處理,這個時候如果都來做預(yù)檢就很耗時,本文將介紹INSERT IGNORE的用法,特別適合解決這一問題。

一、 基本語法
INSERT IGNORE 是 MySQL 中一個非常實用的語句,用于在插入數(shù)據(jù)時避免重復(fù)鍵錯誤(如主鍵沖突或唯一索引沖突)。它可以幫助你優(yōu)雅地處理數(shù)據(jù)重復(fù)問題,而不會拋出錯誤。
INSERT IGNORE 的基本語法與普通的 INSERT 語句非常相似,只是在 INSERT 關(guān)鍵字后面加上了 IGNORE 關(guān)鍵字。以下是常見的語法形式:
- 插入單行數(shù)據(jù)
INSERT IGNORE INTO table_name (column1, column2, ..., columnN) VALUES (value1, value2, ..., valueN);
- 插入多行數(shù)據(jù)
INSERT IGNORE INTO table_name (column1, column2, ..., columnN)
VALUES
(value1a, value2a, ..., valueNa),
(value1b, value2b, ..., valueNb),
...
(value1n, value2n, ..., valueNn);
- 插入查詢結(jié)果
INSERT IGNORE INTO table_name (column1, column2, ..., columnN) SELECT column1, column2, ..., columnN FROM another_table WHERE condition;
二、 工作原理
INSERT IGNORE 的主要功能是忽略插入操作中可能導(dǎo)致重復(fù)鍵錯誤的行。以下是其工作原理的詳細(xì)說明:
2.1 忽略重復(fù)鍵錯誤
當(dāng)嘗試插入的數(shù)據(jù)違反了表的唯一性約束(如主鍵或唯一索引)時,INSERT IGNORE 會自動忽略該插入操作,不會拋出錯誤。例如:
假設(shè)有一個表 users,結(jié)構(gòu)如下:
CREATE TABLE `user_info` ( `id` varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用戶id', `risk_score` int NOT NULL DEFAULT '0' COMMENT '風(fēng)險評分 0-100 (不可超出該范圍)', `risk_level` tinyint(1) NOT NULL DEFAULT '0' COMMENT '0-安全 1-低風(fēng)險 2-中風(fēng)險 3-高風(fēng)險', `register_time` datetime NOT NULL COMMENT '注冊時間', `created` datetime NOT NULL COMMENT '創(chuàng)建時間(北京時間)', `updated` datetime DEFAULT NULL COMMENT '修改時間(北京時間)', `creator` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '創(chuàng)建人', `updater` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '更新人', PRIMARY KEY (`id`), KEY `idx_updated` (`updated`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用戶安全信息表';
如果嘗試插入以下SQL:
INSERT IGNORE INTO `user_info`
(`id`, `risk_score`, `risk_level`, `register_time`, `created`, `updated`, `creator`, `updater`)
VALUES
('11-000034639cc4408aba88358e73d48517', 10, 0, '2023-02-28 20:28:58', '2025-03-21 17:02:21', '2025-03-21 17:02:36', 'admin', 'admin');
通過下圖可以看到,當(dāng)11-000034639cc4408aba88358e73d48517已經(jīng)存在的時候,MySQL 會忽略該插入操作,不會報錯。
注意:這里只是根據(jù)唯一鍵和主鍵去判斷是否存在,至于其它的值是否發(fā)生變化不會拿來判斷。

2.2 返回值
INSERT IGNORE 的返回值是一個整數(shù),表示插入操作的結(jié)果:
- 返回值為 1:表示插入成功。
- 返回值為 0:表示插入操作被忽略(因為數(shù)據(jù)重復(fù))。
- 返回值為 n:表示成功插入了 n 行數(shù)據(jù)(在插入多行時)。
2.3 擴(kuò)展:查看警告信息
即使 INSERT IGNORE 忽略了插入操作,MySQL 仍然會生成一個警告(Duplicate entry)。你可以通過以下命令查看警告信息:
SHOW WARNINGS;
例如:
INSERT IGNORE INTO `user_info`(`id`, `risk_score`, `risk_level`, `register_time`, `created`, `updated`, `creator`, `updater`) VALUES ('11-000034639cc4408aba88358e73d48517', 10, 0, '2023-02-28 20:28:58', '2025-03-21 17:02:21', '2025-03-21 17:02:36', 'admin', 'admin');
SHOW WARNINGS;
輸出結(jié)果如下:

三、 使用場景
INSERT IGNORE 非常適用于以下場景:
3.1 避免重復(fù)數(shù)據(jù)插入
當(dāng)你需要插入大量數(shù)據(jù),但不確定某些數(shù)據(jù)是否已經(jīng)存在時,INSERT IGNORE 可以幫助你避免重復(fù)插入,同時不會拋出錯誤。例如:
INSERT IGNORE INTO `user_info`(`id`, `risk_score`, `risk_level`, `register_time`, `created`, `updated`, `creator`, `updater`) VALUES
('11-000034639cc4408aba88358e73d48517', 10, 0, '2023-02-28 20:28:58', '2025-03-21 17:02:21', '2025-03-21 17:02:36', 'admin', 'admin'),
('11-000034639cc4408aba88358e73d48517', 10, 0, '2023-02-28 20:28:58', '2025-03-21 17:02:21', '2025-03-21 17:02:36', 'admin', 'admin');
執(zhí)行結(jié)果:

3.2 數(shù)據(jù)導(dǎo)入
在從其他數(shù)據(jù)源導(dǎo)入數(shù)據(jù)時,INSERT IGNORE 可以確保不會因為重復(fù)數(shù)據(jù)而導(dǎo)致插入失敗。例如:
INSERT IGNORE INTO `user_info`(`id`, `risk_score`, `risk_level`, `register_time`, `created`, `updated`, `creator`, `updater`) SELECT `id`, `risk_score`, `risk_level`, `register_time`, `created`, `updated`, `creator`, `updater` FROM asrc_user_info;
執(zhí)行結(jié)果:

3.3 日志記錄
在記錄日志或事件時,INSERT IGNORE 可以確保不會因為重復(fù)記錄而導(dǎo)致錯誤。
這種場景主要在于一些日志重復(fù)上報的情況。
四、注意事項
雖然 INSERT IGNORE 非常方便,但在使用時還是要慎重,需要注意以下幾點:
4.1 不僅限于重復(fù)鍵錯誤
INSERT IGNORE 不僅會忽略重復(fù)鍵錯誤,還會忽略其他類型的錯誤(如外鍵約束錯誤)。因此,如果你只想忽略重復(fù)鍵錯誤,而希望其他錯誤拋出異常,可以使用 ON DUPLICATE KEY UPDATE 或其他機(jī)制。
4.2 性能影響
雖然 INSERT IGNORE 的性能通常較高,但在插入大量數(shù)據(jù)時,仍然需要注意性能問題。如果表中存在大量唯一索引,可能會導(dǎo)致插入操作變慢。在這種情況下,可以考慮批量插入或優(yōu)化表結(jié)構(gòu)。
4.3 注意:重要業(yè)務(wù)數(shù)據(jù)不能丟
因為是根據(jù)唯一鍵這些進(jìn)行去重,有一些場景可能是插入或者更新的重要數(shù)據(jù),不能使用這個語句,切記。
五、與INSERT插入的區(qū)別
看到這里對他們之間的區(qū)別相信在腦海中已經(jīng)有一個概念了,下面我將用一個圖更加清晰的表示兩者的區(qū)別:

從上圖可以看出,他們兩個實際都是進(jìn)行了約束檢查的,只是一個返回錯誤信息,停止語句的執(zhí)行,一個生成告警信息,跳過當(dāng)前行繼續(xù)執(zhí)行。
六、總結(jié)
INSERT IGNORE就像一個溫柔的數(shù)據(jù)庫管理員,遇到重復(fù)數(shù)據(jù)時不會大喊大叫拋出錯誤,而是默默跳過,繼續(xù)處理下一條。
無論是批量導(dǎo)入數(shù)據(jù)、避免重復(fù)插入,還是處理日志重復(fù)上報,它都能輕松搞定。
不過,它也有小脾氣,比如會忽略所有錯誤(不只是重復(fù)鍵),所以用的時候得小心。
總之,INSERT IGNORE 是數(shù)據(jù)庫操作中的“溫柔一刀”,幫你優(yōu)雅地解決問題,但別忘了檢查它的“副作用”哦!
到此這篇關(guān)于mysql中INSERT IGNORE的高效插入策略的文章就介紹到這了,更多相關(guān)mysql INSERT IGNORE插入內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
navicat 連接數(shù)據(jù)庫隔段時間后自動斷開連接的解決方案
這篇文章主要介紹了navicat 連接數(shù)據(jù)庫隔段時間后自動斷開連接的解決方案,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12
MySQL優(yōu)化器追蹤(Optimizer Trace)的使用小結(jié)
MySQL OptimizerTrace 是用于分析查詢優(yōu)化器決策過程的工具,通過輸出JSON格式的詳細(xì)執(zhí)行信息,幫助開發(fā)者理解優(yōu)化器如何選擇執(zhí)行計劃,感興趣的可以了解一下2025-08-08
MySQL: mysql is not running but lock exists 的解決方法
下面可以參考下面的方法步驟解決。最后查到一個網(wǎng)友說可能和log文件有關(guān),于是將log文件給移除了,再重啟MySQL終于OK了2009-06-06
MySQL UPDATE 語句的非標(biāo)準(zhǔn)實現(xiàn)代碼
這篇文章主要介紹了MySQL UPDATE 語句的非標(biāo)準(zhǔn)實現(xiàn)代碼,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-04-04
遠(yuǎn)程訪問MySQL數(shù)據(jù)庫的方法小結(jié)
MySQL數(shù)據(jù)庫不允許從遠(yuǎn)程訪問如何辦?本文提供了 3種解決思路方法2009-12-12

