在项目开发中,经常要现实这样的一个功能——关系表更新。比如,一个用户可以设置多个标签,而一个标签下又可以有多个用户,两者是多对多的关系,用一张关系表记录用户的标签数据,那么,当更新用户标签的时候,怎样安排执行流程,才是最优的呢?
数据关系
假设数据库中有三张表,user,tag,user_tag:
假设数据库中有三张表,
user:
id | name |
---|---|
1 | user1 |
2 | user2 |
3 | user3 |
… | … |
tag:
id | title |
---|---|
1 | tag1 |
2 | tag2 |
3 | tag3 |
… | … |
user_tag:
| id | user_id | tag_id | deleted_at|
| — | — | — | — | — |
| 1 | 1 | 1 | null |
| 2 | 2 | 1 | null |
| 3 | 3 | 1 | null |
| … | … | … | null |
user_tag表记录了user表和tag表之间的关系,并且user_tag表内使用软删除。
问题描述
如果用户user1的标签为tag1、tag2和tag3,现在想更新为tag2、tag4和tag6,那么应该怎样操做?
解决方案
最暴力的解决办法就是delete
旧数据,然后insert
新数据。但是项目中,为了安全,一般会禁用硬删除,而使用软删除。如果用软删除结合insert
,关系表就会越来越大。
比较常用的解决方案是:实时更新和差集更新。
实时更新
当给用户添加一个标签时,后台立刻更新;当给用户移除一个标签时,后台也立刻更新,这样的做法,
实现起来很简单,(伪)代码如下:
1 |
|
差集更新
如果使用实时更新,那么每次操作都要向后台发送请求,这样的请求一般都是小而多,倒不如使用批量更新。比较一下新数据和就数据,针对差集进行更新,(伪)代码如下:
1 |
|
最后
最后说两句,多点关注array_intersect
、array_diff
等等PHP数组函数的使用。