2010-09-16 65 views
9

我有3个计划:如何设计StackOverflow问题标签之类的模式?

1,在问表:

question 
------------------------------------ 
id title content ...  tags 
------------------------------------ 
1 aaa  bbb  ...  tag1,tag2,tag3 (use , to split more tags) 

2,在标签表和拆分:

tags 
------------------------------------ 
id tag 
------------------------------------ 
1 tag1,tag2,tag3 (use , to split more tags) 

3,在标签表:

tags 
------------------------------------ 
id tag 
------------------------------------ 
1 tag1 
2 tag2 
3 tag3 

我认为计划3更好,但您的意见是什么?

此实现的其他好主意?

感谢您的帮助:)

+2

请参见[ 你如何推荐实现标记或标记 (http://stackoverflow.com/questions/20856/how-do-you-recommend-implementing-tags-or-tagging)。 – 2010-09-16 23:59:15

回答

12

这些模式被称为mysqlicious,scuttletoxi(从最小到最规范化)。

他们都有他们的好处和缺点。你可以在这里阅读相当不错的分析:

http://forge.mysql.com/wiki/TagSchema (WayBackMachine Version)

注意mysqlicious在很大程度上取决于你的数据库的有效执行FULLTEXT搜索能力。

这意味着对于MySQLInnoDB和其他一些系统,这是非常不切实际的。

1

取决于您希望数据如何规范化。

首先,当我在表格中看到一个不是唯一的“id”列时,我会畏缩。至少将列重命名为“question_id”。

其次,它取决于您是否想快速列出所有已定义的标签。在这种情况下,您需要一个单独的标签表来定义一组可能的标签,然后是一个提供多对多关联的问题和标签之间的中间表。

6

标签和内容之间的关系是many-to-many。这意味着一个标签可以与多个内容单元相关联,而一个内容单元可以与多个标签相关联。

要在数据库中执行此操作,可以使用名为ContentTags的辅助表。 ContentContentTags的关系是一对多关系; TagsContentTags的关系是一对多关系。

#Tags Table 
Id Text 
1 'Tag1' 
2 'Tag2' 
3 'Tag3' 


#Content Table 
Id Content 
1 "some content" 
2 "other content" 
3 "more content" 

#ContenTags Table 
ContentId TagId 
1   1 
1   2 
2   1 
2   2 
2   3 
3   1 

正如你可以看到,这种关系被清楚地反映(内容1与标签1和2相关联;内容2与标签1,2相关联,和3;内容3仅与标签1相关联)

1

正确的做法是创建一对多关系,即您有一条评论和多个标签。来自WIKI

在数据库技术中,当一个实体与另一个实体中的多个事件相关时,会出现一对多(也称为一对多)关系。例如,一个俱乐部有很多成员。

而数据库设计中的主要概念是Database normalization

所以我会这样做。

comments 
------------------------------------ 
id_comment title content 
------------------------------------ 
12   aaa  bbb 

tags 
------------------------------------ 
id_tag comment_id tag 
------------------------------------ 
1  12   tag1 
2  12   tag2 
3  12   tag3 
+0

这种设计将在**标签**中拥有大量冗余**,因为许多评论共享相同的标签。例如,我们可以有一百万个标记为“tag1”的评论。顺便说一句,如果我接受冗余,那么我会看到另一个问题:将** id_tag **和** tag **同时放入**标签表**中没有用处。我们只需要标签,**如果此表已经有comment_id **,则不需要id_tag。 – 2016-04-28 12:50:39