我可以选择为数据库结构编写两种不同的格式:
Article
-------
ArticleID int FK
Article_Tags
------------
ArticleTagID int FK
ArticleID int FK
TagText varchar(50)
或
Article
-------
ArticleID int PK
Article_Tags
------------
ArticleTagID int PK
ArticleID int FK
TagText varchar(50) FK
Tag
---
TagText varchar(50) PK
如果我想要数据库中所有标签的列表,我可以使用:
select distinct tagtext from article_tags
或:
select tagtext from tag
第一种情况非常简单。如果我正确索引它可能会加速。第二个是有点难,因为我必须不断删除没有连接的标签。想象一个相当大的系统,这会更好。
答案 0 :(得分:4)
我会选择哪种解决方案为您的应用提供最佳/最干净的设计。如果您需要将数据直接附加到标记,那么单独的表(即更规范化的解决方案)将是正确的。
我会警告不要过多地担心2个提议的解决方案中的性能差异,如果编入索引,差异可能是微不足道的(两者都是相当常见的用例,并且可以使用标准数据库技术轻松优化)。在基于性能的两个呈现选项之间做出决定听起来像是过早的优化。
答案 1 :(得分:1)
选项2进行了一些修改。假设您将输入限制为标记表中包含的值,那么您可以为不同目的执行两个不同的查询。
第一个查询将为您提供所有当前USED标记的唯一列表。
第二个查询将为您提供可以使用的所有可能标记,包括尚未使用的标记。
最好使用标记ID并在标记和article_tags表之间建立关系。这将使选项2更有效,因为索引只是一个整数而不是一个字符串。
答案 2 :(得分:1)
我会选择
Article
-------
ArticleID int PK
Article_Tags
------------
ArticleTagID int PK
ArticleID int FK
TagId int FK
Tag
---
TagId int identity(1,1) PK
TagText varchar(50)
没有理由从此开始对此进行反规范化。 (您的第一个和第二个版本未规范化)
在单独的表中使用标记很好,并且获取唯一标记更清晰,没有那个明确的语句。
如果应用了正确的索引,如果3个选项中的任何一个将执行几乎相同的性能。
答案 3 :(得分:1)
要回答标题中的基本问题:DISTINCT
通常意味着对数据进行排序。根据索引,查询的结构和返回的数据量可能是免费的(tagtext上的正确索引,ORDER BY tagtext
,小返回集)或不(缺少索引,顺序无关,大量返回集)。 / p>
答案 4 :(得分:1)
维护两个表的开销不太可能是弄乱简单设计的合理权衡。
如果你真的担心它会很简单地测试它,但根据我的丰富经验,毫无疑问这是真的。