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

我是否错过了标签的最佳实践?


当前回答

我建议设计如下: 项目表: Itemid, taglist1, taglist2 这将是快速和容易的保存和检索数据的项目级别。

并行构建另一个表: 标签 标签 不要让标签唯一的标识符,如果你用完了第二列的空间,其中包含100个项目,创建另一行。

现在,当搜索项目的标签,这将是超级快。

其他回答

我建议设计如下: 项目表: Itemid, taglist1, taglist2 这将是快速和容易的保存和检索数据的项目级别。

并行构建另一个表: 标签 标签 不要让标签唯一的标识符,如果你用完了第二列的空间,其中包含100个项目,创建另一行。

现在,当搜索项目的标签,这将是超级快。

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

如果需要关于所拥有的标记的详细信息,可以在增量维护的表中跟踪它,或者运行批处理作业来提取信息。

一些RDBMS甚至提供了原生数组类型,这种类型可能更适合存储,因为不需要解析步骤,但可能会导致全文搜索出现问题。

三个表(一个用于存储所有项,一个用于存储所有标记,一个用于存储两者之间的关系),在适当的数据库上正确地建立索引,并设置外键,应该能够正常工作并适当地扩展。

Table: Item
Columns: ItemID, Title, Content

Table: Tag
Columns: TagID, Title

Table: ItemTag
Columns: ItemID, TagID

我总是把标签放在一个单独的表中,然后有一个映射表。当然,我也从来没有做过真正大规模的事情。

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

如果您正在使用支持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运行该命令将根据标记名称对结果进行分组,甚至返回遇到该标记的次数的计数。这与计算一个单词在文本中的出现次数非常相似。