我正在网站上实施类似于一个stackoverflow使用的标记系统,我的问题是-存储标记以便对其进行搜索和过滤的最有效方法是什么?
我的想法是这样的:
Table: Items
Columns: Item_ID, Title, Content
Table: Tags
Columns: Title, Item_ID
这太慢了吗?有没有更好的办法?
我正在网站上实施类似于一个stackoverflow使用的标记系统,我的问题是-存储标记以便对其进行搜索和过滤的最有效方法是什么?
我的想法是这样的:
Table: Items
Columns: Item_ID, Title, Content
Table: Tags
Columns: Title, Item_ID
这太慢了吗?有没有更好的办法?
Answers:
一个项目将具有许多标签。一个标签将属于许多项目。对我而言,这意味着您很可能需要一个中介表来克服多对多障碍。
就像是:
表格:项目
列:Item_ID,Item_Title,内容表:标签
列:Tag_ID,Tag_Title表格:Items_Tags
列:Item_ID,Tag_ID
可能是您的Web应用程序疯狂流行,并且需要在未来进行非正规化处理,但为时过早地弄糊涂毫无意义。
您应该阅读Philipp Keller的有关标记数据库模式的博客文章。他尝试了一些并报告了结果,无论是从构造常见查询的难易程度还是在性能方面。标签数,标签项目数和每个项目的标签数都是因素。这些职位是2005年的;从那时起,我不知道有任何更新。
如果您不介意使用一些非标准的东西,则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
全面比较了性能方面的更多选项,以上建议的选项是总体上最好的。
我建议使用中间的第三张表来存储标签<=>项目关联,因为我们在标签和项目之间具有多对多的关系,即一个项目可以与多个标签关联,而一个标签可以与多个项目关联。HTH,阀门。
项目应具有“ ID”字段,标签应具有“ ID”字段(主键,群集)。
然后制作一个ItemID / TagID的中间表,并在上面放置“ Perfect Index ”。