更新标签列表 - 或更新has_many关系


Update tags lists - or updating has_many relationships

我经常遇到更新的问题有很多关系。例如,让我们取以下三个表:

  • 职位
  • 标签
  • posts_tags

当用户创建新帖子时,他可以向帖子添加标签。 帖子将被保存,所选标签将通过_posts_tags_附加到该帖子。

当用户编辑帖子

(也可以或不编辑标签列表(并且表单提交时,我必须更新帖子的标签列表。

解决方案可以是以下:更新帖子时,我从_posts_tags_中删除该帖子的所有标签,并插入提交的标签。

另一种解决方案是从数据库中获取帖子的所有标签,将列表与提交的列表进行比较,并决定我们必须删除的内容以及必须插入的内容。

这两种解决方案都可能非常耗时。
什么是更聪明的问题解决方案?

当帖子被编辑并且标签未被编辑(可选(时,只需保存帖子而不执行任何操作。为什么?因为在帖子、标签和posts_tags表中,您有一个自动增量列,它是您的主键。然后,此数字列是相应表中的外键,即表将如下所示:

帖子: id_post(PK(, post_title, post_content

标签: id_tag(PK(, tag_name

posts_tags: id_post_tag(PK(, id_post(FK(, id_tag(FK(

PK:主键FK:外键

以这种格式保存数据后,您将发现无需更新任何依赖表,因为文本数据不再用于维护数据库架构和关系。这也加快了事务时间,因为数据库不像 Bono 所暗示的那样在任何级联作业中都处于繁忙状态。

然后对帖子中的所有标签运行一个简单的循环,以对照post_tags表中的id_post检查它们是否存在,如果未找到,则插入它。在执行此循环时,构建一个字符串,您将在下面使用:

接下来,运行以下查询:

delete from post_tags where id_post = {$id_post} and id_tag not in {$list_id_tags}

此操作通过最小化由添加和删除行导致的 IO 操作来最大程度地减少数据库服务器过载。删除所有post_tags然后再次插入所有标签的情况会产生较大的 IO,而此方法可以最大程度地减少这种情况。