Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Drzewo MySQL uporządkowane według rodzica i dziecka

Poza metodami przedstawionymi na blogu Mike'a Hillyera istnieją inne sposoby organizowania danych hierarchicznych. Lubię używać metody, którą nazywam tablicą przechodniego zamknięcia lub stół zamykający w skrócie. W tym projekcie przechowujesz każdą ścieżkę w hierarchii jako pary przodek/potomek.

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);

Zwróć uwagę, że ten zestaw zawiera nawet „ścieżki” o długości zerowej, tj. element menu jest „rodzicem” samego siebie.

Teraz możesz dołączyć do każdego elementu menu m do każdego jego zestawu przodków a , łącząc się ze ścieżkami, w których m jest dekanantem. Stamtąd dołącz z powrotem do pozycji menu o który znajduje się w zestawie przodków i możesz uzyskać dostęp do order .

Użyj GROUP_CONCAT(), aby utworzyć ciąg „bułka tarta” z order każdego z nich w łańcuchu przodków, a to staje się łańcuchem, według którego możesz sortować, aby uzyskać żądaną kolejność menu.

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

Zwróć uwagę, że bułka tarta sortuje się jako ciąg, więc jeśli masz jakieś order numery z 2 lub 3 cyframi, otrzymasz nieregularne wyniki. Upewnij się, że Twoje order wszystkie liczby mają taką samą liczbę cyfr.

Jako alternatywę możesz po prostu przechowywać ciągi bułki tartej w oryginalnej tabeli menu:

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

Następnie możesz wykonać prostsze zapytanie:

SELECT * FROM menu ORDER BY breadcrumbs;

Ale wtedy to do Ciebie należy ręczne ponowne obliczenie wszystkich dotkniętych ciągów bułki tartej, jeśli kiedykolwiek zmienisz kolejność elementów menu.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak stworzyć bloga w PHP i bazie danych MySQL - projektowanie DB

  2. CURRENT_DATE/CURDATE() nie działa jako domyślna wartość DATE

  3. Egzekwuj unikalne wartości w dwóch tabelach

  4. Co jest nie tak z tą procedurą składowaną?

  5. MySQL:przekroczono limit czasu oczekiwania na blokadę