Есть ли такая вещь, как обратный внешний ключ? - PullRequest
3 голосов
/ 23 сентября 2011

В MySQL есть способ указать, что a.column не может существовать в b.column - обратный внешний ключ?

Другими словами:

# Would not return any rows ever
SELECT * FROM a
INNER JOIN b ON a.column = b.column;

# Would fail
INSERT INTO a
SELECT * FROM b;

# Would not insert any rows
INSERT IGNORE INTO a
SELECT * FROM b;

Ответы [ 3 ]

3 голосов
/ 23 сентября 2011

Нет, такой вещи нет.

Вам нужно сделать это в триггере:

DELIMITER $$

CREATE TRIGGER bi_a_each BEFORE INSERT ON a FOR EACH ROW
BEGIN
  DECLARE forbidden_key INTEGER;
  SELECT id INTO forbidden_key FROM b WHERE b.id = NEW.acolumn LIMIT 1;
  IF forbidden_key IS NOT NULL THEN 
    SELECT * FROM error_insertion_of_this_value_is_not_allowed;
  END IF;
END $$

DELIMITER ;
2 голосов
/ 23 сентября 2011

В какой-то момент, если хотите, «может быть в A или B, но не в обоих»

Это шаблон «супер-ключ / подтип»

Создать новую таблицу ABкоторый имеет 2 столбца

  • SomeUniqueValue, PK
  • WhichChild char (1), ограничен 'a' или 'b'

Существует такжеуникальное ограничение для обоих столбцов

Тогда

  • Добавьте столбец WhichChild в таблицы A и B. В A это всегда «a».В B всегда 'b'
  • Добавлять внешние ключи от A к AB и от B к AB на оба столбца

Теперь SomeUniqueValue может быть только в Aили B.

Примечание: в надлежащей СУБД вы должны использовать проверочные ограничения или вычисляемые столбцы, чтобы ограничить WhichChild до «a» или «b» по мере необходимости.Но MySQL ограничен, поэтому вам нужно использовать триггеры в MySQL.Однако это проще, чем тестировать таблицу B для каждой вставки в A и т. Д.

0 голосов
/ 23 сентября 2011

Попробуйте создать триггер и выдать из него ошибку.

...