我听说过几种实施标记的方法; 使用TagID和ItemID之间的映射表(对我来说有意义,但是可以缩放吗?),向ItemID添加固定数量的可能的TagID列(似乎是个坏主意),将标签保留在逗号分隔的文本列中(声音疯狂但可以工作)。 我什至听说有人建议使用稀疏矩阵,但是标签名称又如何优雅地增长呢?

我是否错过了标签的最佳做法?

===============>>#1 票数:389 已采纳

三个表(一个用于存储所有项目,一个用于所有标签,一个用于两者之间的关系)已正确索引,并且在适当的数据库上运行了外键,这些表应该可以正常工作并可以适当扩展。

Table: Item
Columns: ItemID, Title, Content

Table: Tag
Columns: TagID, Title

Table: ItemTag
Columns: ItemID, TagID

===============>>#2 票数:78

通常,我会同意Yaakov Ellis的观点,但是在这种特殊情况下,还有另一个可行的解决方案:

使用两个表:

Table: Item
Columns: ItemID, Title, Content
Indexes: ItemID

Table: Tag
Columns: ItemID, Title
Indexes: ItemId, Title

这具有一些主要优点:

首先,它使开发变得更加简单:在用于插入和更新item的三表解决方案中,您必须查找Tag表以查看是否已经有条目。 然后,您必须与新成员一起加入。 这不是小事。

然后,它使查询更简单(也许更快)。 您将执行三种主要的数据库查询:输出一个Item所有Tags ,绘制一个标签云,然后为一个标签标题选择所有项目。

一个项目的所有标签:

3桌:

SELECT Tag.Title 
  FROM Tag 
  JOIN ItemTag ON Tag.TagID = ItemTag.TagID
 WHERE ItemTag.ItemID = :id

2表:

SELECT Tag.Title
FROM Tag
WHERE Tag.ItemID = :id

标签云:

3桌:

SELECT Tag.Title, count(*)
  FROM Tag
  JOIN ItemTag ON Tag.TagID = ItemTag.TagID
 GROUP BY Tag.Title

2表:

SELECT Tag.Title, count(*)
  FROM Tag
 GROUP BY Tag.Title

一个标签的项目:

3桌:

SELECT Item.*
  FROM Item
  JOIN ItemTag ON Item.ItemID = ItemTag.ItemID
  JOIN Tag ON ItemTag.TagID = Tag.TagID
 WHERE Tag.Title = :title

2表:

SELECT Item.*
  FROM Item
  JOIN Tag ON Item.ItemID = Tag.ItemID
 WHERE Tag.Title = :title

但是也有一些缺点:它可能会占用数据库中更多的空间(这可能会导致更多的磁盘操作,速度变慢),并且未规范化这可能会导致不一致。

size参数不是很强,因为标签的本质是标签通常很小,因此尺寸增加不是很大。 有人可能会说,在一个只包含每个标签一次的小表中,对标签标题的查询要快得多,这当然是正确的。 但是考虑到不必加入而节省下来的钱,以及可以在它们上建立良好索引的事实,很容易就能弥补这一点。 当然,这在很大程度上取决于您所使用的数据库的大小。

不一致的论点也有一点争议。 标签是自由文本字段,没有预期的操作,例如“将所有标签“ foo”重命名为“ bar””。

tldr:我会寻求两张桌子的解决方案。 (实际上,我要去。我找到了这篇文章,以查看是否有反对它的有效论点。)

===============>>#3 票数:37

如果您使用的是支持map-reduce的数据库(例如,couchdb),则将标签存储在纯文本字段或列表字段中确实是最好的方法。 例:

tagcloud: {
  map: function(doc){ 
    for(tag in doc.tags){ 
      emit(doc.tags[tag],1) 
    }
  }
  reduce: function(keys,values){
    return values.length
  }
}

使用group = true运行此命令将按标签名称对结果进行分组,甚至返回遇到该标签的次数的计数。 这与计算文本中单词的出现非常相似。

===============>>#4 票数:12

使用单个格式化的文本列[1]来存储标签,并使用功能强大的全文本搜索引擎对此进行索引。 否则,在尝试实现布尔查询时,您将遇到扩展问题。

如果需要有关标签的详细信息,则可以在增量维护的表中跟踪它,也可以运行批处理作业以提取信息。

[1]一些RDBMS甚至提供了本机数组类型,由于不需要解析步骤,它甚至可能更适合存储,但是可能会导致全文搜索出现问题。

