我们将postgres for rbac权限模型与组一起使用,并尝试考虑所需的最佳索引,假设我们的数据库具有以下模式:
主题表
id, external_type, external_id, group_id
资源表
id, group_id, external_type, external_id, role_id
两张表都是用来回答一个问题的:
主题[s]能否对资源[r]执行操作[a]
因此,我们需要从用户参与的所有权限组中检索用户在资源上的所有角色。
在subjects表中,一个subject可以有k行,他所在的每个组对应一行。
一个资源在资源表中可以有m行,为该资源分配角色的每个组一行。
我们选择对一个表中的资源、组和角色进行非规范化,以获得读优化的性能。
我们选择不去规范化同一个表中的主题,以避免每次组结构更改时更新许多记录。
两个k&m都可以非常大—一个用户可以在多个组中,而一个资源可以属于多个组。
因此,查询将是:
SELECT role_id
FROM resources
INNER JOIN subjects
ON resources.group_id=subjects.group_id
WHERE subjects.external_type="user" AND subjects.external_id=123
AND resources.external_type="order" AND resources.external_id=456
我们决定定义以下指标:
Subjects: <external_type, external_id>, <group_id>
Resources: <external_type, external_id>, <group_id>
有人能解释一下内心是如何与 where
子句与2个表和索引有关?它们是并行执行的,然后由 ON
语句或只有一个表的索引将用于 where
然后使用 ON
联系?
我们应该使用不同的复合索引吗?添加 group_id
对复合索引有什么影响?
对类似用例的任何引用或为复杂的应用程序选择索引 JOIN
询问会有帮助。
1条答案
按热度按时间0yycz8jy1#
这可以通过多种方式实现。它可以独立地读取索引和表,然后将它们散列连接或合并连接在一起。或者它可以忽略一个或两个索引,如果它认为这样会更快的话(因为索引将返回很大一部分的行),则对表执行seq扫描。或者它可以做一个嵌套循环,使用where子句中的常量加上on子句中不断变化的组id来形成一个三元组,它将在其中一个表(内部表)的三列索引中查找这个三元组。外部表也可以由其索引驱动(仅使用前两列,这两列在查询期间是常量)或使用顺序扫描。
如果你想知道正在使用什么计划,做一个
EXPLAIN
或者更好EXPLAIN (ANALYZE, BUFFERS)
查询的名称。