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

问题描述 投票:128回答:8

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

我的想法是这样的:

Table: Items
Columns: Item_ID, Title, Content

Table: Tags
Columns: Title, Item_ID

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

database database-design tags tagging
8个回答
178
投票

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

就像是:

表:项目 列:Item_ID,Item_Title,Content

表:标签 列:Tag_ID,Tag_Title

表:Items_Tags 列:Item_ID,Tag_ID

可能是你的网络应用程序非常受欢迎,并且需要在路上进行非规范化,但是过早地混淆水域是没有意义的。


104
投票

您应该阅读Philipp Keller关于标记数据库模式的博客文章。他尝试了一些并报告了他在terms of ease of constructing common queriesin terms of performance的结果。标签数量,标记项目数量和每个项目的标签数量都是因素。这些职位来自2005年;从那时起我就不知道有任何更新。


7
投票

实际上我认为对标签表进行去标准化可能是更好的前进方式,具体取决于规模。

这样,tags表只有tagid,itemid,tagname。

您将获得重复的标记名,但它使得为特定项添加/删除/编辑标记更加简单。您不必创建新标记,删除旧标记的分配并重新分配新标记,只需编辑标记名即可。

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


3
投票

如果您不介意使用一些非标准的东西,Postgres版本9.4及更高版本可以选择存储JSON文本数组类型的记录。

您的架构将是:

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

对性能进行了彻底的比较,并且上面提出的选项总体上是最好的。


2
投票

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


1
投票

根据您在问题中提供的数据,您无法真正谈论缓慢。而且我认为你甚至不应该在这个发展阶段过分担心表现。它被称为premature optimization

但是,我建议你在Tags表中包含Tag_ID列。通常一个好的做法是每个表都有一个ID列。


1
投票

如果空间成为问题,请使用第3个表格标记(Tag_Id,标题)来存储标记的文本,然后将标记表更改为(Tag_Id,Item_Id)。这两个值也应该提供唯一的复合主键。


0
投票

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

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

© www.soinside.com 2019 - 2024. All rights reserved.