几千万的数据量,层级权限下的列表展示页查询应该怎么设计?

查看 44|回复 5
作者:lying500   
各位大佬,想请教一下这个关于查询用户拥有权限的数据的问题,感觉这个挺常见的需求
业务场景:
假设一个业务表,数据量在几千万级。
需要为这个表提供一个列表展示页,要求按创建时间倒序分页。
主要是权限问题导致查询慢:
1 、用户可以查看自己创建的数据。
2 、用户可以查看自己所属群组的数据。
3 、群组的权限是可继承的、层级的:如果一个用户属于某个上级群组,那么他自动拥有查看其所有下级、下下级...群组内数据的权限。
问题:
如果权限简单,比如只看自己的数据,查询非常简单:
WHERE user_id = ? ORDER BY create_time DESC LIMIT N
这种查询用索引就好解决。
但如果加入群组权限,查询的逻辑就变成了:
SELECT * FROM a_large_table WHERE user_id = ? OR group_id IN (用户所属群组以及所有下级群组的 ID 列表) ORDER BY create_time DESC LIMIT N
这个查询就比较慢了
比如假定结构是这样:

查询就变成了
SELECT *
FROM project
         JOIN `group` ON project.group_id = `group`.id
WHERE `group`.id IN (SELECT 用户关联的群组及其子群组 id)
   OR user_id = 20
ORDER BY project.created_at DESC
LIMIT 10;
这时候 (group_id, user_id, created_at) 也不好使;
问了 AI ,说了几个方案:
1 、应用层聚合/union user_id 和 group_id 的,建两个索引;
2 、冗余一张 用户能访问数据的表,直接查这个表;
3 、引入 es 之类的中间件;
想问一下实际大家是怎么处理的?

权限, 查询, 性能

evan1   
给群组加个层级 ID 字段,把群组的层级 ID 拼起来。
查的时候 like 一下层级 ID 。
lying500
OP
  
主要是 project 表的 or 导致索引不好设计,实际没法利用索引

kxg3030   
使用 nestedset 做无限分类或者像 1L 那样 加个 path 字段  like 一下 但是最好还是我说的那个方案  一开始就要那么设计才行
chanlk   
一个不成熟的想法,如果最顶层的 group 不多,那么按照每个顶层 group 对应一个 project 表进行分表。
JYii   
@lying500 #2 只是 or 的原因吗,那大可以拆成两个在 union all 。我猜还是 in 的参数太多导致的。
您需要登录后才可以回帖 登录 | 立即注册

返回顶部