grz*_*zes 55 mysql sql database-design foreign-keys polymorphic-associations
我的应用程序中有以下"评论"表:
comments
--------
id INT
foreign_id INT
model TEXT
comment_text TEXT
...
Run Code Online (Sandbox Code Playgroud)
这个表的想法是存储我的应用程序的各个部分的注释 - 它可以存储博客帖子的评论,即:
1|34|blogpost|lorem ipsum...
Run Code Online (Sandbox Code Playgroud)
用户图片:
2|12|picture|lorem ipsum...
Run Code Online (Sandbox Code Playgroud)
等等.
现在,有没有办法强制FOREIGN KEY约束这些数据?
即在评论表中这样的东西:
FOREIGN KEY (`foreign_id`) REFERENCES blogposts (`id`)
//but only when model='blogpost'
Run Code Online (Sandbox Code Playgroud)
Bil*_*win 91
您正在尝试进行称为多态关联的设计.也就是说,外键可以引用几个相关表中的任何一个中的行.
但是外键约束必须恰好引用一个表.您不能声明引用不同表的外键,具体取决于表的另一列中的值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)
);
Run Code Online (Sandbox Code Playgroud)
您的每种内容类型都将被视为此超类型的子类型.这类似于面向对象的接口概念.
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)
);
Run Code Online (Sandbox Code Playgroud)
在将行插入BlogPosts
或之前UserPictures
,必须插入新行Commentable
以生成新的伪代码ID.然后,您可以在将内容插入相应的子类型表时使用该生成的ID.
完成所有操作后,您可以依赖参照完整性约束.