database - 如何更新多对多链接表中的数据?

标签 database relational-database

为简单起见,我们假设有一个 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 应用程序会将包含与帖子关联的标签 ID 数组的 JSON 提交到服务器,然后服务器将处理代码中的更新请求。

例如,post_id=1 仅与 tag_id=[1,2] 一起提交,因此 tag=3 需要删除为链接表中的关联。

如果帖子或标签被删除,我会设置 ON DELETE CASCADE

  • posts_tags.post_id
  • posts_tags.tag_id

但是,在更新与帖子关联的标签的实例中,更新链接表数据的最佳方式是什么?

选项 1:

  • 获取已编辑帖子的所有帖子标签 SELECT * FROM posts_tags WHERE post_id = 1
  • 确定添加了哪些标签(并将 INSERT 插入到链接表中)
  • 确定哪些标签已被删除(并从链接表中删除)

选项 2:

  • 删除链接表中所有带有post_id的标签
  • 将所有提交的标签插入链接表

选项 3:

  • 我没有考虑的事情:)

随着表的增长,选项 2 是否会对索引产生更大的性能影响?

编辑:

  • 为清楚起见,实际的帖子和标签数据未​​更改或删除。这纯粹是关于更新帖子的相关标签
  • 我使用的数据库是 PostgreSQL 9.6

最佳答案

从性能的角度来看,选项 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)),因此您永远不必删除任何内容 - 您只需插入新行。

在实践中,这可能不会更快,但它确实为您省去了“删除”查询。

关于database - 如何更新多对多链接表中的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46603769/

相关文章:

mysql - 每次在Mysql中运行查询时显示不同的数据

database-design - 为了避免一些复杂的查询而重复数据库中的字段是不好的设计实践吗?

用于可视化数据库表关系的 Java 库

mysql - MongoDB、Mysql 和关系

relational-database - (数据库设计 - 产品属性): What is better option for product attribute database design?

sql - 如何通过 PostgreSQL 更新特定列的特定行以反射(reflect)另一个表中的值?

php - 无法设置日期时间

sql - 数据库:流水线函数

database - EdgeDB 的 35k 行/秒是慢还是快?