【问题标题】:MySQL Inheritance via 1 Table - PermissionsMySQL 通过 1 个表继承 - 权限
【发布时间】:2015-11-05 11:41:05
【问题描述】:

我的 MySQL 数据库中有一个名为“文件夹”的表。它为我们网站中的不同用户存储虚拟文件夹的名称。结构如下:

CREATE TABLE IF NOT EXISTS `folder` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `userId` int(11) NOT NULL,
  `parentId` int(11) DEFAULT NULL,
  `folderName` varchar(255) NOT NULL,
  `isPublic` int(1) NOT NULL DEFAULT '0'
  PRIMARY KEY (`id`)
);

该网站允许文件夹中包含任意数量的子文件夹,因此:

Base Folder
- Child Folder 1
--- Child Folder 2
etc

每个文件夹都可以具有公共或私人状态。所以:

Base Folder (Public)
- Child Folder 1 (Private)
--- Child Folder 2 (Private)

如果“子文件夹 1”设置为“私有”,则无论子文件夹是否已在 dd 中设置为公共,它总是会导致子文件夹为私有。

我的问题是,考虑到继承,如何通过 MySQL 确定特定文件夹是公共文件夹还是私有文件夹?

以“子文件夹2”为例。要检查它是私有的还是公共的,我们可以这样做:

SELECT isPublic FROM folder WHERE folderName = "Child Folder 2";

(只是一个例子,在代码中我们使用文件夹 ids :))

但这并没有考虑到继承。所以父文件夹可以设置为私有。

知道如何循环遍历任意数量的父文件夹,直到找到私有状态或不再有父文件夹。理想情况下,我需要从查询返回 1 或 0,1 是公共的,0 是私有的。

提前致谢, 红色。

【问题讨论】:

  • 一个简单的 SQL 查询将不起作用 - 您必须使用递归存储过程或在应用程序中完成它

标签: php mysql inheritance


【解决方案1】:

这是一个简单的存储过程,可以在 MySQL 中执行此操作。它有两个参数 testid 用于文件夹的 id 和 param1 将存储结果

DELIMITER //
CREATE PROCEDURE test_public(IN testid INT,OUT param1 INT)
BEGIN
DECLARE parent,public INT DEFAULT -1;

WHILE testid!=0 DO
SELECT f.parentID,f.isPublic INTO parent,public FROM folder f WHERE f.id = testid ;
IF (parent is not NULL and public is not NULL and parent!=0 and public!=0) THEN
  set testid=parent;
ELSE
  set testid=0;
END  IF;
END WHILE;

select public into param1;
END//
delimiter ;

/* Usage - @a will be 1 if the folder is public, 0 if it is private */
call test_public(3,@a);
select @a;

【讨论】:

    【解决方案2】:

    我在这里得到了一些帮助 - How to do the Recursive SELECT query in MySQL?

    select MIN(IF(isPublic>0, 1, 0)), @pv := if(isPublic>0,parentId,0) as 'parentId' 
    from (select * from folder order by id desc) t
    join (select @pv := 270) tmp
    where id = @pv
    

    结果是 1 表示公共或 0 表示私有。我在上面使用了 IF(isPublic>0, 1, 0) 因为 isPublic 在我的代码中实际上可以是 1 或 2。

    【讨论】:

    • 这个不错。您可以尝试 min(if(isPublic>0, 1, 0)) 代替 sum 和 count,应该返回相同的结果
    • 我注意到还有一件事 - 这将查询所有记录,直到顶部忽略可能更早找到私人文件夹的事实。我建议编辑 @pv := if(isPublic>0,parentId,0) 如果检测到私人文件夹,它将停止递归
    【解决方案3】:

    设置你想要检查的文件夹名称

    check_public($folder_name);
    function check_public($folder_name, $parent_id = FALSE) {
        $query = "select * from folder where ";
        echo $query.=$parent_id ? ("id =" . $parent_id) : ("folderName ='" . $folder_name . "'");exit;
        $result = mysql_query($query);
        if (mysql_num_rows($result)) {
            $row = mysql_fetch_object($result);
            if ($row->isPublic && $row->parentId) {
                check_public($folder_name, $row->parentId);
            } else {
                $public = $row->isPublic ? "public" : "private";
                echo $folder_name . ' is ' . $public;
                exit;
            }
        } else {
            echo 'folder name is not amtched in database';
        }
    }
    

    【讨论】:

    • 感谢您的回答,但是我已经可以在 PHP 中完成了。我希望在数据库级别执行此操作,因为它会更有效率。
    猜你喜欢
    • 2011-02-24
    • 2011-12-15
    • 1970-01-01
    • 2022-09-23
    • 1970-01-01
    • 2010-12-04
    • 2013-07-18
    • 2015-12-05
    • 1970-01-01
    相关资源
    最近更新 更多