Spec-Zone.ru › MySQL 9.2

1.7.2.3 Отличия в ограничении FOREIGN KEY

Реализация ограничений внешнего ключа в MySQL отличается от стандарта SQL в следующих ключевых аспектах:

  • Если в родительской таблице несколько строк имеют одинаковое значение связанного ключа, InnoDB выполняет проверку внешнего ключа так, как будто другие родительские строки с одинаковым значением ключа не существуют. Например, если вы определили ограничение типа RESTRICT, и есть дочерняя строка со множеством родительских строк, InnoDB не позволяет удалить ни одну из родительских строк. Это показано в следующем примере:

    mysql> CREATE TABLE parent (
        ->     id INT,
        ->     INDEX (id)
        -> ) ENGINE=InnoDB;
    Query OK, 0 rows affected (0.04 sec)
    
    mysql> CREATE TABLE child (
        ->     id INT,
        ->     parent_id INT,
        ->     INDEX par_ind (parent_id),
        ->     FOREIGN KEY (parent_id)
        ->         REFERENCES parent(id)
        ->         ON DELETE RESTRICT
        -> ) ENGINE=InnoDB;
    Query OK, 0 rows affected (0.02 sec)
    
    mysql> INSERT INTO parent (id)
        ->     VALUES ROW(1), ROW(2), ROW(3), ROW(1);
    Query OK, 4 rows affected (0.01 sec)
    Records: 4  Duplicates: 0  Warnings: 0
    
    mysql> INSERT INTO child (id,parent_id)
        ->     VALUES ROW(1,1), ROW(2,2), ROW(3,3);
    Query OK, 3 rows affected (0.01 sec)
    Records: 3  Duplicates: 0  Warnings: 0
    
    mysql> DELETE FROM parent WHERE id=1;
    ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key
    constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY
    (`parent_id`) REFERENCES `parent` (`id`) ON DELETE RESTRICT)
    
  • Если ON UPDATE CASCADE или ON UPDATE SET NULL рекурсивно обновляет ту же таблицу, которую уже обновлял ранее в рамках той же каскадной операции, он действует так, как будто RESTRICT. Это означает, что вы не можете использовать самоссылочные ON UPDATE CASCADE или ON UPDATE SET NULL операции. Это сделано для предотвращения бесконечных циклов, возникающих в результате каскадных обновлений. Самоссылочные ON DELETE SET NULL, с другой стороны, возможны, как и самоссылочные ON DELETE CASCADE. Каскадные операции не могут быть вложены глубже чем на 15 уровней.

  • В операторе SQL, который вставляет, удаляет или обновляет множество строк, ограничения внешнего ключа (как и ограничения уникальности) проверяются по строкам. При выполнении проверки внешних ключей InnoDB устанавливает общие блокировки на уровне строк для дочерних или родительских записей, которые он должен проверить. MySQL проверяет ограничения внешнего ключа немедленно; проверка не откладывается до подтверждения транзакции. Согласно стандарту SQL, поведение по умолчанию должно быть отложенной проверкой. То есть ограничения проверяются только после того, как весь оператор SQL был обработан. Это означает, что нельзя удалить строку, которая ссылается на себя с помощью внешнего ключа.

  • Ни один из двигателей хранилища, включая InnoDB, не распознает или не применяет предложение MATCH, используемое в определениях ограничений целостности ссылок. Использование явного предложения MATCH не имеет указанного эффекта и приводит к тому, что предложения ON DELETE и ON UPDATE игнорируются. Следует избегать указания предложения MATCH.

    Предложение MATCH в стандарте SQL управляет тем, как обрабатываются значения NULL в составном (многоколоночном) внешнем ключе при сравнении с первичным ключом в связанной таблице. MySQL по сути реализует семантику, определенную MATCH SIMPLE, которая позволяет внешнему ключу быть полным или частично NULL. В этом случае строка (таблица потомков) содержащая такой внешний ключ может быть вставлена, даже если она не соответствует никакой строке в связанной (родительской) таблице. (Возможно реализовать другую семантику с помощью триггеров.)

  • Ограничение FOREIGN KEY, ссылающееся на не-UNIQUE ключ, не является стандартным SQL, а скорее расширением InnoDB, которое теперь устарело и должно быть включено, установив restrict_fk_on_non_standard_key. Вы должны ожидать, что поддержка использования нестандартных ключей будет удалена в будущих версиях MySQL, и перейти от них сейчас.

    Двигатель хранилища NDB требует явного уникального ключа (или первичного ключа) для любого столбца, на который ссылается внешний ключ, согласно стандарту SQL.

  • Для двигателей хранилища, которые не поддерживают внешние ключи (такие как MyISAM), MySQL Server анализирует и игнорирует спецификации внешних ключей.

  • Предыдущие версии MySQL анализировали, но игнорировали “встроенные REFERENCES спецификации” (как определено в стандарте SQL), где ссылки были определены как часть спецификации столбца. MySQL 9.2 принимает такие REFERENCES предложения и применяет созданные таким образом внешние ключи. Кроме того, MySQL 9.2 допускает неявные ссылки на первичный ключ родительской таблицы. Это означает, что следующий синтаксис допустим:

    CREATE TABLE person (
        id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
        name CHAR(60) NOT NULL,
        PRIMARY KEY (id)
    );
    
    CREATE TABLE shirt (
        id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
        style ENUM('tee', 'polo', 'dress') NOT NULL,
        color ENUM('red', 'blue', 'yellow', 'white', 'black') NOT NULL,
        owner SMALLINT UNSIGNED NOT NULL REFERENCES person,
        PRIMARY KEY (id)
    );
    

    Вы можете убедиться в этом, проверив вывод SHOW CREATE TABLE или DESCRIBE, например так:

    mysql> SHOW CREATE TABLE shirt\G
    *************************** 1. row ***************************
           Table: shirt
    Create Table: CREATE TABLE `shirt` (
      `id` smallint unsigned NOT NULL AUTO_INCREMENT,
      `style` enum('tee','polo','dress') NOT NULL,
      `color` enum('red','blue','yellow','white','black') NOT NULL,
      `owner` smallint unsigned NOT NULL,
      PRIMARY KEY (`id`),
      KEY `owner` (`owner`),
      CONSTRAINT `shirt_ibfk_1` FOREIGN KEY (`owner`) REFERENCES `person` (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
    

Для получения дополнительной информации об ограничениях внешнего ключа, см. Раздел 15.1.21.5, «Ограничения FOREIGN KEY».

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-9.2-en/ansi-diff-foreign-keys.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API