这个问题建立在"如何使用Symfony ACL 过滤我的条令查询"的讨论之上
- 存在类别/实体,例如产品
- 它被映射到数据库表
- 每一行代表一个对象(一个产品)
- 我们使用ACL来允许/限制对产品的访问
考虑到这一点,我们如何查询以获得用户可以访问的所有产品的列表
浏览每个产品,并检查用户是否可以访问是毫无疑问的。。。这种情况很快就会恶化。
在前面的讨论中,我们讨论了In数组或JOIN查询。
IN阵列方法获取用户可以访问的产品ID列表(从acl_entries table
),然后对products table
执行IN阵列查询。
加入方法加入acl_entries table
和products table
。
(注意,在这两种情况下都没有使用parent_acl)
让我们看看这两种情况的时间复杂性:
IN ARRAY APPROACH:M rows
的实体表,带有size N
的ACL条目数组(ACL表中的行与此处无关)
时间复杂性:O[N*log(M)]
加入方法:M rows
的实体表,带有N rows
的ACL表
时间复杂性:O[M+N]
在实践中,我们通常会遇到这样的情况:
阵列
N=10,000
M=1,000,000
O=>60,000
加入
N=10,000
M=1,000,000
O=>1,010,000
理论上,阵列中最坏的情况是
阵列
N=1,000,000,000
M=1,000,000,000
O=>9,000,000,000
加入
N=1,000,000,000
M=1,000,000,000
O=>2,000,000,000
这意味着什么?摘要/TL;DR
如果每个用户只被授予访问实体中一小部分对象的权限,请使用in数组。
如果每个用户都有一个实体的每个对象的ACL条目,请使用JOIN。虽然增益不会是几个数量级(除非你有数万亿的产品),所以你可能仍然想使用IN阵列。
在这两种情况下,只有在绝对必要时才使用ACL!选民FTW!