【问题标题】:Recursive and non-recursive ACLs in one SQL statement一条 SQL 语句中的递归和非递归 ACL
【发布时间】:2018-03-12 02:32:51
【问题描述】:

我正在考虑一个当前的问题——当你在树上搜索每个节点的 ACL 时总是会发生这种情况——如果用户请求分页结果,我有时必须检索原始结果,过滤ACL,如果我没有足够的结果,我必须再次搜索......直到我有足够的结果。

一次性搞定不是更好吗?

鉴于此(为简洁起见,我跳过索引):

CREATE DATABASE `test`;

CREATE TABLE `acl` (
  `id` varchar(36) NOT NULL,
  `entry_id` varchar(36) NOT NULL,
  `principal_id` varchar(36) NOT NULL,
  `recursive` tinyint(1) NOT NULL,
  `permission` varchar(45) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_entry_has_acl_idx` (`entry_id`),
  CONSTRAINT `fk_entry_has_acl` FOREIGN KEY (`entry_id`) REFERENCES `entry` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `entry` (
  `id` varchar(36) NOT NULL,
  `parent_id` varchar(36) DEFAULT NULL,
  `path` varchar(512) DEFAULT NULL,
  `name` varchar(128) DEFAULT NULL,
  `type` varchar(45) DEFAULT NULL,
  `category` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

此语句是否(跳过任何实际搜索条件):

SELECT 
    e.* 
FROM 
    entry e JOIN acl a JOIN entry e2 ON 
        ((
              e.id = a.entry_id 
            AND 
              a.recursive=0 
          ) OR (
              a.entry_id = e2.id
            AND 
              e.path LIKE CONCAT(e2.path,'%') 
            AND
              a.recursive=1

        )) 
        AND 
          a.principal_id in ("K") 
        AND 
          a.permission IN ("READ","WRITE")
    GROUP BY e.id;

成为我正在寻找的陈述?你能发现任何明显的改进和/或错误吗?我对那里的 CONCAT 语句有点不满意......有没有办法避免这种情况?

编辑:ID 是 UUID,“路径”字段将一直包含父 ID,如下所示:

 c83eff41-dec8-45fb-94ef-6e3f380ebcec.1db333d9-995e-4e24-af8a-da2faf962060.dd71fd12-c975-4f33-bf0e-2df9da312bcd

【问题讨论】:

  • 你应该在%之前有目录分隔符,这样你就不会匹配相似但没有嵌套的路径。
  • @barmar 你说的有点对,但我使用的是 UUID,而且我使用的是 UUID 中的路径,而不是名称。无论如何它们都是固定长度的。所以我真的不希望那里有任何碰撞。我将在问题中添加此约束。

标签: mysql sql recursion


【解决方案1】:

所以,我的第一个优化是在 ACL 表中包含路径(我对 concat 所做的操作),包括或不包括通配符(取决于递归标志)

foo bar recursive  entry_path

... ... 1          ID1.ID2.ID3% 
... ... 0          ID1.ID2.ID3

所以我可以通过一个简单的 LIKE 加入

.... FROM entry e, entry_acl a ON e.

【讨论】:

    猜你喜欢
    • 2013-05-08
    • 1970-01-01
    • 2013-07-06
    • 2016-10-30
    • 2010-10-30
    • 1970-01-01
    • 1970-01-01
    • 2010-09-23
    • 1970-01-01
    相关资源
    最近更新 更多