sql - 可扩展数据库标记模式

标签 sql database performance tags scalability

编辑:致构建标记系统的人们。不要读这个。这不是你要找的。当我不知道RDBMS都有自己的优化方法时,我问了这个,只是使用简单的多对多方案。

我有一个拥有数百万个帖子的发布系统。每个帖子都可以有无数个与之关联的标签。

用户可以创建带有注释、创建日期、所有者等的标签。标签本身几乎就像一个帖子,因为人们可以发布关于标签的注释。

每个标签关联都有一个所有者和日期,因此我们可以看到谁在什么时候添加了标签。

我的问题是如何实现它?它必须通过标签快速搜索帖子,或通过帖子标签快速搜索。此外,用户可以通过在字段中输入名称来为帖子添加标签,有点像谷歌搜索栏,它必须为您填写标签名称的其余部分。

目前我有 3 个解决方案,但不确定哪个是最好的,或者是否有更好的方法。

请注意,我没有显示笔记的布局,因为一旦我找到正确的标签解决方案,它就会变得微不足道。

方法一、链表

post中的tagId指向tag_assoc中的一个链表,应用必须遍历链表直到flink=0

post:           id, content, ownerId, date, tagId, notesId
tag_assoc:      id, tagId, ownerId, flink
tag:            id, name, notesId

方法二、反规范化

tags 只是一个 VARCHAR 或 TEXT 字段,包含制表符分隔的 tagId:ownerId 数组。它不能是固定大小。

post:           id, content, ownerId, date, tags, notesId
tag:            id, name, notesId

方法三、毒素

(来自:http://www.pui.ch/phred/archives/2005/04/tags-database-schemas.html, 这里也一样:Recommended SQL database design for tags or tagging )

post:          id, content, ownerId, date, notesId
tag_assoc:     ownerId, tagId, postId
tag:           id, name, notesId

方法 3 提出了一个问题,遍历 tag_assoc 中的每一行需要多快?

方法1和2对于按帖子返回标签应该很快,但是对于按标签的帖子,必须另外制作一个查找表。

我最后需要担心的是按名称优化搜索标签,我还没有解决这个问题。

我在这里做了一个ASCII图:http://pastebin.com/f1c4e0e53

最佳答案

这是我的做法:

posts:          [postId], content, ownerId, date, noteId, noteType='post'
tag_assoc:      [postId, tagName], ownerId, date, noteId, noteType='tagAssoc'
tags:           [tagName], ownerId, date, noteId, noteType='tag'
notes:          [noteId, noteType], ownerId, date, content

方括号中的字段是各自表的主键。

在每个表中定义对 noteType 的约束:poststag_assoctags。例如,这可以防止给定的注释同时应用于 posttag

将标签名称存储为短字符串,而不是整数 id。这样您就可以在 tag_assoc 表中使用覆盖索引 [postId, tagName]。

完成标记是通过 AJAX 调用完成的。如果用户为标签键入“datab”,您的网页会进行 AJAX 调用,并且在服务器端,应用会查询:SELECT tagName FROM tags WHERE tagName LIKE ?||'%'

关于sql - 可扩展数据库标记模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/664283/

相关文章:

c# - 如何将select查询的结果插入到另一个表的列中

sql - Postgres 选择所有列,但按一列分组

sql - 如何监控和记录所有的 SQL 插入命令

php - PHP 和 MySQL 之间无法建立连接

php - 将不同行中的值连接到一列中

JavaPreparedStatement 在 SQL 查询中将小写字符串名称传递给区分大小写的 PostgreSQL 数据库

mysql - 关于数据库设计

performance - AS3 引用单例

python - 检查列表中是否存在子列表的最有效方法,忽略最后一个元素

c - printf 性能 : Better to use "%d" or "%c" for single digit numbers