我在兩個表字段A,B,C,D之間插入,相信我在A,B,C,D上創建了唯一索引以防止重複項。然而,我不知何故只是對這些做了一個正常的索引。所以重複插入。它是2000萬條記錄表。刪除具有唯一索引的重複項
如果我將現有的索引從正常狀態更改爲唯一狀態,或者只是爲A,B,C,D添加新的唯一索引,那麼是否會刪除重複項或將添加失敗,因爲存在唯一記錄?我會測試它,但它是30萬條記錄,我不想把桌子搞亂或複製它。
我在兩個表字段A,B,C,D之間插入,相信我在A,B,C,D上創建了唯一索引以防止重複項。然而,我不知何故只是對這些做了一個正常的索引。所以重複插入。它是2000萬條記錄表。刪除具有唯一索引的重複項
如果我將現有的索引從正常狀態更改爲唯一狀態,或者只是爲A,B,C,D添加新的唯一索引,那麼是否會刪除重複項或將添加失敗,因爲存在唯一記錄?我會測試它,但它是30萬條記錄,我不想把桌子搞亂或複製它。
如果你在你的表格重複和使用
ALTER TABLE mytable ADD UNIQUE INDEX myindex (A, B, C, D);
查詢將失敗,錯誤1062(重複鍵)。
但是如果你使用IGNORE
ALTER IGNORE TABLE mytable ADD UNIQUE INDEX myindex (A, B, C, D);
的副本將被刪除。但文件沒有指定哪些行將被保留:
IGNORE
是一個MySQL擴展到標準SQL。它控制ALTER TABLE
如果新表中的唯一鍵上有重複項,或者如果啓用嚴格模式時發生警告,將如何工作ALTER TABLE
。如果IGNORE
不是 指定,則複製被中止並回滾,如果重複鍵錯誤 發生。如果指定了IGNORE
,則只有一行用於具有唯一密鑰上 重複項的行。其他衝突的行被刪除。 不正確的值被截斷爲最接近匹配的可接受的 值。
從MySQL 5.7.4開始,ALTER TABLE的IGNORE子句被刪除, 的使用產生錯誤。
如果你的版本是5.7。4或更高版本 - 您可以:
INSERT IGNORE
(仍然可用)。CREATE TABLE tmp_data SELECT * FROM mytable;
TRUNCATE TABLE mytable;
ALTER TABLE mytable ADD UNIQUE INDEX myindex (A, B, C, D);
INSERT IGNORE INTO mytable SELECT * from tmp_data;
DROP TABLE tmp_data;
如果使用
IGNORE
改性劑,在執行INSERT
聲明中出現的錯誤被忽略。例如,如果沒有IGNORE
,表 重複表UNIQUE
索引或PRIMARY KEY
表 中的值會導致重複鍵錯誤,並且語句會中止。使用IGNORE
,該行將被丟棄並且不會發生錯誤。忽略錯誤 改爲生成警告。
另見:INSERT ... SELECT Syntax和Comparison of the IGNORE Keyword and Strict SQL Mode
如果您認爲會有重複項,則添加唯一索引將會失敗。 先檢查什麼複製有:
select * from
(select a,b,c,d,count(*) as n from table_name group by a,b,c,d) x
where x.n > 1
這可能是在20M行的昂貴的查詢,但將讓你的所有重複鍵,這將阻止您添加的主要指標。 如果您在子查詢中執行某處操作,則可以將其拆分爲更小的塊:where a='some_value'
對於檢索到的記錄,您必須更改某些內容才能使行具有唯一性。如果這樣做(查詢返回0行),您應該可以安全地添加主索引。
要回答您的問題 - 在具有重複值的列上添加UNIQUE
約束將引發錯誤。
例如,你可以試試下面的腳本:
CREATE TABLE `USER` (
`USER_ID` INT NOT NULL,
`USERNAME` VARCHAR(45) NOT NULL,
`NAME` VARCHAR(45) NULL,
PRIMARY KEY (`USER_ID`));
INSERT INTO USER VALUES(1,'apple', 'woz'),(2,'apple', 'jobs'),
(3,'google', 'sergey'),(4,'google', 'larry');
ALTER TABLE `USER`
ADD UNIQUE INDEX `USERNAME_UNIQUE` (`USERNAME` ASC);
/*
Operation failed: There was an error while applying the SQL script to the database.
ERROR 1062: Duplicate entry 'apple' for key 'USERNAME_UNIQUE'
*/
而是不理你可以使用對重複密鑰更新,這將讓你控制哪些值爲準。
您需要使用'IGNORE'關鍵字 - 否則會失敗。在一個小測試桌上測試它。 –
「IGNORE是標準SQL的MySQL擴展,它控制着ALTER TABLE如何在新表中的唯一鍵上存在重複或如果啓用嚴格模式時發生警告......」 - [ALTER TABLE語法](http: //dev.mysql.com/doc/refman/5.7/en/alter-table.html) –
@PaulSpiegel這很有道理。我嘗試複製Table1,僅結構,並添加一個唯一的索引,然後在原始索引表和新索引表之間插入,但確實失敗。我這樣做是因爲在30萬條記錄上更改或添加獨特索引需要很長時間。因此,現在我在「插入」後添加了「忽略」,它效果很好。 – user3649739