简体   繁体   English

使用邻接表模型在MySQL中管理分层数据

[英]Managing Hierarchical Data in MySQL using The Adjacency List Model

I would like to retrieve all categories with parent in order to create a breadcrumb path. 我想检索所有与父类别,以创建一个面包屑路径。 for that reason I create the following schema: 因此,我创建以下架构:

CREATE TABLE category(
        category_id INT AUTO_INCREMENT PRIMARY KEY,
        name VARCHAR(20) NOT NULL,
        parent INT DEFAULT NULL
);
INSERT INTO category VALUES(1,'ELECTRONICS',NULL),(2,'TELEVISIONS',1),(3,'TUBE',2),
        (4,'LCD',2),(5,'PLASMA',2),(6,'PORTABLE ELECTRONICS',1),(7,'MP3 PLAYERS',6),(8,'FLASH',7),
        (9,'CD PLAYERS',6),(10,'2 WAY RADIOS',6);

SELECT * FROM category ORDER BY category_id;

+-------------+----------------------+--------+
| category_id | name                 | parent |
+-------------+----------------------+--------+
|           1 | ELECTRONICS          |   NULL |
|           2 | TELEVISIONS          |      1 |
|           3 | TUBE                 |      2 |
|           4 | LCD                  |      2 |
|           5 | PLASMA               |      2 |
|           6 | PORTABLE ELECTRONICS |      1 |
|           7 | MP3 PLAYERS          |      6 |
|           8 | FLASH                |      7 |
|           9 | CD PLAYERS           |      6 |
|          10 | 2 WAY RADIOS         |      6 |
+-------------+----------------------+--------+
10 rows in set (0.00 sec)

With the example I follow I can retrieve the information using the following SQL: 通过下面的示例,我可以使用以下SQL检索信息:

SELECT t1.name AS lev1, t2.name as lev2, t3.name as lev3, t4.name as lev4
FROM category AS t1
LEFT JOIN category AS t2 ON t2.parent = t1.category_id
LEFT JOIN category AS t3 ON t3.parent = t2.category_id
LEFT JOIN category AS t4 ON t4.parent = t3.category_id
WHERE t1.name = 'ELECTRONICS';

The problem I found is before being able to see the full path of a category we have to know the level at which it resides. 我发现的问题是,在查看类别的完整路径之前,我们必须知道其所处的级别。

my question, is there a way to retrieve the information as the following example but not defining the exact amount of levels? 我的问题是,有什么方法可以像下面的示例那样检索信息,但不能定义级别的确切数量?

+-------------+----------------------+-------------+-------+
| lev1        | lev2                 | lev3        | lev4  |
+-------------+----------------------+-------------+-------+
| ELECTRONICS | PORTABLE ELECTRONICS | MP3 PLAYERS | FLASH |

my idea is to retrieve lev1 or lev2 etc taking into consideration the depth level. 我的想法是在考虑深度级别的情况下检索lev1或lev2等。

UPDATE: 更新:

EXAMPLE OUTPUT 示例输出

ELECTRONICS
ELECTRONICS / TELEVISIONS
ELECTRONICS / TELEVISIONS / TUBE
ELECTRONICS / TELEVISIONS / LCD
ETC
ETC

There is a workaround. 有一种解决方法。

You can add collateral PATH column. 您可以添加附带的PATH列。 The column should have chain of ids from the elemetn to parent. 该列应具有从elemetn到父代的id链。 Thus for the root the column empty. 因此,对于根,该列为空。 All the children of root has _ 根的所有子代都有_

+-------------+----------------------+--------+--------+
| category_id | name                 | parent | path   |
+-------------+----------------------+--------+--------+
|           1 | ELECTRONICS          |   NULL |        |
|           2 | TELEVISIONS          |      1 |1_      |
|           3 | TUBE                 |      2 |1_2_    |
|           4 | LCD                  |      2 |1_2_    |
|           5 | PLASMA               |      2 |1_2_    |
|           6 | PORTABLE ELECTRONICS |      1 |1_      |
|           7 | MP3 PLAYERS          |      6 |1_6_    |
|           8 | FLASH                |      7 |1_6_7_  |
|           9 | CD PLAYERS           |      6 |1_6_    |
|          10 | 2 WAY RADIOS         |      6 |1_6_    |
+-------------+----------------------+--------+--------+

On insert a new node you just copy parent node path and add '_' So to retrieve all children of a node you just use 在插入一个新节点时,您只需复制父节点路径并添加'_',以便检索该节点的所有子节点

SELECT * 
FROM THE_TABLE
WHERE PATH LIKE '<parent node path>%'

There is a restriction of the field size and amount of levels though 尽管对字段大小和级别数量有限制

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM