Błąd 1022 - Nie można pisać; zduplikowany klucz w tabeli

218

Otrzymuję błąd 1022 dotyczący duplikatów kluczy podczas tworzenia polecenia table. Po przejrzeniu zapytania nie mogę zrozumieć, gdzie odbywa się duplikacja. Czy ktoś może to zobaczyć?

SQL query:

-- -----------------------------------------------------
-- Table `apptwo`.`usercircle`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS  `apptwo`.`usercircle` (

 `idUserCircle` MEDIUMINT NOT NULL ,
 `userId` MEDIUMINT NULL ,
 `circleId` MEDIUMINT NULL ,
 `authUser` BINARY NULL ,
 `authOwner` BINARY NULL ,
 `startDate` DATETIME NULL ,
 `endDate` DATETIME NULL ,
PRIMARY KEY (  `idUserCircle` ) ,
INDEX  `iduser_idx` (  `userId` ASC ) ,
INDEX  `idcategory_idx` (  `circleId` ASC ) ,
CONSTRAINT  `iduser` FOREIGN KEY (  `userId` ) REFERENCES  `apptwo`.`user` (
`idUser`
) ON DELETE NO ACTION ON UPDATE NO ACTION ,
CONSTRAINT  `idcategory` FOREIGN KEY (  `circleId` ) REFERENCES  `apptwo`.`circle` (
`idCircle`
) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE = INNODB;

MySQL said: Documentation

#1022 - Can't write; duplicate key in table 'usercircle' 
Git-zdolny
źródło
4
Jeśli dobrze pamiętam, klucz podstawowy jest zawsze również UNIKALNYM INDEKSEM, więc musiałbyś usunąć unikalną instrukcję indeksu?
Mr47,
1
ON DELETE NO ACTIONpo prostu porzuciłby całe użycie klucza obcego. Chyba że masz bardzo konkretne powody, aby to zrobić.
AmazingDreams,
4
@AmazingDreams Dlaczego? Nadal wymusza integralność referencyjną. Tylko Ty musisz samodzielnie usunąć dzieci. Jest to bezpieczniejsze niż usuwanie kaskadowe, w którym można przypadkowo usunąć wiele danych, usuwając jedno nieprawidłowe słowo kluczowe.
GolezTrol,
1
stackoverflow.com/a/5810024/1567737 Dlaczego warto używać aliasu, gdy użycie „aliasu” natychmiast wyjaśnia cel?
AmazingDreams,
@AmazingDreams Dzięki za wskazówkę. Podoba mi się również debata wokół niej - pomaga mi ona poznać zalety i wady.
Git-stanie

Odpowiedzi:

534

Najprawdopodobniej masz już ograniczenie do nazwy iduserlub idcategoryw bazie danych. Po prostu zmień nazwę ograniczeń, jeśli tak.

Ograniczenia muszą być unikalne dla całej bazy danych, a nie tylko dla konkretnej tabeli, którą tworzysz / modyfikujesz.

Aby dowiedzieć się, gdzie są obecnie stosowane ograniczenia, możesz użyć następującego zapytania:

SELECT `TABLE_SCHEMA`, `TABLE_NAME`
FROM `information_schema`.`KEY_COLUMN_USAGE`
WHERE `CONSTRAINT_NAME` IN ('iduser', 'idcategory');
Maksym Polshcha
źródło
15
Dokładnie tak jak powiedziałeś. Wiele ograniczeń zostało wygenerowanych automatycznie przy użyciu tych samych nazw użytkowników idcategory w pozostałej części zapytania CREATE - dzięki za pomoc!
Git-stanie
1
Myślałem, że MySQL Workbench naprawiłby to podczas eksportowania skryptu tworzenia, ale to właśnie dostaję za „Ignorowanie” ostrzeżenia o tego rodzaju rzeczach, gdy otwieram projekt.
SnowInferno
Dziękuję, kolego :) To mi bardzo pomaga, a teraz moja konwencja dotycząca kluczy obcych jest inna i nie mogę ponownie rozwiązać tego problemu :)
Potwierdzam to. Ale co mogę zrobić, jeśli istnieje nazwane ograniczenie, chociaż tabela, do której istnieje odwołanie, została już usunięta? Czy mogę usunąć ograniczenie z nieistniejącej tabeli? Chyba powinienem zaktualizować MySQL 5.6 do obecnej MariaDB.
Anse
3
Dziękujemy za to: Ograniczenia muszą być unikalne dla całej bazy danych
sebasira
31

