Wondercease

浙ICP备2022017321号

MySQL存储树形结构

要做个目录功能,开发的时候我用了1的办法

1.首先想到的是存 parent_id 这样的表

优点:查直接上级和下级很方便

缺点:查询和删除 间接的上级和下级很难

这就需要学习mysql 定义函数以及循环的方法

网上找了一个先贴在这里

CREATE DEFINER=`root`@`localhost` FUNCTION `getSubordinate`(`uid` int) RETURNS varchar(2000) CHARSET utf8mb4
BEGIN
DECLARE str varchar(1000);
DECLARE cid varchar(100);
DECLARE result VARCHAR(1000);
DECLARE tmpName VARCHAR(100);
SET str = '$';
SET cid = CAST(uid as char(10));
WHILE cid is not null DO
SET str = concat(str, ',', cid);
SELECT group_concat(eid) INTO cid FROM employees where FIND_IN_SET(parent_id,cid);
END WHILE;
SELECT GROUP_CONCAT(ename) INTO result FROM employees WHERE FIND_IN_SET(parent_id,str);
RETURN result;
END;

-- 查询父节点下的所有子节点
SELECT getSubordinate(2);

*开发的时候我还遇到因为事务隔离性不一样导致循环语句结果不一样的问题

2.存路径的方式

id name path

1.添加节点

插入自己,然后查出父节点的Path,并且把自己生成的ID更新到path

2.查询直接上下级

直接上级 就需要对path进行字符串处理 去掉自己的id REPLACE ( e2.path, CONCAT( ‘/’, e2.eid ), ” );

直接下级 正则表达式 REGEXP CONCAT( e1.path, ‘/[0-9]{1,}$’ );

3.查询所有上司 和下属

所有上司

SELECT
    e1.eid,
    e1.ename
FROM
    employees2 e1,
    employees2 e2
WHERE
    e2.ename = 'xx'
    AND e2.path LIKE concat( e1.path, '/%' );

所有下属:

SELECT
    e2.eid,
    e2.ename
FROM
    employees2 e1,
    employees2 e2
WHERE
    e1.ename = 'xx'
    AND e2.path LIKE concat( e1.path, '/%' );

优点:查询所有上级下级很方便

缺点:直接上下级很麻烦 且path长度 无法控制 时候深度小的

3 Closure Table(存储关系表和深度)

建立一张信息表

建立一张关系表

原id 联系id 是否为叶子节点 深度关系

发表评论

您的电子邮箱地址不会被公开。