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