Zmień nazwę klucza obcego w MySQL. Nie można mieć takich samych nazw kluczy obcych w tabelach bazy danych.

Sprawdź wszystkie tabele i wszystkie klucze obce i unikaj posiadania dwóch kluczy obcych o tej samej dokładnej nazwie.

Wassim Sabra
źródło
To był problem w moim przypadku. Nigdy bym tego nie zgadł, a ty uratowałeś mi dzień. Używam teraz fk_id_1, fk_id_2 itp. Dzięki.
JackLeEmmerdeur,
15

Z dwóch linków Pomyślnie rozwiązanych i konwencji nazewnictwa z łatwością rozwiązałem ten sam problem, z którym się spotkałem. czyli o nazwę klucza obcego, jak dać fk _colName_ NazwaTabeli . Ta konwencja nazewnictwa jest niejednoznaczna i sprawia, że ​​każdy klucz zagraniczny w modelu DB jest unikalny i nigdy nie wystąpi ten błąd.

Błąd 1022: Nie można pisać; zduplikowany klucz w tabeli

Chandz
źródło
6

Jak wspomnieli inni, możliwe jest, że nazwa twojego ograniczenia jest już używana przez inną tabelę w twojej bazie danych . Muszą być unikalne w całej bazie danych.

Dobrą konwencją nazywania ograniczeń klucza obcego jest:

fk_TableName_ColumnName

Aby sprawdzić, czy możliwe jest zderzenie, możesz wyświetlić listę wszystkich ograniczeń używanych przez bazę danych za pomocą tego zapytania:

SELECT * FROM information_schema.table_constraints WHERE constraint_schema = 'YOUR_DB';

Kiedy uruchomiłem to zapytanie, odkryłem, że wcześniej utworzyłem tymczasową kopię tabeli i ta kopia już używała nazwy ograniczenia, którego próbowałem użyć.

Simon East
źródło
4

Właśnie spędziłem ostatnie 4 godziny z tym samym problemem. Po prostu upewniłem się, że ograniczenia mają unikalne nazwy.

Możesz zmienić nazwę ograniczeń. Dołączyłem numer do mojego, aby móc łatwo prześledzić liczbę wystąpień.

Przykład

Jeśli ograniczenie w tabeli nosi nazwę boy z kluczem obcym X, następne ograniczenie z kluczem obcym X można nazwać boy1

Jestem pewien, że wymyślisz lepsze nazwiska niż ja. 🙂

Nieznajomy skrypt
źródło
3

Może się to również pojawić w związku z błędem w niektórych wersjach narzędzia do zmiany schematu online Percona Toolkit. Aby zmutować dużą tabelę, pt-osc najpierw tworzy duplikat tabeli i kopiuje do niej wszystkie rekordy. W niektórych okolicznościach niektóre wersje pt-osc 2.2.x spróbują nadać ograniczeniom w nowej tabeli takie same nazwy, jak ograniczenia w starej tabeli.

Poprawka została wydana w 2.3.0.

Zobacz https://bugs.launchpad.net/percona-toolkit/+bug/1498128 więcej szczegółów.

MJD
źródło
1

Zetknąłem się również z tym problemem. Sprawdź, czy nazwa bazy danych już istnieje w Mysql, i zmień nazwę starej.


źródło
1

Miałem ten problem podczas tworzenia nowego stołu. Okazuje się, że nazwa klucza obcego, którą podałem, była już w użyciu. Naprawiono zmianę nazwy klucza.

użytkownik3076750
źródło