是否可以在表的一列中连接两个或多个具有ID的表?

时间:2017-03-19 00:16:14

标签: sql database polymorphic-associations

我有以下要解决的问题。我想添加一列ID,这些ID应该将一个注释连接到上面的一个表,例如影片。我不想在上面的表中添加 CommentID 列,因为每个表都可以有多个注释。

enter image description here

创意1:我知道数据库,也可以在查询中设计如下连接。查询看起来像这样:SELECT * FROM Comments c JOIN Videos_Comments vc ON c.CommentID=vc.CommentID JOIN Videos v ON vc.VideoID=v.VideoID ...

enter image description here

理念2:另一个想法是为每个表的ID添加前缀,例如V12

修改 创意3(yair): enter image description here

是否有另一种更为批准的实施方式?

Tl; dr:如何在同一列中完成不同表的ID,同时保留ID的来源。

2 个答案:

答案 0 :(得分:2)

如果我正确理解您的问题,您可以直接在评论中添加VideoID列。

但是,如果您对非视频内容(如帖子或图片表)也有评论,那么请忘记VideoID列 - 这很糟糕。而是添加另外两列:CommentedOnCommentedOnID

CommentedOn代表注释评论的类型。可能的值为videospostspictures(如果这些是您保留评论的内容类型)。

CommentedOnID不言自明(但我会解释)。它是评论评论的视频(或帖子或图片)中相应行的ID。

请注意,名称可能比我使用的名称(CommentedOnCommentedOnID)更好。我之所以使用它们只是因为我对评论所引用的表格知之甚少。例如,如果评论是关于视频,图片和音频的 - 我会将列命名为MediaTypeMediaID。名字很重要。

例如,如果您有一个ID为123454321的视频,为了检索该特定视频的所有评论,您可以使用一个没有JOIN的简单查询:

select * from Comments where CommentedOn = 'videos' and CommentOnID = 123454321;

答案 1 :(得分:0)

正如您所看到的,有很多方法可以实现这些表。我提供了一种使用游标设置动态查询的方法。另外,我通过创建一个过程提供了另一种方法,然后您可以传入要使用的tableName,并让它根据该表名返回所有注释。这些当然部分基于构思3而没有额外的CommentsOn表但是CommentTable有一个列CommentOn(nvarchar(64))而不是CommentOnId,当然MediaId是等于主键的条件。 CommentOn字段中的表。我还建议不同的mediaTables将主键名称设置为Id,而不是{tableName} Id,但是如果你必须保持这样,你可以改变下面的一些代码使其工作,但这要复杂得多将表名复数化。

动态查询:

declare @tableName AS Table(Id nvarchar(64))
Insert into @tableName 
    Select distinct(CommentOn) from Comments
declare @tempId nvarchar(64)
declare cur cursor for 
    select Id from @tableName 
open cur
fetch next from cur into @tempId
while @@FETCH_STATUS =0
    Begin
        declare @sql as nvarchar(max)
        set @sql = 'Select t.*,c.* from ' + @tempId + ' as t join Comments as c on t.Id = c.MediaId where c.Comments = ''' + @tempId + ''''
        exec(@sql)
        Fetch Next from cur into @tempId
    End
close cur

程序方式:

create procedure GetComments 
    @tableName nvarchar(64)
AS   
    SET NOCOUNT ON;  
    declare @sql as nvarchar(max)
    set @sql = 'Select t.*,c.* from ' + @tempId + ' as t join Comments as c on t.Id = c.MediaId where c.Comments = ''' + @tempId + ''''
    exec(@sql); 

然后像这样调用:

exec GetComments N'Videos'

您可能想要更改从" t。*,c。*"

返回的列