處理重複資料是 DBA 最大的煩惱之一。無論我們多麼努力防範它,重複的東西總是能夠找到入侵資料表的方法。這是一個很大的問題,因為它可能影響應用程式檢視(每個項目應該是唯一的),令統計資料傾斜,並且在嚴重的情況下會增加伺服器的額外負荷。
在這篇文章中,我們將學習如何識別 MySQL 中的重複資料,以及如何刪除它們而不影響寶貴的有效資料。
重複類型
大多數重複記錄是這兩種不同類型的其中之一:重複意思和非唯一鍵。在這一篇文章,我們將處理重複意思的記錄。而非唯一鍵將在下一篇文章處理。
當重複不是重複時
重複意思是最常見的重複類型。這情況是兩個或多個欄位的內容不一樣,但它們的意思是一樣的。你可以將其視為語義重複。
請看以下的資料表摘錄:
movie_name | media |
--------------------------- | |
ACADEMY DINOSAUR | Theatre |
ACE GOLDFINGER | Television |
ADAPTATION HOLES | Theatre |
AFFAIR PREJUDICE | Theatre |
AFRICAN EGG | TV |
在 media 欄中,「Television」和「TV」項目有相同的意思,但表達方式不同。此問題通常是由使用自由文字輸入引起的,使用有限選項的下拉式選單是一個更好選擇。
這種重複類型可能非常難以處理,因為你無法使用 SELECT DISTINCT 語句排除重複項。
有兩種方法可以解決這個問題:
- 使用 REPLACE() 選取資料,將不想要的值換成我們想要查看的值:
- 更新資料表中的實際資料。將所有「TV」值更新為「TELEVISION」。這是更新語句:
SELECT DISTINCT | movie_name, |
REPLACE(media, "TV", "TELEVISION") as media, | |
FROM films; |
UPDATE films |
SET media = REPLACE(media, "TV", "TELEVISION") |
WHERE media = "TV"; |
以下是我一個月前遇到的真實例子!
不知何故,我們的資料多了一些不需要的捲曲撇號。請注意「O'BRIEN」和「O'BRIEN」項目:
first_name | last_name |
--------------------- | |
PENELOPE | GUINESS |
CONAN | O'BRIEN |
ED | CHASE |
JENNIFER | DAVIS |
CONAN | O'BRIEN |
我們可以像上面那樣處理這個問題:
- 使用 REPLACE() 以普通的單引號交換捲曲撇號來選取資料,以便我們處理相同的字元:
- 更新資料表中的實際資料。此語句將 last_name 欄中的所有撇號更新為普通的單引號:
SELECT DISTINCT | first_name, |
REPLACE(last_name, "'", "'") as last_name, | |
FROM actors | WHERE REPLACE(last_name, "'", "'") like "O'BRIEN"; |
UPDATE actors |
SET last_name = REPLACE(last_name, "'", "'") |
WHERE last_name like "%'%"; |
總結
無論是稱作重複記錄、相同資料、冗餘資料,還是重複列,它們都是 DBA 生命中最大的禍根之一。然而,定期清除它們是很重要,免得產生錯誤的統計資料和使資料庫使用者感到困惑。