Mysql
 sql >> база данни >  >> RDS >> Mysql

MySQL дърво, подредено от родител и дете

Има и други начини за организиране на йерархични данни освен методите, показани в блога на Майк Хилър. Обичам да използвам метод, който наричам преходна таблица за затваряне или накратко таблица за затваряне. В този дизайн вие съхранявате всеки път през йерархията като двойки предшественик/наследник.

create table closure (
    ancestor int,
    descendant int,
    length int,
    primary key (ancestor,descendant),
    key (descendant,ancestor)
);
insert into closure values
(1,1,0),
(1,3,1),
(1,4,2),
(1,5,3),
(2,2,0),
(3,3,0),
(3,4,1),
(3,5,2),
(4,4,0),
(4,5,1),
(5,5,0);

Имайте предвид, че този набор включва дори „пътеките“ с нулева дължина, т.е. елемент от менюто е „родител“ сам за себе си.

Сега можете да се присъедините към всеки елемент от менюто m на всеки негов набор от предци a , чрез присъединяване към пътища, където m е дескандантът. Оттам се присъединете обратно към елемента от менюто o който е в набора от предшественици и можете да получите достъп до order .

Използвайте GROUP_CONCAT(), за да направите низ от "хлебни трохи" от order от всеки във веригата от предци и това се превръща в низ, по който можете да сортирате, за да получите желания ред на менюто.

SELECT m.*, GROUP_CONCAT(o.`order` ORDER BY a.length DESC) AS breadcrumbs
FROM menu AS m
INNER JOIN closure AS a ON a.descendant = m.id
INNER JOIN menu AS o ON a.ancestor = o.id
GROUP BY m.id
ORDER BY breadcrumbs;

+----+----------+-------+-------------+
| id | name     | order | breadcrumbs |
+----+----------+-------+-------------+
|  1 | Father1  |     0 | 0           |
|  3 | Son      |     0 | 0,0         |
|  4 | Child    |     1 | 0,0,1       |
|  5 | Grandson |     2 | 0,0,1,2     |
|  2 | Father2  |     1 | 1           |
+----+----------+-------+-------------+

Имайте предвид, че галетата се сортират като низ, така че ако имате някакъв order числа с 2 или 3 цифри, ще получите неправилни резултати. Уверете се, че вашата order всички числа имат еднакъв брой цифри.

Като алтернатива можете просто да съхраните низовете на галета в оригиналната си таблица на менюто:

ALTER TABLE menu ADD COLUMN breadcrumbs VARCHAR(255);
UPDATE menu SET breadcrumbs = '0,0,1,2' WHERE id = 5;
etc.

След това можете да направите по-проста заявка:

SELECT * FROM menu ORDER BY breadcrumbs;

Но след това зависи от вас да преизчислите ръчно всички засегнати низове на галерията, ако някога промените реда на елементите от менюто.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да промените външния ключ на MySQL таблица с помощта на командния ред

  2. C# Mysql UTF8 кодиране

  3. Защита от инжектиране на MySQL и знаци за уязвимост с помощта на PHP

  4. MySQL съответства на 2 от 5 полета

  5. Как да изберете ограничено количество редове за всеки външен ключ?