Is there such a thing as a reverse foreign key?

亡梦爱人 提交于 2019-12-12 14:08:11

问题


In MySQL, is there a way to specify that a.column cannot exist in b.column - a reverse foreign key?

In other words:

# 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;

回答1:


No there is no such thing.

You would need to do that in a trigger:

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:


To a point, if you want "can be in A or B, but not both"

This is the "super key/sub type" pattern

Create a new table AB that has a 2 columns

  • SomeUniqueValue, PK
  • WhichChild char(1), limited to 'a' or 'b'

There is also a unique constraint on both columns

Then

  • Add a WhichChild column to tables A and B. In A, it is always 'a'. In B, always 'b'
  • Add foreign keys from A to AB and B to AB on both columns

Now, SomeUniqueValue can be in only A or B.

Note: in proper RDBMS you'd use check constraints or computed columns to restrict WhichChild to 'a' or 'b' as needed. But MySQL is limited so you need to use triggers in MySQL. However, this is simpler then testing table B for each insert in A etc




回答3:


Try to create a trigger and throw an error from it.



来源:https://stackoverflow.com/questions/7527587/is-there-such-a-thing-as-a-reverse-foreign-key

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!