关于数据库设计:将一个表中的多个外键定义为多个表

Defining multiple foreign keys in one table to many tables

在有三个模型:

邮件:

  • ID
  • 标题

照片:

  • ID
  • 文件路径

评论:

  • ID
  • _邮件ID

与相应的数据库表。现在,如果我想让我的文章的评论只有我可以简单的添加以下:对外ALTER TABLE comment ADD FOREIGN KEY (post_id) REFERENCES post (id)密钥。但我想让其他的评论对模型(配置文件,照片,视频等)和保存在一个表的所有评论。如何能在各对外键(当然需要TCS的蠕虫)在这样的情况?


找到一些常见的帖子、简介等——我用Entity来表示缺少更好的单词,然后是子类型。

  • 在这个模型中,一个实体可以有多个注释,一个注释只属于一个实体。

alt text


你可以这样做:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 post:
  * post_id (PK)
  * title
  * body

 photo:
  * photo_id (PK)
  * filepath

 comment:
  * comment_id (PK)
  * body

 comment_to_post
  * comment_id (PK) -> FK to comment.comment_id
  * post_id (PK) -> FK to post.post_id

 comment_to_photo
  * comment_id (PK) -> FK to comment.comment_id
  * photo_id (PK) -> FK to photo.photo_id

仍然有可能发表属于两个不同项目的评论。如果你认为这是一个问题,我可以尝试改进设计。


如果你想知道一列中是否可以有多个外键,那么答案是"不,你不能"。

如果你想的话,可以有单独的外键。这样您就可以像这样修改注释表-

1
2
3
4
5
6
 comment:
  * comment_id (PK)
  * PostID (FK to Post.PostID)
  * PhotoID (FK to <Photo>.PhotoID)
  * ProfileID (FK to <Profile>.ProfileID)
  * Body

而且,您必须确保在注释表的postid、photoid和profileid列中允许空值,也可能将默认值设置为空。

这是实现这一目标的DDL-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
Create table Photo
(
PhotoID int,
PhotoDesc varchar(10),
Primary key (PhotoID)
)

Create table Post
(
PostID int,
PostDesc varchar(10),
Primary key (PostID)
)

Create table Profiles
(
ProfileId int,
ProfileDesc varchar(10),
Primary key (ProfileId)
)

Create table Comment  
(
CommentID int,
PhotoID int,
PostID int,
ProfileId int,
body varchar(10),
Primary key (CommentID),
Foreign key (PhotoID) references Photo(PhotoID),
Foreign key (PostID) references Post(PostID),
Foreign key (ProfileId) references Profiles(ProfileId)
)

insert into Photo values (1,'Photo1')
insert into Photo values (2,'Photo2')
insert into Photo values (3,'Photo3')

insert into Post values (11,'Post1')
insert into Post values (12,'Post2')
insert into Post values (13,'Post3')

insert into Profiles values (111,'Profiles1')
insert into Profiles values (112,'Profiles2')
insert into Profiles values (113,'Profiles3')

insert into Comment (CommentID,PhotoID,body) values (21,1,'comment1')
insert into Comment (CommentID,PhotoID,body) values (22,3,'comment2')
insert into Comment (CommentID,PostID,body) values (23,11,'comment3')
insert into Comment (CommentID,PostID,body) values (24,12,'comment4')
insert into Comment (CommentID,ProfileId,body) values (25,112,'comment5')
insert into Comment (CommentID,ProfileId,body) values (26,113,'comment6')

-- to select comments seperately for Photos, profiles and posts
select * from Comment where PhotoID is not null
select * from Comment where ProfileId is not null
select * from Comment where PostID is not null


由于照片注释与日志注释不同,所以我将它们存储在单独的相关表中。所以我会:

职位:

  • 波斯蒂德
  • 标题
  • 身体

后注释:

  • 注释ID
  • Post-ID正文

照片:

  • 似照片
  • 文件路径

光通信:

  • 注释ID
  • 照片ID
  • 身体

使用id作为pk的名称是一种糟糕的实践,它使报告变得更加困难,并且更可能无意中在复杂查询中加入错误的表。如果您使用tablenameid并始终为fks使用相同的名称,那么也更容易看到关系。


在这种情况下,您可以添加一个包含"photo"、"profile"的枚举字段…它将是外键的第二部分