Внешний ключ MySQL "ON DELETE CASCADE" для 3 таблиц - PullRequest
1 голос
/ 16 января 2012

У меня есть 3 таблицы в моей БД (их больше, но к ним еще нет соединений)

  • таблица "молекула" с идентификатором столбца
  • таблица "дескриптор"с столбцами "id" и "молекуле_ид" и внешним ключом, ссылающимся на "молекулу.ид"
  • таблица "tDepDescriptor" с столбцами "id" и "дескриптор_ид" и внешним ключом, ссылающимся на "дескриптор.ид"

(каждая таблица имеет больше столбцов, но ни один из них не действует как внешние ключи или что-то в этом роде)

Для всех внешних ключей указано «при каскаде удаления», все идентификаторы имеют беззнаковые целые (5).

Теперь, если я попытаюсь удалить запись в «молекуле», для которой есть ссылки на записи в «дескрипторе» и «tDepDescriptor», то ничего не произойдет, как если бы внешние ключи были установлены на «при обновлении ограничить», нетошибка дана.Если я удаляю запись в «дескрипторе», все ссылки на записи в «tDepDescriptor» удаляются, как они должны.То же самое происходит, если я пытаюсь удалить запись в "молекуле", для которой есть ссылки на записи в "дескрипторе", но нет ссылок на эти записи "descriptor" в "tDepDescriptor".Таким образом, «каскад удаления» работает для двух таблиц, но «каскад», по-видимому, не передается, когда задействованы три таблицы.

Что таблицы должны делать: Когда я хочу удалить запись в «молекуле», все ссылки в «дескрипторе» удаляются.И поэтому все записи в «tDepDescriptor», которые имеют ссылку на одну из удаленных записей в «дескрипторе», также удаляются.

версия сервера mysql 5.1, движок InnoDB

Есть надежда, что кто-то может последовать этому сложному объяснению и помочь мне.

// РЕДАКТИРОВАТЬ: Нашел проблему.Кажется, проблема с phpMyAdmin, а не с базой данных.нажатие на удаление в PMA не сработало, но кодирование запроса вручную сработало, каскадно пройдя все три таблицы.Странно, но, по крайней мере, я знаю, что мои таблицы работают правильно.

Ответы [ 2 ]

4 голосов
/ 16 января 2012

Достаточно иметь опцию ON DELETE CASCADE.Посмотрите на этот пример:

Создание и заполнение таблиц:

CREATE TABLE molecule (
  id INT(11) NOT NULL,
  PRIMARY KEY (id)
)
ENGINE = INNODB;

CREATE TABLE descriptor (
  id INT(11) NOT NULL,
  molecule_id INT(11) DEFAULT NULL,
  PRIMARY KEY (id),
  CONSTRAINT FK_descriptor_molecule_id FOREIGN KEY (molecule_id)
    REFERENCES molecule(id) ON DELETE CASCADE ON UPDATE RESTRICT
)
ENGINE = INNODB;

CREATE TABLE tdepdescriptor (
  id INT(11) NOT NULL,
  descriptor_id INT(11) DEFAULT NULL,
  PRIMARY KEY (id),
  CONSTRAINT FK_tdepdescriptor_descriptor_id FOREIGN KEY (descriptor_id)
    REFERENCES descriptor(id) ON DELETE CASCADE ON UPDATE RESTRICT
)
ENGINE = INNODB;

INSERT INTO molecule VALUES 
  (1),
  (2),
  (3);

INSERT INTO descriptor VALUES 
  (1, 1),
  (2, 1),
  (3, 2);

INSERT INTO tdepdescriptor VALUES 
  (1, 1),
  (2, 2),
  (3, 3);

Удаление одной молекулы и всего ее дескриптора и всего его tdepdescriptor:

DELETE FROM molecule WHERE id = 1;

SELECT * FROM molecule;
+----+
| id |
+----+
|  2 |
|  3 |
+----+

SELECT * FROM descriptor;
+----+-------------+
| id | molecule_id |
+----+-------------+
|  3 |           2 |
+----+-------------+

SELECT * FROM tdepdescriptor;
+----+---------------+
| id | descriptor_id |
+----+---------------+
|  3 |             3 |
+----+---------------+
0 голосов
/ 30 октября 2013

Пожалуйста, убедитесь, что вы используете Engine InnoDB во всех таблицах, связанных с другими внешними ключами при каскаде обновления / удаления, вы можете использовать:

create table test1 (
  #column definitions, including fk with on delete/update cascade
) engine = "InnoDB";

Мой опыт:

У меня была такая же проблема на одном из моих проектов. Мне уже была разработана база данных для добавления еще нескольких частей. Таблицы не имели каскада удаления / обновления для внешних ключей. Я добавил их, а также добавил другую таблицу из вкладки «запрос» в phpMyAdmin cPanel. поэтому у меня было отношение как:

(приоритеты) 1-м (пакеты) 1-м (стандарты)

Все с каскадом удаления / обновления. Но когда я использовал для удаления «приоритет», «стандарт» не был удален. «Приоритеты» и «пакеты» существовали с движком «InnoDB», и когда я создавал таблицу «стандартов», я не указывал ДВИГАТЕЛЬ, поэтому он по умолчанию использовал «MyISAM», что вызвало проблему. Когда я пересоздал таблицу с явно указанным ENGINE = "InnoDB", проблема была решена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...