为了简单起见,我们假设有一个Post表和一个Tags表(不是实际的用例,但这样可以保持简单)
帖子表
id | title
--------------------------------
1 | Random Text Here
2 | Another Post About Stuff
标签表
id | tag
--------------------------------
1 | javascript
2 | node
3 | unrelated-thing
posts_tags表
id| post_id | tag_id
--------------------------------
1 | 1 | 1
2 | 1 | 2
3 | 1 | 3
4 | 2 | 2
帖子可以包含许多标签,单个标签可以与许多帖子相关联。
Web应用程序假设让我们假装添加/删除标记不会在Web应用程序中针对链接表触发单个异步操作。 相反,用户将编辑帖子(添加或删除已创建的任何标签),然后点击保存。 Web应用程序将向服务器提交包含与Post关联的标签ID数组的JSON,然后服务器将处理代码中的更新请求。
例如,post_id=1
仅提交tag_id=[1,2]
,因此tag=3
需要作为关联表中的关联被删除。
如果删除帖子或标签,我将设置ON DELETE CASCADE
但是在更新与帖子关联的标签的实例中,更新链接表数据的最佳方法是什么?
选项1:
SELECT * FROM posts_tags WHERE post_id = 1
选项2:
选项3:
随着表的增长,选项2会对索引产生更大的性能影响吗?
编辑:
答案 0 :(得分:1)
从性能的角度来看,选项2会很好 - 比选项1好多了,因为你只有一个操作来删除旧的关联,然后是一堆插入语句。在选项1中,您有更多查询(您的第一个查询检索关联,然后删除,如果适用)。
只要你的表在post_id上有一个索引,那么即使在一张巨大的桌子上,delete * from posts_tags where post_id = ?
也会闪电般快速。
有另一种选择......
posts_tags表
id| post_id | tag_id | version_id
--------------------------------
1 | 1 | 1 | 0
2 | 1 | 2 | 0
3 | 1 | 3 | 1
4 | 2 | 2 | 0
5 | 1 | 1 | 2
6 | 1 | 3 | 2
在这种情况下,您使用版本控制机制来确定“当前”关联(max(version_id)),因此您永远不必删除任何内容 - 只需插入新行。
在实践中,这可能不会更快,但它确实可以为您节省“删除”查询。