如何去除數據表中的重復數據 2015-11-27

通常情況下,一個我們在做一個產品的時候,一開始可能由于設計考慮不周或者程序寫的不夠嚴謹,某個字段上的值產生重復了,但是又必須去掉,這個時候就稍微麻煩了一點,直接加一個 UNIQUE KEY 肯定是不行了,因為會報錯。
現在,我們來采用一種變通的辦法,不過可能會丟失一些數據 :)

在這里,我們設定一個表,其結構如下:

mysql> desc `user`;
+-------+------------------+------+-----+---------+----------------+
| Field | Type             | Null | Key | Default | Extra          |
+-------+------------------+------+-----+---------+----------------+
| id    | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name  | char(10)         | NO   |     |         |                |
| extra | char(10)         | NO   |     |         |                |
+-------+------------------+------+-----+---------+----------------+

原來表中的數據假定有以下幾條:

mysql> SELECT * FROM `user`;
+----+-------+--------+
| id | name  | extra  |
+----+-------+--------+
|  1 | user1 | user1  |
|  2 | user2 | user2  |
|  3 | user3 | user3  |
|  4 | user4 | user4  |
|  5 | user5 | user5  |
|  6 | user3 | user6  |
|  7 | user6 | user7  |
|  8 | user2 | user8  |
|  9 | USER2 | user9  |
| 10 | USER6 | user10 |
+----+-------+--------+

1、將原來的數據導出

mysql>SELECT * INTO OUTFILE '/tmp/user.txt' FROM `user`;

2、清空數據表

mysql>TRUNCATE TABLE `user`;

3、創建唯一索引,并且修改 name 字段的類型為 BINARY CHAR 區分大小寫

mysql> ALTER TABLE `user` MODIFY `name` CHAR(10) BINARY NOT NULL DEFAULT '';

mysql> ALTER TABLE `user` ADD UNIQUE KEY ( `name` );

現在來看看新的表結構:

mysql> desc user;
+-------+------------------+------+-----+---------+----------------+
| Field | Type             | Null | Key | Default | Extra          |
+-------+------------------+------+-----+---------+----------------+
| id    | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name  | char(10)         | NO   | UNI |         |                |
| extra | char(10)         | NO   |     |         |                |
+-------+------------------+------+-----+---------+----------------+

4、把數據導回去,在這里,有兩種選擇:新的重復記錄替換舊的記錄,只保留最新的記錄 或者是 新的記錄略過,只保留最舊的記錄

mysql> LOAD DATA INFILE '/tmp/user.txt' REPLACE INTO TABLE `user`;
Query OK, 10 rows affected (0.00 sec)
Records: 8  Deleted: 2  Skipped: 0  Warnings: 0

mysql> SELECT * FROM USER;
+----+-------+--------+
| id | name  | extra  |
+----+-------+--------+
|  1 | user1 | user1  |
|  8 | user2 | user8  |
|  6 | user3 | user6  |
|  4 | user4 | user4  |
|  5 | user5 | user5  |
|  7 | user6 | user7  |
|  9 | USER2 | user9  |
| 10 | USER6 | user10 |
+----+-------+--------+

上面是采用 REPLACE 的方式,可以看到,導入過程中刪掉了兩條數據,結果驗證確實是 新的重復記錄替換舊的記錄,只保留最新的記錄。
現在,來看看用 IGNORE 的方式:

mysql> LOAD DATA INFILE '/tmp/user.txt' IGNORE INTO TABLE `user`;
Query OK, 6 rows affected (0.01 sec)
Records: 8  Deleted: 0  Skipped: 2  Warnings: 0

mysql> SELECT * FROM USER;
+----+-------+--------+
| id | name  | extra  |
+----+-------+--------+
|  1 | user1 | user1  |
|  2 | user2 | user2  |
|  3 | user3 | user3  |
|  4 | user4 | user4  |
|  5 | user5 | user5  |
|  7 | user6 | user7  |
|  9 | USER2 | user9  |
| 10 | USER6 | user10 |
+----+-------+--------+

看到了吧,確實是 新的記錄略過,只保留最舊的記錄。

一级A片不卡在线观看