Помилка 1022 - Неможливо написати; дублікат ключа в таблиці


218

Я отримую помилку 1022 щодо дублікатів ключів у команді create table. Переглянувши запит, я не можу зрозуміти, де відбувається дублювання. Хтось ще може це бачити?

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' 

4
Якщо я правильно пам’ятаю, первинний ключ - це також УНІКАЛЬНИЙ ІНДЕКС, тож вам доведеться кинути унікальний оператор індексу?
Mr47

1
ON DELETE NO ACTIONпросто відмовиться від усього використання іноземного ключа. Якщо у вас немає дуже конкретних причин для цього.
AmazingDreams

4
@AmazingDreams Чому? Він все ще забезпечує референтну цілісність. Тільки ви повинні самі видалити дітей. Це безпечніше, ніж каскадне видалення, де ви можете випадково видалити багато даних, видаливши одне неправильне ключове слово.
GolezTrol

1
stackoverflow.com/a/5810024/1567737 Чому використання псевдоніма під час використання "псевдоніму" робить мету зрозумілою негайно?
AmazingDreams

@AmazingDreams Дякую за пораду. Мені також подобаються дебати навколо неї - це допомагає мені дізнатися про плюси і мінуси.
Git-

Відповіді:


534

Найімовірніше, у вас вже є обмеження з іменем iduserабо idcategoryу вашій базі даних. Просто перейменуйте обмеження, якщо так.

Обмеження повинні бути унікальними для всієї бази даних, а не лише для конкретної таблиці, яку ви створюєте / змінюєте.

Щоб дізнатися, де обмеження в даний час використовуються, ви можете скористатися наступним запитом:

SELECT `TABLE_SCHEMA`, `TABLE_NAME`
FROM `information_schema`.`KEY_COLUMN_USAGE`
WHERE `CONSTRAINT_NAME` IN ('iduser', 'idcategory');

15
Точно так, як ви сказали. Багато обмежень було створено автоматично з однаковими іменами iduser ідентифікаторів в решті запиту CREATE - дякую за допомогу!
Git-

1
Я думав, що MySQL Workbench це виправить під час експорту сценарію створення, але це те, що я отримую за "Ігнорувати" попередження про подібні речі, коли я відкривав проект.
SnowInferno

Дякую, товариш :) Це мені дуже допомагає, і тепер моя умова щодо зовнішніх ключів відрізняється, і я не можу знову зустріти цю проблему :)

Можна підтвердити це. Але що я можу зробити, якщо назване обмеження існує, хоча згадана таблиця вже випала ?? Чи можу я скинути обмеження з неіснуючої таблиці? Я думаю, я повинен оновити з MySQL 5.6 до поточного MariaDB.
Анс

4
Дякую за це: Обмеження повинні бути унікальними для всієї бази даних
sebasira

31

Змініть ім'я іноземного ключа в MySQL. У таблицях бази даних не можна мати однакових імен іноземних ключів.

Перевірте всі свої таблиці та всі ваші закордонні ключі та уникайте наявності двох іноземних ключів з однаковою назвою.


У цьому і була проблема в моєму випадку. Я б ніколи не здогадувався про це, і ти врятував мені день. Використовуючи fk_id_1, fk_id_2 тощо, зараз. Дякую.
JackLeEmmerdeur

15

З двох посилань , вирішених Успішно і Конвенції про іменування , я легко вирішив цю саму проблему, з якою зіткнувся. тобто для назви іноземного ключа дайте як fk _colName_ TableName . Ця умова іменування неоднозначна, а також робить кожен ForeignKey у вашій моделі DB унікальним, і ви ніколи не отримаєте цю помилку.

Помилка 1022: Неможливо записати; дублікат ключа в таблиці


6

Як уже згадували інші, можливо, ім'я для вашого обмеження вже використовується іншою таблицею у вашій БД . Вони повинні бути унікальними в базі даних.

Гарною умовою для іменування обмежень іноземних ключів є:

fk_TableName_ColumnName

Щоб дослідити, чи можливе зіткнення, ви можете перерахувати всі обмеження, використовувані вашою базою даних за допомогою цього запиту:

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

Коли я запустив цей запит, я виявив, що раніше робив тимчасову копію таблиці, і ця копія вже використовувала ім'я обмеження, яке я намагався використовувати.


4

Я щойно провів останні 4 години з тим же номером. Що я зробив, це просто переконатися, що обмеження мають унікальні назви.

Ви можете перейменувати обмеження. Я додав номер до свого, щоб я міг легко простежити кількість подій.

Приклад

Якщо обмеження в таблиці називається хлопчиком із зовнішнім ключем X Наступне обмеження із зовнішнім ключем X можна назвати boy1

Я впевнений, що ти б придумав кращі імена, ніж я. 🙂


3

Це також може виникнути у зв'язку з помилкою в певних версіях Інтернету-інструменту зміни схеми Percona Toolkit. Щоб мутувати велику таблицю, pt-osc спочатку створює дублюючу таблицю і копіює в неї всі записи. За певних обставин деякі версії pt-osc 2.2.x намагатимуться надати обмеженням нової таблиці ті ж назви, що і обмеження в старій таблиці.

Виправлення було випущено в 2.3.0.

Дивіться https://bugs.launchpad.net/percona-toolkit/+bug/1498128 для отримання більш детальної інформації.


1

Я також зіткнувся з цією проблемою. Перевірте, чи ім'я бази даних вже існує в Mysql, і перейменуйте стару.


1

У мене була ця проблема під час створення нової таблиці. Виявляється, ім'я Іноземного ключа, яке я дав, уже використовувалося. Перейменування ключа зафіксувало його.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.