返回
探索 MySQL 中的树形结构存储及查询
后端
2023-09-07 18:26:52
序
在计算机科学中,树形结构是一种广泛应用的数据结构,它以层级关系组织数据,便于数据存储和检索。在现实生活中,许多数据都具有树形结构,例如文件系统、组织机构、产品分类等。为了有效管理和查询这些数据,我们需要将它们存储在数据库中。MySQL 作为一款功能强大的数据库管理系统,提供了多种方法来存储和查询树形结构数据。
存储 parent
建表及数据准备
parent 方法是最简单直接的树形结构存储方法。它使用两个字段来表示树形结构中的父子关系:id 和 parent_id。其中,id 是每个节点的唯一标识符,parent_id 是每个节点的父节点的 id。
CREATE TABLE tree (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
parent_id INT,
PRIMARY KEY (id),
FOREIGN KEY (parent_id) REFERENCES tree(id)
);
INSERT INTO tree (name, parent_id) VALUES
('根节点', NULL),
('子节点1', 1),
('子节点2', 1),
('子节点3', 2),
('子节点4', 3);
查询
使用 parent 方法存储树形结构后,我们可以通过以下查询来检索数据:
-- 查找所有根节点
SELECT * FROM tree WHERE parent_id IS NULL;
-- 查找节点的子节点
SELECT * FROM tree WHERE parent_id = <node_id>;
-- 查找节点的所有祖先节点
SELECT * FROM tree WHERE id IN (
SELECT parent_id FROM tree
WHERE id = <node_id>
UNION
SELECT parent_id FROM tree
WHERE parent_id IN (
SELECT parent_id FROM tree
WHERE id = <node_id>
)
);
存储 path
建表及数据准备
path 方法使用一个字段来表示树形结构中的路径,即从根节点到当前节点的路径。路径通常使用分隔符来连接各个节点的 id,例如“1/2/3”。
CREATE TABLE tree (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
path VARCHAR(255) UNIQUE,
PRIMARY KEY (id)
);
INSERT INTO tree (name, path) VALUES
('根节点', '1'),
('子节点1', '1/2'),
('子节点2', '1/3'),
('子节点3', '1/3/4'),
('子节点4', '1/3/5');
查询
使用 path 方法存储树形结构后,我们可以通过以下查询来检索数据:
-- 查找所有根节点
SELECT * FROM tree WHERE path = '1';
-- 查找节点的子节点
SELECT * FROM tree WHERE path LIKE '<parent_path>/%';
-- 查找节点的所有祖先节点
SELECT * FROM tree WHERE path LIKE '%/<node_path>/%';
MPTT (Modified Preorder Tree Traversal)
MPTT 是一种特殊的存储方法,它将树形结构中的节点按照深度优先搜索(DFS)的顺序存储在数据库中。MPTT 使用两个字段来表示树形结构中的父子关系:id 和 lft/rgt。其中,id 是每个节点的唯一标识符,lft 是每个节点在 DFS 中的左边界,rgt 是每个节点在 DFS 中的右边界。
建表及数据准备
CREATE TABLE tree (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
lft INT NOT NULL,
rgt INT NOT NULL,
PRIMARY KEY (id)
);
INSERT INTO tree (name, lft, rgt) VALUES
('根节点', 1, 14),
('子节点1', 2, 5),
('子节点2', 6, 9),
('子节点3', 10, 13),
('子节点4', 11, 12);
查询
使用 MPTT 方法存储树形结构后,我们可以通过以下查询来检索数据:
-- 查找所有根节点
SELECT * FROM tree WHERE lft = 1;
-- 查找节点的子节点
SELECT * FROM tree WHERE lft > <parent_lft> AND rgt < <parent_rgt>;
-- 查找节点的所有祖先节点
SELECT * FROM tree WHERE lft < <node_lft> AND rgt > <node_rgt>;
比较
方法 | 优点 | 缺点 |
---|---|---|
parent | 简单直接,易于理解 | 查询效率较低 |
path | 查询效率较高 | 维护成本较高 |
MPTT | 查询效率高,维护成本低 | 实现复杂,理解难度大 |
总结
本文详细介绍了 MySQL 中树形结构存储及查询的多种方法,包括 parent、path 和 MPTT。每种方法都有其自身的优缺点,适合不同的场景。在实际应用中,我们可以根据具体需求选择合适的方法来存储和查询树形结构数据。