Sql 使用匿名外键连接表

Sql 使用匿名外键连接表,sql,database-design,foreign-keys,guid,foreign-key-relationship,Sql,Database Design,Foreign Keys,Guid,Foreign Key Relationship,相关的 关于我的另一个问题: 数据设计 假设我有一个标签表: tblTags ------------- TagID (int) Name (string) 和两个内容表: tblBlogs ------------- Anchor (GUID, Primary Key) BlogTitle (string) + More custom fields tblTutorials ------------- Anchor (GUID, Primary Key) TutorialTitle (s

相关的

关于我的另一个问题:

数据设计

假设我有一个标签表:

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)
我的问题是,一旦我建立了博客和教程与特定标记的关联,有没有办法编写查询来返回带有特定标记的博客或教程?不需要对博客和教程进行单独的查询

主要用于搜索,大致如下(伪):

从tblBlogs和tblTutorials中选择,其中GUID存在于标记ID=5的tblTagAnchors中
对于每个返回的记录
如果从博客记录

write(“我建议使用联合。此查询将只有一个结果集,但在引擎盖下它将合并到一起的查询

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和TBLTutorial,如tblWebsites,并将键转到超类型。

不启用您可以使用一个查询来选择必要的数据,但是您也可以在客户机中取消决定输出哪个
href
if
条件,因为您可以在同一个查询中同时选择数据和构造输出字符串。这样,您的客户机只需迭代结果集并输出字符串

基本上,您的查询将是两个子查询的并集,但我的做法与@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
这将是“通常”的方法

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 ;


您可以将其打包到一个视图中,以帮助从应用程序代码中分离出任何未来的架构更改。

我同意@JStead的回答。您有两个表,因此需要两个查询(在您的示例中),Union将把它们合并到一个结果集中。但是,他关于“条件外键”的评论让我想“这让我有点困惑,因为您的设计是处理多对多表设计的经典方式。一个标记可以在多个博客(或教程)中,而一个博客(或教程)可以有多个标记。因此,您需要一个多对多表(tblTagAnchors)为了跟踪它们--我不确定您还有什么其他选择。这也不违反数据库设计规范化。我将在开始工作时概述我的设计,但我的问题不是拥有关联表。无论如何,这里都有一个关联表。我的查询说明的主要问题是您有一个关联表ign键关系,该关系取决于网站的类型。基于联合的查询将比基于左外联合的查询更有效。@Jim检查Damir的实现。开始时工作有点忙,但这正是我实现此设计的方式。@JStead。是的,这很有意义。谢谢。谢谢您的帮助和a非常感谢您的时间,非常感谢您的时间!
for each record returned
    response.write(OutputString)
next
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 ;