1

Я пытаюсь сделать взаимосвязь «два-ко-многим» между двумя таблицами. В Mysql WorkBench и одна из этих двух таблиц имеет составной первичный ключ (части поступают из двух внешних ключи). Когда я пытаюсь генерировать SQL Я получаю эту ошибку:Соединительный ключ Mysql из внешнего составного ключа

ERROR: Error 1215: Cannot add foreign key constraint

SQL код:

-- ----------------------------------------------------- 
    -- Table `A_D_schema`.`Resources_has_OwnerGroups` 
    -- ----------------------------------------------------- 
    CREATE TABLE IF NOT EXISTS `A_D_schema`.`Resources_has_OwnerGroups` (
     `Resources_id` INT NOT NULL, 
     `OwnerGroups_id` INT NOT NULL, 
     `OwnerGroups_Instances_has_Customers_Instances_idInstances` INT NOT NULL, 
     `OwnerGroups_Instances_has_Customers_Customers_idCustomers` INT NOT NULL, 
     PRIMARY KEY (`Resources_id`, `OwnerGroups_id`, `OwnerGroups_Instances_has_Customers_Instances_idInstances`, `OwnerGroups_Instances_has_Customers_Customers_idCustomers`), 
     INDEX `fk_Resources_has_OwnerGroups_OwnerGroups1_idx` (`OwnerGroups_id` ASC, `OwnerGroups_Instances_has_Customers_Instances_idInstances` ASC, `OwnerGroups_Instances_has_Customers_Customers_idCustomers` ASC), 
     INDEX `fk_Resources_has_OwnerGroups_Resources1_idx` (`Resources_id` ASC), 
     CONSTRAINT `fk_Resources_has_OwnerGroups_Resources1` 
     FOREIGN KEY (`Resources_id`) 
     REFERENCES `A_D_schema`.`Resources` (`id`) 
     ON DELETE NO ACTION 
     ON UPDATE NO ACTION, 
     CONSTRAINT `fk_Resources_has_OwnerGroups_OwnerGroups1` 
     FOREIGN KEY (`OwnerGroups_id` , `OwnerGroups_Instances_has_Customers_Instances_idInstances` , `OwnerGroups_Instances_has_Customers_Customers_idCustomers`) 
     REFERENCES `A_D_schema`.`OwnerGroups` (`id` , `Instances_has_Customers_Instances_idInstances` , `Instances_has_Customers_Customers_idCustomers`) 
     ON DELETE NO ACTION 
     ON UPDATE NO ACTION) 
    ENGINE = InnoDB 

Из SHOW ENGINE INNODB STATUS я могу видеть это сообщение:

Cannot resolve column name close to: 
) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION, 
    CONSTRAINT `fk_Resources_has_OwnerGroups_OwnerGroups1` 
    FOREIGN KEY (`OwnerGroups_id` , `OwnerGroups_Instances_has_Customers_Instances_idInstances` , `OwnerGroups_Instances_has_Customers_Customers_idCustomers`) 
    REFERENCES `A_D_schema`.`OwnerGroups` (`id` , `Instances_has_Customers_Instances_idInstances` , `Instances_has_Customers_Customers_idCustomers`) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION) 
ENGINE = InnoDB 

SHOW CREATE TABLE Resources и SHOW CREATE TABLE OwnerGroups:

CREATE TABLE `Resources` (
    `idResources` int(11) NOT NULL AUTO_INCREMENT, 
    `email` varchar(45) DEFAULT NULL, 
    `role` int(11) DEFAULT NULL COMMENT 'role : 1 disptcher \n0 admin', 
    PRIMARY KEY (`idResources`), 
    UNIQUE KEY `idresources_UNIQUE` (`idResources`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

CREATE TABLE `OwnerGroups` (
    `idOwnerGroups` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(45) DEFAULT NULL, 
    `group` int(11) DEFAULT NULL, 
    PRIMARY KEY (`idOwnerGroups`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

ответ

1
CONSTRAINT `fk_Resources_has_OwnerGroups_Resources1` 
    FOREIGN KEY (`Resources_id`) 
    REFERENCES `A_D_schema`.`Resources` (`id`) 

В таблице «Ресурсы» нет столбца id. Его первичный ключ: idResources.

CONSTRAINT `fk_Resources_has_OwnerGroups_OwnerGroups1` 
    FOREIGN KEY (`OwnerGroups_id` , `OwnerGroups_Instances_has_Customers_Instances_idInstances` , `OwnerGroups_Instances_has_Customers_Customers_idCustomers`) 
    REFERENCES `A_D_schema`.`OwnerGroups` (`id` , `Instances_has_Customers_Instances_idInstances` , `Instances_has_Customers_Customers_idCustomers`) 

Ваш стол OwnerGroups не имеет столбец id. Его первичный ключ: idOwnerGroups. У него нет двух других столбцов, на которые вы ссылаетесь вообще.


В общем, при объявлении внешнего ключа, сначала имя колонки в детской таблице:

CREATE TABLE Child (
    childCol1 INT, 
    childCol2 INT, 
... 
FOREIGN KEY (childCol1, childCol2) ... 

Тогда вы ссылаться на столбцы в родительской таблице:

... REFERENCES Parent (parentCol1, parentCol2) 
); 

Вы должны использовать имена столбцов, как они существуют в родительской таблице.

Столбцы, которые вы указываете в родительской таблице, вместе должны быть PRIMARY KEY или UNIQUE KEY этой таблицы. Другими словами, данный пример выше, он не будет работать против этой родительской таблицы:

CREATE TABLE Parent (
    parentCol1 INT, 
    parentCol2 INT, 
    PRIMARY KEY (parentCol1) 
); 

Поскольку PRIMARY KEY не включает parentCol2.


В вашем случае, следующий должен работать:

CREATE TABLE IF NOT EXISTS `A_D_schema`.`Resources_has_OwnerGroups` (
    `Resources_id` INT NOT NULL, 
    `OwnerGroups_id` INT NOT NULL, 
    `OwnerGroups_Instances_has_Customers_Instances_idInstances` INT NOT NULL, 
    `OwnerGroups_Instances_has_Customers_Customers_idCustomers` INT NOT NULL, 
    PRIMARY KEY (`Resources_id`, `OwnerGroups_id`, `OwnerGroups_Instances_has_Customers_Instances_idInstances`, `OwnerGroups_Instances_has_Customers_Customers_idCustomers`), 
    CONSTRAINT `fk_Resources_has_OwnerGroups_Resources1` 
    FOREIGN KEY (`Resources_id`) 
    REFERENCES `A_D_schema`.`Resources` (`idResources`) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION, 
    CONSTRAINT `fk_Resources_has_OwnerGroups_OwnerGroups1` 
    FOREIGN KEY (`OwnerGroups_id`) 
    REFERENCES `A_D_schema`.`OwnerGroups` (`idOwnerGroups`) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION 
) ENGINE = InnoDB 

Я вынул несколько определений INDEX, которые являются избыточными. Вам не нужно индексировать свой PRIMARY KEY, это уже кластеризованный индекс таблицы. Вам не нужно индексировать столбец, который вы используете в объявлении внешнего ключа, MySQL будет индексировать этот столбец автоматически, если это необходимо (хотя, если индекс уже существует для этого столбца, ограничение FK будет использовать этот индекс).

Я не уверен, что я понимаю, что должны делать ваши другие две колонки OwnerGroups_Instances_has_Customers_Instances_idInstances и OwnerGroups_Instances_has_Customers_Customers_idCustomers. Как правило, в таблице «многие-ко-многим» вам достаточно только столбцов для ссылки на первичные ключи соответствующих родительских таблиц.


Re ваш комментарий:

Вы должны попробовать освежающий вид схемы время от времени. На правой стороне «SCHEMAS» есть кнопка с парой пытливых стрелок.

enter image description here

+0

Ok спасибо за ваше замечание .Я заметил, что она исходит от ВБ. У меня были идентификаторы, называемые idResources, переименованные в id. но он все еще присутствует в скрипте. на левой панели я могу даже увидеть таблицы с дублированными именами, которые я удалил с тех пор .... Я удалил Resources_has_OwnerGroups и все еще присутствует в скрипте. WB так прослушивается? –

+0

Итак, если я правильно понимаю ваш комментарий, какова наилучшая практика для сложного ключа? Скажем, для таблицы Resources_has_OwnerGroups: , создавая один новый ключ Resources_has_OwnerGroups_id, составленный: fk_Resources_id и fk_OwnerGroups_id? –

+0

'PRIMARY KEY (Resources_id, OwnerGroups_id)' будет лучшей практикой. Если вы включаете больше столбцов, это позволяет использовать дубликаты в отношении первых двух столбцов. Элементами первичного ключа являются * столбцы *, а не ограничения FK. –

Смежные вопросы