什么是在数据库中存储标签的最有效的方法?

我在我的网站上实现了一个类似于一个stackoverflow使用的标记系统,我的问题是 – 什么是最有效的方法来存储标记,以便他们可以被search和过滤?

我的想法是这样的:

Table: Items Columns: Item_ID, Title, Content Table: Tags Columns: Title, Item_ID 

这太慢了吗? 有没有更好的办法?

一个项目将有很多标签。 一个标签将属于许多项目。 这对我意味着你很可能需要一张中间桌来克服多对多的障碍。

就像是:

表:项目
列:Item_ID,Item_Title,内容

表:标签
列:Tag_ID,Tag_Title

表:Items_Tags
列:Item_ID,Tag_ID

这可能是因为你的networking应用程序非常stream行,需要在路上进行非规范化处理,但是这个时间太早,毫无意义。

您应该阅读Philipp Keller关于标记数据库模式的博客文章。 他尝试了几个,并在结构上提出了一些结果,无论是在构build常见查询方面 ,还是在性能方面 。 标签的数量,加标签的项目的数量和每个项目的标签的数量都是因素。 这些职位是从2005年起; 从那以后,我不知道有任何更新。

事实上,我认为标签表的标准化可能是一个更好的方法,这取决于规模。

这样,标签表只需要tagid,itemid,tagname。

你会得到重复的标记名,但是它使得添加/删除/编辑特定项目的标记更加简单。 您不必创build新标签,删除旧标签的分配并重新分配新标签,只需编辑标签名即可。

要显示标签列表,只需使用DISTINCT或GROUP BY,当然,您也可以计算标签的使用次数。

我build议使用中间第三表来存储标签<=>项目关联,因为我们有标签和项目之间的多对多关系,即一个项目可以与多个标签相关联,一个标签可以与多个项目相关联。 HTH,阀门。

如果空间将是一个问题,有一个第三个表标签(Tag_Id,标题)来存储标签的文本,然后改变你的标签表(Tag_Id,Item_Id)。 这两个值也应该提供一个独特的复合主键。

如果你不介意使用一些非标准的东西,Postgres 9.4及以上版本可以select存储一个JSONtypes的文本数组。

你的模式将是:

 Table: Items Columns: Item_ID:int, Title:text, Content:text Table: Tags Columns: Item_ID:int, Tag_Title:text[] 

欲了解更多信息,请参阅Josh Berkus的优秀博文: http ://www.databasesoup.com/2015/01/tag-all-things.html

对于性能来说,有更多的select进行比较,上面提到的是最好的总体。

根据您在问题中提供的数据,您无法真正谈论缓慢。 在这个发展阶段,我不认为你应该担心过多的performance。 这叫做过早优化 。

不过,我build议你在标签表中包含Tag_ID列。 每个表都有一个ID列通常是一个好习惯。

项目应该有一个“ID”字段,标签应该有一个“ID”字段(主键,集群)。

然后制作一个ItemID / TagID中间表,并在那里放上“ Perfect Index ”。