2013-02-22 18 views
18

MySQL Workbench wymyślił następującym SQL utworzyć tabelę:Błąd MySQL 1022 podczas tworzenia tabeli

CREATE TABLE IF NOT EXISTS `mydb`.`errors_reports` (
    `error_id` INT NOT NULL , 
    `report_short` VARCHAR(15) NOT NULL , 
PRIMARY KEY (`error_id`, `report_short`) , 
INDEX `error_id_idx` (`error_id` ASC) , 
INDEX `report_short_idx` (`report_short` ASC) , 
CONSTRAINT `error_id` 
    FOREIGN KEY (`error_id`) 
    REFERENCES `mydb`.`errors` (`error_id`) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION, 
CONSTRAINT `report_short` 
    FOREIGN KEY (`report_short`) 
    REFERENCES `mydb`.`reports` (`report_short`) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION) 
ENGINE = InnoDB 

który wygląda dobrze dla mnie, i istnieje kilka innych bardzo podobnych tabel w mojej bazy danych MySQL był całkowicie szczęśliwy w tworzeniu.

Ale ten ...

ERROR 1022 (23000): Can't write; duplicate key in table 'errors_reports' 

nie mogę dla życia mnie zobaczyć tutaj żadnych duplikatów kluczy. Został zdefiniowany tylko jeden klucz!

Używam MySQL w wersji 5.6 ze świeżą domyślną instalacją. W dzienniku błędów nie ma nic.

Pomysły?

Edycja: w procesie eliminacji (wracając do najprostszej definicji tabeli, a następnie stopniowe dodanie bitów widok) problem pojawia się bit:

CONSTRAINT `error_id` 
    FOREIGN KEY (`error_id`) 
    REFERENCES `mydb`.`errors` (`error_id`) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION, 

co jest szczególnie dziwne, istnieje identyczny kod w kilku innych definicjach tabel i są one całkowicie w porządku!

+0

nie mam żadnego problemu z tego zapytania .. Wygląda na to, że może być coś innego dzieje –

+0

Nie jesteś pewien, że musisz jawnie utworzyć indeks dla kolumn FK. Miałem wrażenie, że stworzenie odnośnika stworzy indeks. – Kermit

+0

Wyciąganie instrukcji INDEX nie robi różnicy. –

Odpowiedz

-1

Spróbuj użyć INSERT IGNORE zamiast INSERT gdzie INSERT IGNORE nie wstawi nowego wiersza, jeśli zostanie odnaleziony zduplikowany klucz podstawowy. To powinno pomóc w rozwiązaniu problemu tymczasowego, ale zaleciłbym skrócenie tabeli.

+0

Powoduje to utworzenie tabeli, bez wstawiania danych. Tu nie ma INSERT. –

+0

Dobrze.Jest to zdecydowanie kluczowy problem zagraniczny (błąd 105 dla mnie). Upewnij się, że klucz obcy i kolumna z odniesieniami mają takie same typy danych, takie jak sortowanie, atrybuty domyślne i tak dalej. –

2

Wygląda na to, że tworzysz indeks na kolumnach klucza obcego. Podczas tworzenia obcego klucza w InnoDb, zostanie on utworzony automatycznie.

See this thread.

+0

Kod został utworzony przez MySQL Workbench, który wydaje się dodawać to wyraźnie. Nie to robi żadnej różnicy. –

+0

@MattMcLeod Czy jesteś w stanie utworzyć ograniczenia po utworzeniu tabeli? Czy możesz także spróbować [sprawdzanie indeksów] (http://stackoverflow.com/a/5213364/679449) przed/po utworzeniu tabeli? – Kermit

+1

Aha! To doprowadziło mnie do tego, o czym myślę, że jest rozwiązaniem: inna tabela miała już to samo nałożone ograniczenie: error_id, a Workbench nadał obu tym samym ograniczającym nazwom. Zmiana nazwy ograniczenia pozwoliła na jej utworzenie. –

59

Problemem jest to, że nazwa z klucz obcy nie może być samo jak inny klucz obcy w całym modelu.

Wyobraźmy sobie taką sytuację

katalog -> Dostawca

Produkty -> Dostawca

jeśli nazwa klucza obcego w tabeli katalogu dla dostawcy jest „dostawca” i przypisana taka sama nazwa w tabeli produktów, wtedy nazwy kluczy obcych będą "kolidować".

Trzeba nazwać je inaczej ..

Na przykład:

catalog_supplier product_supplier

+0

Dzięki! Miał ten sam problem i nie mógł zrozumieć, że biorąc pod uwagę masaż błędu. BTW nazwa kolizyjnego klucza obcego NIE jest taka sama jak nazwa kolumny, tylko wewnętrzna nazwa MySql dla klucza. – uzilan

+2

to jest odpowiedź! wspaniały! –

+1

Czy wiesz, dlaczego to ograniczenie istnieje w MySQL? – vipw

Powiązane problemy