使用Symfony';使用JOIN查询还是IN数组查询更好


When using Symfony's ACL, is it better to use a JOIN query or an IN array query?

这个问题建立在"如何使用Symfony ACL 过滤我的条令查询"的讨论之上

  • 存在类别/实体,例如产品
  • 它被映射到数据库表
  • 每一行代表一个对象(一个产品)
  • 我们使用ACL来允许/限制对产品的访问

考虑到这一点,我们如何查询以获得用户可以访问的所有产品的列表

浏览每个产品,并检查用户是否可以访问是毫无疑问的。。。这种情况很快就会恶化。

在前面的讨论中,我们讨论了In数组或JOIN查询。

IN阵列方法获取用户可以访问的产品ID列表(从acl_entries table),然后对products table执行IN阵列查询。

加入方法加入acl_entries tableproducts 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!