Предотвращение одновременного использования двух внешних ключей NULL - PullRequest
3 голосов
/ 05 ноября 2019

В MySQL / MariaDB, как я могу предотвратить одновременное использование двух внешних ключей NULL? Сначала это кажется довольно простым, я использовал ограничение оператора CREATE, например:

CREATE TABLE `Table` (
    `foo_id` INT UNSIGNED UNIQUE DEFAULT NULL,
    `bar_id` INT UNSIGNED UNIQUE DEFAULT NULL,
    CONSTRAINT `CHECK_keys_present` CHECK (
        ((`foo_id` IS NOT NULL) OR (`bar_id` IS NOT NULL)) != FALSE
    ),
    FOREIGN KEY (`foo_id`) REFERENCES `Foo` (`foo_id`) ON UPDATE CASCADE ON DELETE SET NULL,
    FOREIGN KEY (`bar_id`) REFERENCES `Bar` (`bar_id`) ON UPDATE CASCADE ON DELETE SET NULL
);

Это решение работает, пока я вручную обновляю значения в столбцах foo_id и bar_id. В этом случае столбцы не становятся NULL одновременно. Однако, когда я удаляю строки из таблицы Foo или Bar (которая затем устанавливает значения внешних ключей в NULL из-за предложений ON UPDATE), ограничение CHECK_keys_present не срабатывает.

Кроме того, я пытался использовать BEFORE UPDATE триггеры, но, похоже, они тоже не работают.

Я использую MariaDB версии 10.4.8.

Также я 'мы использовали странную конструкцию ((`foo_id` IS NOT NULL) OR (`bar_id` IS NOT NULL)) != FALSE, потому что просто (`foo_id` IS NOT NULL) OR (`bar_id` IS NOT NULL) не работал.

Ответы [ 2 ]

2 голосов
/ 05 ноября 2019

Это не полный ответ, потому что я не нашел ссылку, относящуюся к ограничениям check. Однако MariaDB не применяет триггеры в каскадах внешних ключей :

Для триггеров действуют следующие ограничения.

. ,,- Триггеры не активируются действиями внешнего ключа.

Я бы предположил, что ограничения check попадают в одну категорию.

Это будет означать, что вы не можете делать то, что хотите скаскадное ограничение внешнего ключа.

0 голосов
/ 09 ноября 2019

FOREIGN KEYs, TRIGGERs, CHECK и т. Д. Имеют только базовые возможности. Более сложные вещи необходимо выполнить в коде приложения или в хранимой процедуре.

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