2011-11-08 3 views
47

UNIQUE KEY와 ALTER IGNORE TABLE을 사용하여 MySQL 테이블에서 중복을 제거하려고합니다. MySQL 설명서에서 다음과 같이 말합니다 :MySQL : ALTER IGNORE TABLE은 "무결성 제약 조건 위반"을 나타냅니다.

IGNORE는 표준 SQL에 대한 MySQL 확장입니다. 새로운 테이블의 고유 키에 중복이 있거나 ALTER TABLE이 작동하는 방식을 제어합니다. IGNORE가 지정되지 않으면 중복 키 오류가 발생하면 사본이 중단되고 롤백됩니다. IGNORE가 지정되면 유일한 키에 중복 된 행이있는 첫 번째 행만 사용됩니다. 충돌하는 다른 행이 삭제됩니다. 잘못된 값은 가장 일치하는 수용 가능한 값으로 잘립니다. 키 'dupidx'에 대한 항목 'blabla'을 중복 -

내가 쿼리를 실행 ...

ALTER IGNORE TABLE table ADD UNIQUE INDEX dupidx (field) 

... 난 여전히 오류 # 1062 얻을.

답변

95

MySQL에 대한 IGNORE 키워드의 확장자는 일부 버전의 MySQL에서는 bug in the InnoDB version입니다.

당신은 항상 당신이 작동하지 않습니다 외래 키 제약 조건이있는 경우,

ALTER TABLE table ENGINE MyISAM; 
ALTER IGNORE TABLE table ADD UNIQUE INDEX dupidx (field); 
ALTER TABLE table ENGINE InnoDB; 

참고 이노로 다시 변환 한 후 인덱스를 무시-추가하고,의 MyISAM로 변환 할 수

는 먼저 사람들을 제거해야합니다 , 나중에 다시 추가하십시오.

+56

설정 세션 old_alter_table = 1 '첫 번째 실행에 대한 권장 해결 방법은,'이 근무는! 나를. – Peter

+1

감사합니다 피터 - 이것은 나를 위해 지금 일하는 것 같습니다. 이 문제에 대해 전혀 알지 못했습니다. 내 dev 머신은 mariadb이지만, 프로덕션 (mysql 5.5)에서 실행해야 할 때이 문제가 발생했습니다. 이 stackoverflow 내 하루 저장! – spidie

+5

이것은 아마도 스택 오버플로에서 본 최악의 대답입니다. 스토리지 엔진을 변경하는 것 자체가 중형 테이블에서도 중요한 사업입니다. 이 세 가지 쿼리는 잠시 동안 데이터베이스 서버를 잠글 수 있습니다. 이것은 해결책과 같은 것이 아닙니다. – Mikkel

2

색인을 생성하려는 입력란에 중복 데이터가있는 것이 문제입니다. 고유 색인을 추가하려면 문제가되는 중복을 제거해야합니다.

한 가지 방법은 다음을 수행하는 것입니다 :이 수

CREATE TABLE tmp_table LIKE table; 
    ALTER IGNORE TABLE tmp_table ADD UNIQUE INDEX dupidx (field); 
    INSERT IGNORE INTO tmp_table SELECT * FROM table; 
    DROP TABLE table; 
    RENAME TABLE tmp_table TO table; 

당신이 테이블

+0

아니, IGNORE 키워드는 그 중복을 처리해야한다. 이것이이 솔루션의 아름다움입니다. 내 질문에 인용 된 문서를 참조하십시오. –

25

으로 만 고유 데이터를 삽입 또는 설정 세션을 시도 old_alter_table = 1 (을 설정하는 것을 잊지 마세요 다시)

참조 : InnoDB의 버그에 링크에서 http://mysqlolyk.wordpress.com/2012/02/18/alter-ignore-table-add-index-always-give-errors/

+2

이것은 저에게 효과적이었습니다. 그것은 큰 테이블에 길지만, 꽤 선형적인 것처럼 보입니다. 내 컴퓨터에서는 약 2GiB의 데이터를 시간당 처리 할 수있었습니다. 이는 약 2 일이었습니다. myISAM으로 변환하여 인덱스를 추가하고 다시 변환하는 것이 허용 된 솔루션과 어떻게 비교되는지 궁금합니다. –

+0

주의! 만약 당신이 복제를 사용한다면'old_alter_table' 설정은 복제되지 않기 때문에'ALTER TABLE IGNORE'는 슬레이브와 브레이크 복제에서 실패 할 것입니다.이 문제를 해결하기 위해 슬레이브에서'ALTER'를 수동으로 수행 한 다음'SET GLOBAL sql_slave_skip_counter = 1'을 사용하여 문제가되는'ALTER TABLE '을 건너 뛰고 복제를 재개했습니다. – thenickdude