首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 重複資料處理完全指南:防重、統計、去重與刪除的多種實戰方案

     編輯:MySQL 綜合教學

核心場景分類

  • 防重 (寫入端): 業務邏輯/資料庫約束阻止重複寫入
  • 查重 (讀取端): 統計重複分布、過濾重複顯示
  • 去重 (清理端): 刪除現有重複資料、保留唯一記錄

一、防重:資料庫層面的唯一性保障 (最推薦)

1. 主鍵約束 (單欄/複合)

CREATE TABLE person_tbl (
    first_name CHAR(20) NOT NULL,
    last_name CHAR(20) NOT NULL,
    sex CHAR(10),
    UNIQUE KEY uk_name (last_name, first_name)
);

差異: 允許一個 NULL (InnoDB 視 NULL≠NULL)、表可有多個唯一索引、非叢集。

3. 插入策略對比

語句重複時行為返回值適用場景
INSERT報錯 (Duplicate entry)錯誤碼 1062嚴格業務、需感知衝突
INSERT IGNORE靜默跳過、不插入受影響行數 0、Warning日誌/統計類、允許重複嘗試
REPLACE INTO刪除舊行 → 插入新行刪除+插入行數和需覆蓋更新、主鍵/唯一鍵衝突
INSERT ... ON DUPLICATE KEY UPDATE更新指定欄位1(新增)/2(更新)最通用:計數器、最後更新時間、業務覆蓋

ON DUPLICATE KEY UPDATE 實戰範例

通用查重三步法

  1. 確定可能重複的業務鍵欄位 (如 user_id+order_no、phone、email)
  2. SELECT 列表包含業務鍵 + COUNT(*)
  3. GROUP BY 業務鍵欄位
  4. HAVING COUNT(*) > 1

三、過濾重複:查詢去重 (不修改資料)

方法語法特點效能
DISTINCTSELECT DISTINCT col1, col2 FROM tbl簡單、標準、所有欄位組合去重需排序/哈希,大表較慢
GROUP BYSELECT col1, col2 FROM tbl GROUP BY col1, col2可搭配聚合函數 (MAX/MIN/COUNT)同 DISTINCT,可利用索引
ROW_NUMBER() 窗口函數 (8.0+)SELECT * FROM (SELECT *, ROW_NUMBER() OVER (PARTITION BY col1 ORDER BY id) rn FROM tbl) t WHERE rn=1保留特定行 (最新/最舊/最大 ID)、支援複雜排序單次掃描,大表首選

四、刪除重複:物理去重方案對比

方案 1:建新表 → 刪舊表 → 改名 (最通用、可控)

-- 僅 5.6 及以下可用
ALTER IGNORE TABLE person_tbl ADD UNIQUE KEY uk_name (last_name, first_name);
-- 會自動刪除重複行,保留第一條,但行為不可控、已廢棄

方案 3:多表連接刪除 (保留最小/最大 ID)

WITH ranked AS (
    SELECT id, ROW_NUMBER() OVER (PARTITION BY last_name, first_name ORDER BY id) rn
    FROM person_tbl
)
DELETE FROM person_tbl
WHERE id IN (SELECT id FROM ranked WHERE rn > 1);

五、方案選型決策樹

場景資料量MySQL 版本推薦方案
防重寫入任意所有唯一索引 + INSERT ... ON DUPLICATE KEY UPDATE
事後清理< 10 萬所有建新表法 (方案 1)
事後清理10 萬 - 1 億5.7/8.0CTE + 窗口函數 (方案 4) 或分批 DELETE
事後清理> 1 億8.0pt-archiver 歸檔重建 或 線上結構變更
保留最新/最舊任意8.0+ROW_NUMBER() 窗口函數

六、效能優化關鍵點

  • 建立臨時唯一索引加速分組: ALTER TABLE person_tbl ADD KEY idx_dedup (last_name, first_name);
  • 分批處理大表: DELETE ... LIMIT 10000 循環執行,避免長事務、鎖升級、Undo 爆漲
  • 停服維護窗口: 大表去重建議業務低峰期、加鎖維護
  • 備份先行: 任何刪除操作前必須 mysqldump --single-transaction 完整備份

總結

重複資料治理遵循 「源頭防重 > 過程查重 > 事後去重」 分層策略。資料庫約束 (主鍵/唯一索引) 是第一道防線,ON DUPLICATE KEY UPDATE 是寫入端最靈活工具。事後清理首選 建新表法 (通用可控) 或 CTE 窗口函數 (8.0+ 精準高效),大表務必分批、備份、驗證。建立資料質量監控儀表板,定期掃描核心表重複率,納入 DBA 例巡指標。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved