2012-01-22 2 views
0

У меня есть следующие таблицы:Внешний ключ между таблицами MySQL InnoDB не работает ... почему?

породы (MyISAM)
изображения (ЬшоВВ)
specie_map (ЬшоВВ)

В таблице specie_map следует отобразить изображение на монете, и, следовательно, имеет следующие столбцы:

specie_id
image_id

Оба INT 11, так же, как Ид столбцов звонкой и графических таблиц. Я знаю, что не могу создать внешний ключ между specie_id и specie => id, так как таблица видов - таблица MyIsam. Тем не менее, я ожидаю, что возможно создать внешний ключ между image_id и image => id.

Я могу создать этот внешний ключ, и он сохранит его, однако действие CASCADE, которое я связал с ним, не работает. Когда я удаляю изображение, он не удаляет запись specie_map, связанную с ней. Я ожидаю, что это сработает, поскольку этот внешний ключ находится между таблицами InnoDB. Оба столбца индексируются и имеют один и тот же тип данных.

Является ли это ограничением для MySQL, или я делаю что-то еще неправильно?

Обновление: в соответствии с этими определениями таблиц. Я отрезала несущественные столбцы:

-- ---------------------------- 
-- Table structure for `image` 
-- ---------------------------- 
DROP TABLE IF EXISTS `image`; 
CREATE TABLE `image` (
    `id` int(11) NOT NULL auto_increment, 
    `guid` char(36) default NULL, 
    `title` varchar(255) NOT NULL, 
    `description` text, 
    `user_id` int(11) NOT NULL, 
    `item_id` int(11) default NULL, 
    `date_uploaded` timestamp NOT NULL default '0000-00-00 00:00:00', 
    `date_created` timestamp NOT NULL default '0000-00-00 00:00:00', 
    `date_modified` timestamp NOT NULL default '0000-00-00 00:00:00', 
    `status` enum('softdeleted','tobedeleted','active') default 'active', 

    PRIMARY KEY (`id`), 
    KEY `image_user` (`user_id`), 
    KEY `image_item` (`item_id`), 
    KEY `image_mod_by` (`moderated_by`), 
    CONSTRAINT `image_mod_by` FOREIGN KEY (`moderated_by`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, 
    CONSTRAINT `image_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='stores image data (not file data)'; 


-- ---------------------------- 
-- Table structure for `specie` 
-- ---------------------------- 
DROP TABLE IF EXISTS `specie`; 
CREATE TABLE `specie` (
    `id` int(11) NOT NULL auto_increment, 
    `name` varchar(256) NOT NULL, 
    `commonname` varchar(256) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM AUTO_INCREMENT=22 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; 


-- ---------------------------- 
-- Table structure for `specie_map` 
-- ---------------------------- 
DROP TABLE IF EXISTS `specie_map`; 
CREATE TABLE `specie_map` (
    `id` int(11) NOT NULL auto_increment, 
    `image_id` int(11) NOT NULL, 
    `specie_id` int(11) NOT NULL, 
    `user_id` int(11) NOT NULL, 
    `karma` int(11) NOT NULL, 
    `date_created` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`), 
    KEY `image_id` (`image_id`), 
    KEY `specie_id` (`specie_id`), 
    CONSTRAINT `specie_map_ibfk_1` FOREIGN KEY (`image_id`) REFERENCES `image` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
+0

Показать определение трех таблиц - особенно «specie_map». –

ответ

2

Внешние ключи работает только с InnoDb в MySQL. MyISAM не поддерживает их (инструкции игнорируются).

И есть ли причина, по которой вы смешиваете несколько двигателей БД?

+2

Я понимаю это. Обратите внимание, что внешний ключ между specie_map и изображением находится между двумя таблицами innodb. У меня даже нет внешнего ключа в таблице MyISAM в этой настройке. И да, у меня есть причина использовать MyIsam для таблицы видов. – Ferdy

+0

@ Ферди вы можете поделиться причиной? (Мне это очень интересно). Затем попробуйте 'SHOW CREATE TABLE specie_map' и' SHOW INDEXES' (http://dev.mysql.com/doc/refman/4.1/en/show-index.html), чтобы проверить правильность создания 'FOREIGN KEY'. – Vyktor

+0

В таблице specie содержится много столбцов среднего текста для хранения больших фрагментов текста. InnoDB позволяет вам иметь несколько из них из-за максимального размера строки. Вот почему я использую MyIsam. – Ferdy

2

Думаю, вам следует опубликовать точные заявления DDL, которые вы использовали при попытке создать эти таблицы и внешний ключ. Внешние ключи между столами innodb работают нормально, но есть еще несколько вещей, которые необходимо обратить внимание:

0) Обе таблицы должны быть InnoDB. Это уже было подчеркнуто другими плакатами, и это, вероятно, является непосредственной причиной вашей проблемы.

1) тип данных ссылочных столбцов (те, которые составляют внешний ключ) и их соответствующие столбцы, должны быть одинаковыми. Например, вы не можете создать ограничение внешнего ключа в столбце INT UNSIGNED для простого столбца INT.

2) если внешний ключ создан как часть таблицы DDL, обязательно укажите определение внешнего ключа в разделе ограничений, то есть ниже всех определений столбцов. Например:

CREATE TABLE parent (
    id int unsigned PRIMARY KEY 
); 

CREATE TABLE child (
    parent_id int unsigned 
, foreign key (parent_id) 
     references parent (id) 
); 

будет работать, но это:

CREATE TABLE child (
    parent_id int unsigned 
     foreign key references parent (id) 
); 

не будет. Он будет терпеть неудачу, потому что синтаксический анализатор MySQL игнорирует эти типы определений ограничений даже до того, как InnoDB будет создавать таблицу (глупо, но так оно и есть)

3) Должен быть индекс по всем столбцам, на которые делается ссылка. Обычно ссылочные столбцы в любом случае будут составлять первичный ключ или уникальное ограничение, но именно ваше задание должно определить этот до, определяющий внешний ключ.

Заключительный совет: если вы думаете, что ваш DDL в порядке, но вы все равно получите ошибку при выполнении его, например, как это:

ERROR 1005 (HY000): Can't create table 'test.child' (errno: 150) 
Warning (Code 150): Create table 'test/child' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns. 

Error (Code 1005): Can't create table 'test.child' (errno: 150) 

Тогда эти ошибки могут до сих пор не раскрывают истинную природу ошибка (глупо снова, но так оно и есть). Для того, чтобы пролить свет на это, запустите эту команду сразу после попытки создать внешний ключ:

SHOW ENGINE INNODB STATUS; 

Это даст вам кучу информации о состоянии, и один раздел там выглядит следующим образом:

------------------------ 
LATEST FOREIGN KEY ERROR 
------------------------ 
120122 11:38:28 Error in foreign key constraint of table test/child: 
foreign key (parent_id) references parent (id)): 
Cannot find an index in the referenced table where the 
referenced columns appear as the first columns, or column types 
in the table and the referenced table do not match for constraint. 
Note that the internal storage type of ENUM and SET changed in 
tables created with >= InnoDB-4.1.12, and such columns in old tables 
cannot be referenced by such columns in new tables. 
See http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html 
for correct foreign key definition. 

Как вы можете видеть, это дает немного больше информации и раскрывает истинную проблему, а именно «типов столбцов в таблице и ссылочной таблице не совпадают для ограничения»

Так что, пожалуйста, напишите ваше фактическое DDL, я Я уверен, что там где-то есть проблема.

+0

Я делаю ставку на вторую возможность (тихий сбой при создании FK). –

+0

Спасибо, я отправил DDL сейчас. На первый взгляд, я думаю, что я согласен с условиями, о которых вы упоминаете. – Ferdy

+0

Проверка статуса InnoDB не приводит к ошибкам FK, связанным с соответствующими таблицами. – Ferdy

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