sql >> Database teknologi >  >> RDS >> Mysql

MySQL Tree bestilt af forælder og barn

Der er andre måder at organisere hierarkiske data på end de metoder, der er vist i Mike Hillyers blog. Jeg kan godt lide at bruge en metode, jeg kalder transitive closure table eller lukkebord for kort. I dette design gemmer du hver sti gennem hierarkiet som forfader/efterkommer-par.

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

Bemærk, at dette sæt også inkluderer "stier" af længde nul, dvs. et menupunkt er en "forælder" af sig selv.

Nu kan du tilslutte dig hvert menupunkt m til hver dens sæt af forfædre a , ved at slutte sig til stier hvor m er descandant. Gå derfra tilbage til menupunktet o som er i sættet af forfædre, og du kan få adgang til order .

Brug GROUP_CONCAT() til at lave en streng af "brødkrummer" fra order af hver i kæden af ​​forfædre, og dette bliver en streng, du kan sortere efter for at få den menurækkefølge, du ønsker.

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

Bemærk, at brødkrummerne sorterer som en streng, så hvis du har en order tal med 2 eller 3 cifre, vil du få uregelmæssige resultater. Sørg for at din order numre har alle det samme antal cifre.

Som et alternativ kan du blot gemme brødkrummestrengene i din originale menutabel:

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

Så kan du lave en enklere forespørgsel:

SELECT * FROM menu ORDER BY breadcrumbs;
 

Men så er det op til dig manuelt at genberegne alle berørte brødkrummestrenge, hvis du nogensinde ændrer rækkefølgen af ​​menupunkterne.



  1. Hvordan tester man, om en MySQL-forespørgsel lykkedes med at ændre databasetabeldata?

  2. MariaDB navngivne kommandoer

  3. Hvordan eksporteres tabel som CSV med overskrifter på Postgresql?

  4. DevOps-databaseordliste til MySQL-begynderen