使用匿名外键连接表

发布于 2024-11-02 11:01:51 字数 1247 浏览 1 评论 0原文

相关

与我的另一个问题相关:

评论系统设计

数据设计假设

我有一个标签表:

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 有很大区别,但基于设计的答案是我需要的只是这些,除非用于演示,否则不需要任何代码。

这是通过多个查询执行此操作的唯一方法吗?

Related

Related to my other question:

Comment system design

Data Design

Let's say I have a tags table:

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

And two content tables:

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

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

There will be more tables with anchors as well, it's not just 2.

Then to associate a tag with an above entity:

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

My question is, once I have built up my associations of blogs and tutorials with a specific tag, is there any way to write a query to return blogs or tutorials with a specific tag? Without needing to have separate queries for both the Blogs and Tutorials?

The main use would be for search, something along the lines of (pseudo):

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

I'm using SQL Server 2008 Express, and ASP.net 4 (c#) if it makes much difference with Linq to SQL, but a design based answer is all I need, not any code necesserially unless for demonstration.

Is the only way to do this with multiple queries?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

指尖上得阳光 2024-11-09 11:01:51

这将是“通常的”方法。

在此处输入图像描述

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 ;

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

This would be "the usual" approach.

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 ;

You may package this into a view to help isolate any future schema changes from the application code.

烙印 2024-11-09 11:01:51

我建议使用联合体。该查询只有一个结果集,但在幕后它会合并到一起查询。

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),并将密钥设置为超级类型。

I would recommend the use of a union. This query would only have one result set but under the hood it is merging to queries together.

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

Then in your vb code just do an if on the type field. In linq you will have to write the query using .union command. I just wrote a generic sql solution. It can easily be transformed to linq though.

As a side note conditional foreign keys makes me want to shutter. In modern database design you should always avoid a key that can go to multiple tables it is hard to enforce CRUD and more confusing to query. I would suggest creating a super type of tblBlogs and tblTutorials like tblWebsites and making the key go to the supertype.

明明#如月 2024-11-09 11:01:51

您不仅可以使用一个查询选择必要的数据,还可以摆脱客户端中的 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

Not only can you select the necessary data using one query, but you can also get rid of the if condition in the client, the one which decides which href to output, because you can select data and construct the output strings at the same time, in the same query. Your client would then only have to iterate through the result set and output the strings.

Basically, you query would be a UNION of two subqueries, but I would do that somewhat differently from how @JStead has offered, something like this possibly:

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

As you can see, the query returns data ready to be output. Therefore your client's logic gets simplified to something like this:

for each record returned
    response.write(OutputString)
next
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文