我正在构建一个系统来存储文章和对文章进行分类的标签。标准的东西,类似于这个网站的做法。现在我的问题是我是否应该将标签存储在仅包含标签和文章 id 的单独表中,或者将标签存储在文章表中的额外列上。我的第一反应是标准化数据库并拥有两个表。问题在于用户管理标签的界面是一个简单的文本框,所有标签均以逗号分隔。因此,当用户提交更改时,为了找出添加、更改或删除了哪些标签,我需要首先查询数据库,将结果与标签基础上的新数据进行比较,然后相应地处理更改。一个开销巨大的过程,与简单地更新文章表的一行中提交的文章相比。你会怎么做,或者还有我没有考虑过的第三种选择吗?

PD。我在这个项目中坚持使用关系数据库。


如果您使用单独的表,则无需尝试找出每次更改的标签,只需删除给定文章 ID 的所有标签,然后插入所有提供的标签 - 这应该会产生很少的开销。

在标记系统中,通常最重要的性能是标记的检索和/或相关内容的检索。在项目可以具有任意数量的标签的情况下,使用带有索引标签列的单独表应该可以提供非常快速的查找。


您需要规范化数据库才能运行“查找带有标签 T 的所有文章”等查询。

假设您应用了正确的索引,我认为抓取所有标签将它们与新标签进行比较确实不会有那么多开销。

就我个人而言,我不会删除所有标签然后插入所有新标签,因为我可能想要在输入单个标签时执行诸如审核之类的操作。

如果您使用的是 SQL Server 2008,那么我建议您查看 MERGE 命令。


仅当标签始终以相同顺序输入时,简单字符串比较才有效。无论怎样,您都必须逐个标签进行比较。

我可以使用 LIKE 语句。

但这将是一种可怕且低效的黑客行为。

我考虑过,但我没有办法保证操作的原子性,如果删除标签后出现问题,我会留下一篇未分类的文章。此外,我可能想跟踪哪些标签是新的,哪些已删除。

这仍然不会带来太大的开销,而且事实上,如果使用单独的表而不是在单个列中进行字符串比较,应该更容易计算出来。关键是优化信息检索,因为它将是最常见的用法 - 即使在插入/更新时会产生额外的开销

我使用的是 SQL Server Compact,因此没有 MERGE 命令。至少我找不到。

我想你必须为每种情况编写单独的插入、更新和删除语句。请注意,如果将它们包装在事务中,那么您将获得原子性。