===============>>#5 票数:9

我一直将标签放在单独的表中,然后有一个映射表。 当然,我也从来没有做过任何大规模的事情。

拥有一个“标签”表和一个映射表使得生成标签云变得相当简单,因为您可以轻松地将SQL组合在一起以获取一个标签列表,其中包含每个标签使用频率的计数。

===============>>#6 票数:0

我建议以下设计:项目表:Itemid,taglist1,taglist2
这样很快,并且可以轻松地在项目级别保存和检索数据。

并行构建另一个表:标签标记不会使标签成为唯一标识符,如果第二列中的空间用完,则假设有100个项目会创建另一行。

现在,在搜索标签商品时,它将会非常快。

  ask by dlamblin translate from so

未解决问题?本站智能推荐:

12回复

标记数据库设计

您将如何设计数据库以支持以下标记功能: 项目可以包含大量标签 搜索标记有给定标记集的所有项目必须快速(项目必须包含所有标记,因此它是AND搜索,而不是OR搜索) 创建/写入项目可能较慢以启用快速查找/读取 理想情况下,使用单个SQL语句查找使用(至少)一组n个给
2回复

在数据库中存储标签的最佳方法?

我有一个包含两个表的数据库: 项 标签 条目表包含每个都有一个或多个标签的帖子。 问题是,每个帖子可以有任意数量的标签。 换句话说,我不能拥有'tag1','tag2'等列并执行LEFT JOIN。 我应该如何设置条目,以便每个帖子可以有任意数量的标签?
3回复

用于标记多个源的数据库设计(MySQL)

我正在开发一个项目,我有以下(编辑过的)表结构:(MySQL) 我们的想法是,标签可以应用于任何博客或剧集(以及其他类型的源),如果用户已经不存在标签表,则可以创建新标签。 标签的目的是用户将能够搜索网站,结果将搜索网站上的所有类型的材料。 此外,在每篇博客文章/剧集描述的底部,
1回复

分组标记的数据库实现

我需要实现这样的标记系统:- 每个用户都可以根据其受过教育而被标记。 (标签为:小学,中学,高中),这些标签属于“教育”范畴。类似地,用户也可以根据自己的兴趣进行标签(板球,足球,摇滚音乐,流行音乐...)板球和足球属于“体育”类别,摇滚音乐和流行音乐属于“音乐”类别。 当前设计是
1回复

在数据库架构中用三列标记同义词

假设您具有与此处所述相同的数据模型。 如果要像在stackoverflow上一样具有类似的标记同义词,则将这些信息放置在数据模型中的什么位置? 您将只添加一个带有逗号分隔的同义词列表的属性,还是将数据模型进行一些转换? 用于插入新项目的SQL语句看起来如何? 新项目将与所有同义
2回复

如何使用php和mysql创建标记系统?

想知道我如何在php和mysql数据库中创建标记系统,我最初的想法是在表格中创建一个存储文章的行,命名标签,并列出用逗号分隔的标签,但我不知道如何我可以创建一个搜索匹配标签的查询,我不想每次有人点击标签时查询每篇文章。 有人可以帮忙吗?
3回复

如何构建像stackoverflow这样的标记系统

我正在实现类似于StackOverflow标签系统的标签系统,但我只是想知道如何获取相关标签并定义标签之间的关系权重,如任何标签页中的“相关标签”列表,如https://stackoverflow.com / questions / tagged / php它们通过2个或更多标签之间的共现来定义
8回复

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

我在我的网站上实现了一个类似于stackoverflow使用的标记系统,我的问题是 - 什么是存储标记的最有效方法,以便可以搜索和过滤它们? 我的想法是这样的: 这太慢了吗? 有没有更好的办法?
2回复

分布式内容类型的多租户标记架构

关于标记架构的讨论很多,但我注意到它大部分都集中在单个内容类型上,例如书签或照片。 我对跨多租户业务应用程序的多个功能使用标签感兴趣; 一种可以将标签与表单字段,文档,照片,配置设置等相关的标签。 我想设计一组较小的表来满足这些不同的需求,而不是为每种内容类型添加链接表,这会增加一
1回复

标签或标签的数据库设计

存储在数据库中的项目标签如何无忧无虑? 每个项目都有多个标签。 我已经以有效的方式阅读了几个答案: 在数据库中存储标签的最有效方法是什么? 推荐用于标记或标记的SQL数据库设计 但我认为有一个更好的解决方案。 为什么我们不能简单地将标签包含为每个项目的长字符串