0

相关匿名外键

连接表相关的我的其他问题:

Comment system design

数据设计

比方说,我有一个标签表:

tblTags 
------------- 
TagID (int) 
Name (string) 

和两个内容表:

tblBlogs 
------------- 
Anchor (GUID, Primary Key) 
BlogTitle (string) 
+ More custom fields 

tblTutorials 
------------- 
Anchor (GUID, Primary Key) 
TutorialTitle (string) 
+ More custom fields 

将会有更多的表与锚为好,它不只是2

然后标签与上述实体相关联:

tblTagAnchors 
------------- 
TagID (int, Foreign Key) 
Anchor (GUID, Foreign Key) 

我的问题是,一旦我建立了具有特定标记的博客和教程的关联,是否有任何方法来编写查询以返回具有特定标记的博客或教程?无需为博客和教程分别查询?

主要用途是用于搜索,东西线沿线的(伪):

select from tblBlogs and tblTutorials where the GUID exists in tblTagAnchors where tagID = 5 

for each record returned 
    if record from Blog 
     response.write("<a href=blogView.aspx?ID=" + recID) 
    else if record from Tutorial 
     response.write("<a href=tutorialView.aspx?ID=" + recID) 
next 

我使用SQL Server 2008 Express和ASP.net 4(C#),如果它使太大的区别Linq to SQL,但基于设计的答案是我所需要的,除非用于演示,否则不需要任何代码。

是否有多个查询做到这一点的唯一方法?

回答

3

我会推荐使用联合。这个查询只有一个结果集,但是它们正在合并到查询中。

Select b.rec_id,'Blog' as type from tblBlogs b 
inner join tblTagAnchors ta on ta.anchor = b.anchor 
where ta.tagid = 5 
union 
Select t.rec_id,'Tutorials' as type from tblTutorials t 
inner join tblTagAnchors ta on ta.anchor = t.anchor 
where ta.tagid = 5 

然后在你的VB代码中只需要在类型字段上做一个if。在linq中,您将不得不使用.union命令编写查询。我只写了一个通用的SQL解决方案。它可以很容易地转换为LINQ。

作为附注,有条件的外键让我想要快门。在现代数据库设计中,你应该总是避免一个可以转到多个表的键,这很难执行CRUD并且更难以查询。我会建议创建一个超级类型的tblBlogs和tblTutorials,如tblWebsites,并使密钥转到超类型。

+1

我同意@JStead的回答。你有两个表,所以你需要两个查询(在你的例子中),Union会将它们合并成一个结果集。但是,他关于“有条件的外键使我想要关闭”的评论对我来说有点令人困惑,因为您的设计是处理多对多表格设计的经典方式。一个标签可以在许多博客(或教程)中,一个博客(或教程)可以有很多标签。因此,你需要一个多对多的表(tblTagAnchors)来跟踪它们 - 我不确定你会有什么其他选择。它也不违反数据库设计规范化。 – Jim 2011-04-18 12:18:07

+0

当我开始工作时,我会概述我的设计,但我的问题不在于拥有关联表。无论如何,你都会有一张关联表。我的查询说明的主要问题是您有一个外键关系,这取决于网站的类型。 – JStead 2011-04-18 12:29:48

+0

基于联合的查询将比基于左外部联接的查询更高效。 – 2011-04-18 14:15:34

1

您不仅可以选择使用一个查询所需要的数据,但是你也可以在客户端摆脱if条件,这决定了其中一个href输出,因为你可以选择数据和构建输出字符串在同一时间,在同一个查询中。您的客户端只需遍历结果集并输出字符串。

基本上,你的查询将两个子查询的UNION,但我会做到这一点有所不同,从如何@JStead提供了,这样的事情可能是:

SELECT 
    OutputString = '<a href=' + SrcName + 'View.aspx?ID=' + CAST(x.recID AS varchar) 
FROM (
    SELECT 'blog' AS SrcName, Anchor, recID 
    FROM tblBlogs 
    UNION ALL 
    SELECT 'tutorial' AS SrcName, Anchor, recID 
    FROM tblTutorials 
) x 
    INNER JOIN tblTagAnchors ta ON x.Anchor = ta.Anchor 

正如你所看到的,查询返回数据准备好输出。因此,你的客户的逻辑被简化为这样的事情:

for each record returned 
    response.write(OutputString) 
next 
+0

非常感谢您的时间! – 2011-04-19 08:32:45

5

这将是“平常”的做法。

enter image description here

select 
     p.PublicationID 
    , p.PublicationType 
    , p.PublicationTitle 
    , t.TagID 
    -- other blog/tutorial specific fields here 
from Publication as p 
left join Blog  as b on (b.PublicationID = p.PublicationID and p.PublicationType = 'B') 
left join Tutorial as t on (t.PublicationID = p.PublicationID and p.PublicationType = 'T') 
join PublicationTag as x on x.PublicationID = p.PublicationID 
join Tag   as t on t.TagID = x.TagID ; 

您可以打包到这一点,以便帮助隔离来自应用程序代码的任何未来架构更改。

+0

感谢您的选择和设计,非常感谢您的时间 – 2011-04-19 08:32:12