MySQL - Conditional Foreign Key Constraints

心不动则不痛 提交于 2019-12-17 00:46:18

问题


I have following 'comments' table in my app:

comments
--------
id           INT
foreign_id   INT
model        TEXT
comment_text TEXT
...

the idea of this table is to store comments for various parts of my app - it can store comments for blog post i.e:

1|34|blogpost|lorem ipsum...

user picture:

2|12|picture|lorem ipsum...

and so on.

now, is there a way to force FOREIGN KEY constraint on such data?

i.e. something like this in comments table:

FOREIGN KEY (`foreign_id`) REFERENCES blogposts (`id`)
//but only when model='blogpost'

回答1:


You're attempting to do a design that is called Polymorphic Associations. That is, the foreign key may reference rows in any of several related tables.

But a foreign key constraint must reference exactly one table. You can't declare a foreign key that references different tables depending on the value in another column of your Comments table. This would violate several rules of relational database design.

A better solution is to make a sort of "supertable" that is referenced by the comments.

CREATE TABLE Commentable (
  id SERIAL PRIMARY KEY
);

CREATE TABLE Comments (
  comment_id SERIAL PRIMARY KEY,
  foreign_id INT NOT NULL,
  ...
  FOREIGN KEY (foreign_id) REFERENCES Commentable(id)
);

Each of your content types would be considered a subtype of this supertable. This is analogous to the object-oriented concept of an interface.

CREATE TABLE BlogPosts (
  blogpost_id INT PRIMARY KEY, -- notice this is not auto-generated
  ...
  FOREIGN KEY (blogpost_id) REFERENCES Commentable(id)
);

CREATE TABLE UserPictures (
  userpicture_id INT PRIMARY KEY, -- notice this is not auto-generated
  ...
  FOREIGN KEY (userpicture_id) REFERENCES Commentable(id)
);

Before you can insert a row into BlogPosts or UserPictures, you must insert a new row to Commentable to generate a new pseudokey id. Then you can use that generated id as you insert the content to the respective subtype table.

Once you do all that, you can rely on referential integrity constraints.



来源:https://stackoverflow.com/questions/2002985/mysql-conditional-foreign-key-constraints

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