2009-09-06 28 views
0

美好的一天!繼續問題「用於存儲標記記錄的DB模式」 - 如何選擇標籤項目列表?

有很多的問題,如何在DB標籤存放在這裏的計算器,我終於決定使用TOXI辦法(項目表,標籤表,並多到許多中間表)http://www.pui.ch/phred/archives/2005/04/tags-database-schemas.html

我想在頁面上顯示20-50個標籤項目列表,每個標籤列表都包含它的標籤列表(我在ASP.NET 3.5中使用LINQ2SQL)。

我看到一些選項:

  1. 的項目超過運行查詢的名單首先查詢每一個選項,爲每個項目的標籤 - 似乎是緩慢的,但在應用程序級緩存可以改善情況。

  2. 非正常化物品表和物品標籤存儲在「物品」表中的文本字段中。

但是這兩種選擇對我來說都不好,可能是我錯過了什麼?

在此先感謝!

回答

0

2KLE:謝謝,我知道了。這個查詢的結果是每個標籤一行(項目數據被複制),所以無論如何需要處理應用程序代碼中的結果集。我對嗎?

對於LINQ 2 SQL我使用DataLoadOptions來指定要加載的關聯數據。這裏是LINQ2SQL生成的代碼示例,用於選擇包含所有標籤的所有項目。

請注意在我的示例中Items表稱爲Snippets(所以我們有Snippets,Tags和SnippetsTags表)。另外需要注意的是,LINQ2SQL不支持開箱即用的多對多關係,所以有一箇中間表(SnippetsTag)的實體類。下面是C#代碼:

  using (SnippetsDataContext context = UtilsLinq.CreateContext()) 
     { 
      DataLoadOptions dl = new DataLoadOptions(); 
      dl.LoadWith<Snippet>(s => s.SnippetsTags); 
      dl.LoadWith<SnippetsTag>(st => st.Tag); 
      context.LoadOptions = dl; 
      var result = (from s in context.Snippets 
          select s).ToList(); 

      string x = result.First().SnippetsTags.First().Tag.Title; 
     } 

這裏是一個的LINQ to SQL生成SQL:

SELECT [t0].[Id], [t0].[Title], [t0].[Text], [t0].[Created], [t1].[Id] AS [Id2], [t1].[TagId], [t1].[SnippetId], [t2].[Id] AS [Id3], [t2].[Title] AS [Title2], (
    SELECT COUNT(*) 
    FROM [dbo].[SnippetsTags] AS [t3] 
    INNER JOIN [dbo].[Tags] AS [t4] ON [t4].[Id] = [t3].[TagId] 
    WHERE [t3].[SnippetId] = [t0].[Id] 
    ) AS [value] 
FROM [dbo].[Snippets] AS [t0] 
LEFT OUTER JOIN ([dbo].[SnippetsTags] AS [t1] 
    INNER JOIN [dbo].[Tags] AS [t2] ON [t2].[Id] = [t1].[TagId]) ON [t1].[SnippetId] = [t0].[Id] 
ORDER BY [t0].[Id], [t1].[Id], [t2].[Id] 
0

我不推薦選項2,因爲它會過分複雜的隔離一個標籤或一組標籤。我的建議是將數據模型保留原樣(ITEMS,TAGS,ITEM_TAGS_XREF),並針對包含包含標記列表的計算列的VIEW進行查詢。如果你提到了你正在使用的數據庫,我們可以提供這樣的查詢,它將構建一個項目與之關聯的標籤的逗號/等分隔字符串。

假設主鍵和外鍵都相應設置,性能應該不錯 - 應用程序層中是否有滯後現象發生?

+0

感謝您詳細的答覆!你能分享這個視圖的僞代碼嗎?計算列是否應對標記表上的每一行執行相關子查詢?在性能方面可以接受嗎? 謝謝! – artvolk 2009-09-06 20:01:23

+0

你使用了哪個數據庫?我不熟悉LINQ。我相信查詢可以被構建爲使用JOIN而不是相關的查詢。 – 2009-09-06 20:19:24

0

如果我理解正確...

也許你可以創建一個連接所有三個表的查詢。在只有一個快速查詢,你會得到所有的信息......在SQL中,它可能是這樣的:

select ... //itemColumns, tagColumns 
    from item 
    join tagItem on item.id = tagItem.itemId 
    join tag on tag.id = tagItem.tagId 
    where ... // your other conditions