MYSQL ON DELETE CASCADE - Работает только при установке на первичный ключ - PullRequest
0 голосов
/ 08 октября 2018

Я столкнулся с проблемой с ON DELETE CASCADE в MySQL.Он отлично работает, когда он установлен на поле первичный ключ , но не в других случаях.


Например, у меня есть дочерняя таблица , где яиметь внешний ключ, ссылающийся на поле в родительской таблице 1010 *, но дочерняя таблица 1012 * имеет собственное поле Auto-Incremental ID, которое должно быть первичным ключомпотому что таблицы внуков относятся к нему.

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

Iпроводил исследования безрезультатно.Хотя я предполагаю, что это как-то связано с тем, что система идентифицирует строку по ее первичному ключу, я не смог найти никакой соответствующей информации об этом.

Родительская таблица:

CREATE TABLE IF NOT EXISTS table_parent (
            ID              TINYINT(3)    UNSIGNED PRIMARY KEY AUTO_INCREMENT,
            `level`         TINYINT(1)    NOT NULL,
            updated         DATETIME      NOT NULL DEFAULT NOW()
        );

Дочерний элементtable:

CREATE TABLE IF NOT EXISTS table_child (
            ID              TINYINT(3)    UNSIGNED PRIMARY KEY AUTO_INCREMENT,
            parentId        TINYINT(3)    UNSIGNED NOT NULL,
            `name`          VARCHAR(16)   UNIQUE NOT NULL,
            updated         DATETIME      NOT NULL DEFAULT NOW()
        );

Соотношение:

ALTER TABLE table_child
        ADD FOREIGN KEY (parentId)        REFERENCES table_parent(ID) ON DELETE CASCADE

В двух словах, моя цель - удалить все записи в таблице table_child, где parentId равен удаленной строке в table_parent.

Спасибо за помощь и хорошего дня:)

1 Ответ

0 голосов
/ 08 октября 2018

Мне кажется, что вам не хватает того, что ограничения ссылочной целостности работают только с таблицами InnoDB.В ваших заявлениях DDL отсутствует engine=InnoDB и, скорее всего, по умолчанию используется MyISAM.

Хотя вы не получите сообщение об ошибке, таблицы MyISAM по умолчанию являются теми, которые вы получаете, когда вы не указываете движок, а MyISAM игнорирует операторы ограничений.

Исправленный CREATE TABLEоператор будет выглядеть следующим образом:

CREATE TABLE IF NOT EXISTS table_parent (
        ID              TINYINT(3)    UNSIGNED PRIMARY KEY AUTO_INCREMENT,
        `level`         TINYINT(1)    NOT NULL,
         updated         DATETIME      NOT NULL DEFAULT NOW()
    ) ENGINE=InnoDB;

Вот песочница SQL , демонстрирующая, что ограничение корректно и работает так, как вы ожидаете.

Это не относится к вопросу, но мне кажется странным, что вы объявили все свои ключи TINYINT.Это будет означать, что в ваших таблицах может быть максимум 255 строк ...

...