build议SQL数据库devise标签或标签

我听说过几种实现标签的方法, 使用TagID和ItemID之间的映射表(对我来说是有意义的,但它是否缩放?),将固定数量的TagID列添加到ItemID(看起来像一个坏主意),将标签保留在逗号分隔的文本列中疯狂,但可以工作)。 我甚至听到有人推荐一个稀疏matrix,但那么标签名称如何优雅地生长呢?

我是否缺less标签的最佳做法?

三个表(一个用于存储所有的项目,一个用于所有的标签,一个用于两者之间的关系),正确的索引,外键设置在一个合适的数据库上运行,应该能正常工作和适当扩展。

Table: Item Columns: ItemID, Title, Content Table: Tag Columns: TagID, Title Table: ItemTag Columns: ItemID, TagID 

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

使用两个表格:

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

这有一些主要的优点:

首先它使开发变得更简单:在用于插入和更新item的三表解决scheme中,您必须查找Tag表以查看是否已经有条目。 那么你必须join新的。 这不是一件小事。

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

所有标签为一个项目:

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 

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

尺寸参数并不那么强大,因为标签的本质是它们通常非常小,所以尺寸的增加并不是很大。 有人可能会争辩说,标签标题的查询在一个只包含一次标签的小表中会快得多,这当然是对的。 但考虑到不必join的储蓄,以及你可以build立一个良好的指数,可以很容易地弥补这一点。 这当然很大程度上取决于您使用的数据库的大小。

不一致的论点也是有点不切实际的。 标签是自由文本字段,没有像“重命名所有标签”foo“到”bar“”的预期操作。

所以tldr:我会select双表解决scheme。 (实际上我会去的,我发现这篇文章看看是否有有效的论据。)

如果您使用的是支持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运行这个命令将会按照标签名称对结果进行分组,甚至可以返回遇到标签的次数。 这与计算文字中出现的单词非常相似。

使用一个格式化的文本列[1]来存储标签,并使用一个function强大的全文search引擎来编制索引。 否则当尝试实现布尔查询时会遇到扩展问题。

如果您需要有关您所拥有的标签的详细信息,可以使用增量维护表来跟踪它,也可以运行批量作业来提取信息。

[1]有些RDBMS甚至提供了一种本地数组types,它可能更适合于不需要parsing步骤的存储,但可能会导致全文search出现问题。

我一直把标签保存在一个单独的表中,然后有一个映射表。 当然,我从来没有做过大规模的事情。

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

我会build议以下devise:项目表:Itemid,taglist1,taglist2
这将是快速的,并容易保存和检索项目级别的数据。

在并行build立另一个表:标签标签不使标签唯一标识符,如果你用尽了第二列空间用尽可以说100个项目创build另一行。

现在,当search一个标签的项目时,它会超快。