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