将一个表中的多个外键定义为多个表

时间:2010-10-29 09:54:15

标签: database-design foreign-keys

我有3个型号:

发表

  • ID
  • 标题

照片

  • ID
  • 文件路径

注释

  • ID
  • POST_ID

和DB中的相应表格。现在,如果我只想为我的帖子添加评论,我只需添加以下外键:ALTER TABLE comment ADD FOREIGN KEY (post_id) REFERENCES post (id)。但我希望对其他模型(照片,个人资料,视频等)发表评论,并将所有评论保留在一个表中。在这种情况下,如何定义外键(我肯定需要ORM的FK)?

5 个答案:

答案 0 :(得分:10)

你可以这样做:

 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 :(得分:10)

查找帖子,个人资料等常见内容 - 我使用Entity表示缺少更好的单词,然后是子类型。

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

alt text

答案 2 :(得分:2)

如果您想知道单个列是否可以有多个外键,那么您的答案就不行了。

如果您愿意,可以使用单独的外键。所以你可以修改你的评论表 -

 comment:
  * comment_id (PK)
  * PostID (FK to Post.PostID)
  * PhotoID (FK to <Photo>.PhotoID)
  * ProfileID (FK to <Profile>.ProfileID)
  * Body

并且,您必须确保在Comment表中的PostID,PhotoID和ProfileID列中允许空值,并且还可以将默认值设置为null。

这是实现此目的的DDL -

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

答案 3 :(得分:0)

在这种情况下,你可以添加一个包含'photo','profile'的ENUM字段......它将是外键的第二部分

答案 4 :(得分:0)

由于照片评论与评论后评论不同,我会将它们存储在单独的相关表格中。所以我会有:

发表:

  • 帖子ID
  • 标题

PostComment:

  • Commentid
  • post_id body

照片:

  • PHOTOID
  • 文件路径

PhotoComment:

  • Commentid
  • photo_id

使用id作为PK的名称是一种不好的做法,这使得报告变得更加困难,并且更有可能在复杂查询中无意中加入到错误的表中。如果您使用tablenameID并且始终对Fks使用相同的名称,那么也更容易看到关系。