如何计算和跟踪外键ID

时间:2017-11-12 22:23:29

标签: mysql sql database tree

所以基本上我有一个名为文件夹的表,它存储用于在网站上构建文件结构的数据,现在我希望强加的限制之一是只允许用户将3个文件夹设置为深层,如他们只能这样制作3个文件夹:

Folder 1
File 1.1
    >
    Folder 2
    File 2.1
        >
        Folder 3
        File 3.1

希望可视化我想走多远。

该表格包含:folderIDfolderNameparentFolderID

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

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

更新

使用此处的信息:http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql

我想出了这个:

    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时的计数?我做错了什么?

2 个答案:

答案 0 :(得分:1)

耻。我不知道如何使用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
; 

如果你这样做,请检查BEFORE INSERT触发器,如果​​grand_parent.folder不是NULL,则拒绝插入。

答案 1 :(得分:1)

你可以得到不允许孩子的所有folderID深3:

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
//