【问题标题】:Is it possible to connect two or more tables with IDs in one column of a table?是否可以在表的一列中连接两个或多个具有 ID 的表?
【发布时间】:2017-03-19 00:16:13
【问题描述】:

我有以下想要解决的问题。我想添加一列 ID,它应该将一个 comment 连接到上面的一个表,例如视频。我不想在上面的表格中添加 CommentID 列,因为每个表格都可能有多个 cmets。

思路一: 我知道数据库,也可以设计成如下的形式,在查询中加入join。查询看起来像这样:SELECT * FROM Comments c JOIN Videos_Comments vc ON c.CommentID=vc.CommentID JOIN Videos v ON vc.VideoID=v.VideoID ...

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

编辑: 想法 3(来自 yair):

还有其他更认可的实施方式吗?

Tl;dr:我怎样才能在同一列中拥有不同表的 ID,同时能够保留 ID 的来源。

【问题讨论】:

标签: sql database polymorphic-associations


【解决方案1】:

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

但是,如果您还为非视频的内容(如帖子或图片表)设置了 cmets,则不要忘记 VideoID 列 - 这很糟糕。而是添加另外两列:CommentedOnCommentedOnID

CommentedOn 表示评论所针对的事物的类型。可能的值为 videospostspictures(如果这些是您保留 cmets 的类型)。

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

请注意,可能有比我使用的名称更好的名称(CommentedOnCommentedOnID)。我使用它们只是因为我对 cme​​ts 所引用的表了解不够。例如,如果 cmets 在视频、图片和音频上 - 我会将列命名为 MediaTypeMediaID。名字很重要。

例如,如果您有一个 ID 为 123454321 的视频,为了检索该特定视频的所有 cmets,您可以使用不带 JOINs 的简单查询:

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

【讨论】:

  • 好答案。也许向提问者显示一个关于您如何知道根据 CommentedOn 列动态查询哪个表的查询
  • 非常感谢您的回答。我编辑了问题,以包含您的建议,但我仍在努力解决这个问题。
  • @CodePure 我添加了一个示例查询,显示如何检索特定视频的所有 cmets。 HTH
  • @yair 其实我在想一个更动态的查询。所以我发布了一个允许这样的答案。
  • @Edward 为什么在干净简单的查询就足够的情况下使用动态查询?
【解决方案2】:

如您所见,实现表格的方法有很多种。我提供了一种通过使用游标设置来动态查询的方法。我还提供了另一种方法,即创建一个过程,然后您可以传入要使用的 tableName 并让它根据该表名称返回所有 cmets。这些当然部分基于想法 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.*”返回的列

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-16
    • 1970-01-01
    • 2014-03-06
    • 1970-01-01
    • 2019-08-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多