MySQL - 条件外键约束
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2002985/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
MySQL - Conditional Foreign Key Constraints
提问by grzes
I have following comments
table in my app:
comments
我的应用程序中有下表:
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?
现在,有没有办法强制对此类数据进行 FOREIGN KEY 约束?
i.e. something like this in comments table:
即评论表中的类似内容:
FOREIGN KEY (`foreign_id`) REFERENCES blogposts (`id`)
-- but only when model='blogpost'
回答by Bill Karwin
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.
您正在尝试进行称为Polymorphic Associations的设计。也就是说,外键可以引用几个相关表中的任何一个中的行。
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.
但是外键约束必须正好引用一个表。您不能根据表的另一列中的值声明引用不同表的外键Comments
。这将违反关系数据库设计的几条规则。
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.
在向BlogPosts
or插入一行之前UserPictures
,您必须插入一个新行Commentable
以生成新的伪键 id。然后,您可以在将内容插入到相应的子类型表时使用生成的 id。
Once you do all that, you can rely on referential integrity constraints.
完成所有这些操作后,您就可以依赖参照完整性约束了。