2009-09-26 79 views
7

我想要更详细地说明在数据库中存储标签的toxi方法 - 在SO的其他地方提到过。在数据库中存储标签。存储标签一次或多次?

数据库模式是:

Table: Item 
Columns: ItemID, Title, Content 

Table: Tag 
Columns: TagID, Title 

Table: ItemTag 
Columns: ItemID, TagID 

这可能是一个愚蠢的问题(但我不知道答案)...如果每个条目,在表标签,有一个独特的称号。即我每次只使用一次标签或存储它?

为了说明,这两个表的下面我应该结束了:

TagID  Title 
1   Fish 
2   Cat 
3   Dog 

TagID  Title 
1   Fish 
2   Fish 
3   Cat 
4   Fish 
5   Dog 
6   Cat 

如果使用第一个表,输入标签之前,我必须先运行和sql语句来找出它是否存在,是否正确?

任何帮助将不胜感激。由于黑客攻击和索引,最近我的手指被烧伤,想要开始正确的基础知识。

+0

在您的第二个解决方案中,您并不需要标记表,只需将标记保存在您的ItemTag表中而不是TagID中即可。 虽然我会使用第一个解决方案。 – Vertigo 2009-09-26 10:36:32

回答

4

基本的是,你需要存储标签,就像你在第一种情况下显示的一样。检查标签是否存在是很好的(因为在第二种情况下,现有标签会返回与标签外观一样多的行),并且适用于通过标签检索项目(通过一个标签ID选择项目ID比选择项目更好由具有相同表示意义的一组tag_id来标识)。

如果您因为索引而烧坏了手指 - 您应该始终检查查询是如何执行的(对于mysql,它是EXPLAIN/DESCRIBE SELECT)。

2

如果“Fish”和“Fish”是相同的标签,你应该在你的Tag表有它只有一次。

因此,我会用你的第一个解决方案 - 这实际上意味着在你的insert之前做一个select,以确定标签是否已经存在;并且如果存在,则使用其现有的TagID作为该项目与标签之间的链接,在ItemTag表中。

实际上,这就是ItemTag存在的原因:它是一个关联表,它存储项目和标签之间的对应关系:对于每个项目,可以有多个标签,并且对于每个标签,可以有多个项目。

这也可以让事情变得更容易获得附加到特定标签的项目列表。

1

您应该在标签表中只有一次标签; ItemTag表的整个要点是为您提供n:m关联(每个项目具有多个标签,并且每个标签都属于多个项目)。

如果您要重复标记标题,可以通过使标记表立即使用ItemID而不是标记ID来简化结构。

+0

-1:重复标签并使用标签表使用item_ids将使搜索真正资源昂贵,因为搜索将通过比较字符串而不是整数,这是比较慢的。 – Eimantas 2009-09-26 10:37:08

+0

@Eimantas:我不建议重复标签。我只是说* if *标签要重复,你可以放下一张桌子。 – 2009-09-26 10:52:00