Mysql 如何从外键ID计数和跟随外键

Mysql 如何从外键ID计数和跟随外键,mysql,sql,database,tree,Mysql,Sql,Database,Tree,基本上,我有一个名为folders的表,它存储我用来在网站上建立文件结构的数据,现在我想施加的限制之一是只允许用户创建3个文件夹,因为他们只能创建3个文件夹,如下所示: Folder 1 File 1.1 > Folder 2 File 2.1 > Folder 3 File 3.1 希望这能让我想象我想走多远 该表有:folderID、folderName和parentFolderID parentFolde

基本上,我有一个名为folders的表,它存储我用来在网站上建立文件结构的数据,现在我想施加的限制之一是只允许用户创建3个文件夹,因为他们只能创建3个文件夹,如下所示:

Folder 1
File 1.1
    >
    Folder 2
    File 2.1
        >
        Folder 3
        File 3.1
希望这能让我想象我想走多远

该表有:
folderID
folderName
parentFolderID

parentFolderID
设置为
NULL
如果该文件夹不在另一个文件夹下,如果某个文件夹确实属于另一个文件夹,则
parentFolderID
设置为另一个文件夹
folderID

我如何使用SQL检查用户已进入的深度,以便返回错误并说他们已达到最大文件夹深度?这种事情在SQL中可能发生吗?或者我应该处理这个后端吗

更新:

由于使用了此处的信息:

我想到了这个:

    SELECT node.folderName, (COUNT(parent.folderID))
    FROM folders AS node,
    folders AS parent
    WHERE node.folderID BETWEEN parent.parentFolderID AND parent.folderID
    GROUP BY node.folderName
    ORDER BY node.folderName;

但是当它检查第三个深度的文件夹时,它只返回1,这是它应该是3时计算的值?我做错了什么?

羞愧。我不知道如何使用mySQL进行树漫游,但由于您已将硬限制设置为3,您可以执行以下操作:-

select 
    child.folder_id,
    parent.folder_id,
    grand_parent.folder_id
from
    folder child
     left outer join
    folder parent
      on parent.folder_id = child.parent_folder_id
      left outer join
    folder grand_parent
      on grand_parent.parent_folder id = parent.parent_folder_id
; 

如果在插入前触发器中执行该检查,则如果grand_parent.folder不为空,则拒绝插入。

您可以获取所有不允许子级的深度3的
folderID

SELECT p3.folderID
FROM folders p1
    INNER JOIN folders p2
            ON p1.folderID = p2.parentFolderID
        INNER JOIN folders p3
                ON p2.folderID = p3.parentFolderID
WHERE p1.parentFolderID IS NULL
使用良好的存储过程:

CREATE PROCEDURE p(
    IN parentFolderID int,
    IN folderName varchar(15)
)
BEGIN
    IF NOT EXISTS (
        SELECT 1
        FROM folders p1
            INNER JOIN folders p2
                    ON p1.folderID = p2.parentFolderID
                INNER JOIN folders p3
                        ON p2.folderID = p3.parentFolderID
        WHERE
            p1.parentFolderID IS NULL
            AND p3.folderID = @parentFolderID
    )
    THEN
        INSERT INTO folders(`folderName`, `parentFolderID`)
        VALUES(@folderName, @parentFolderID);
    END IF;
END
//

您正在使用哪个数据库?Oracle非常擅长遍历树。@McMurphy MYSQL 5.5这真的很好,我会测试它,但是有没有办法让它检查20次,而不必写20次连接?@Erdss4这意味着强制递归:你必须创建一个过程来调用自己并检查深度。如果您不想使用递归,可以看看这个:这可能是不使用递归处理所需内容的最佳方法。如果你想了解更多这方面的信息,请告诉我,我非常熟悉;)嘿,我更新了我的问题并使用了你发送的链接,但是有问题,你能看一看吗?@ERDS4再次阅读我给你的链接,我认为你错过了右/左值的要点…哦,所以我想我使用邻接列表的模型是一个坏主意,没有folderID(主索引)和parentFolderID(指向主索引的指针)?我是否应该在数据库中以不同的方式存储它,我现在真的很纠结在哪里?如果可以,请尽量避免不必要的
左外连接
,它们比
内连接
(cf)慢,特别是当您将其放入触发器时,触发器将在每次插入时运行;)外部连接是有意的,因为我希望ant和所有先前的信息都有用,但我大体上同意您的看法。话虽如此,如果这是甲骨文,我将取消任何人为的硬限制,并使用select BY PRIOR。