使用Symfony的ACL时,使用JOIN查询或IN数组查询会更好吗?

时间:2016-07-17 22:36:40

标签: php mysql symfony

此问题建立在How to filter my Doctrine queries with Symfony ACL

的讨论基础之上
  • 有一个类/实体,例如产品
  • 它映射到数据库表
  • 每行代表一个对象(产品)
  • 我们使用ACL来允许/限制对产品的访问

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

浏览每个产品,并检查用户是否有权访问是不可能的......这很快就会变坏。

在前面的讨论中,我们使用IN数组或JOIN查询进行操作。

在ARRAY APPROACH中获取用户有权访问的产品ID列表(来自acl_entries table),然后对products table进行IN数组查询。< / p>

加入方法使用acl_entries table加入products table

(注意,在两种情况下都没有使用parent_acls)

1 个答案:

答案 0 :(得分:2)

让我们看看两种情况的时间复杂性:

在ARRAY APPROACH中M rows的实体表,其中ACL条目数组为size N(ACL表中的行与此处不相关)

时间复杂度:O [N * log(M)]

加入方法M rows的实体表,ACL表格为N rows

时间复杂度:O [M + N]

在实践中,我们通常会遇到类似的情况,

IN ARRAY

N=10,000
M=1,000,000
O=>60,000

<强> JOIN

N=10,000
M=1,000,000
O=>1,010,000

理论上,数组中最糟糕的情况是

IN ARRAY

N=1,000,000,000
M=1,000,000,000
O=>9,000,000,000

<强> JOIN

N=1,000,000,000
M=1,000,000,000
O=>2,000,000,000

这是什么意思?摘要/ TL; DR

如果只允许每个用户访问实体中的一小部分对象,请使用IN数组。

如果每个用户都有一个实体的每个对象的ACL条目,请使用JOIN。虽然增益不会达到几个数量级(除非你有数万亿的产品),所以你可能仍然想要使用IN数组。

在这两种情况下,仅在绝对必要时才使用ACL!选民FTW!