sql >> Databasteknik >  >> RDS >> Mysql

MySQL Tree beställt av förälder och barn

Det finns andra sätt att organisera hierarkisk data förutom de metoder som visas i Mike Hillyers blogg. Jag gillar att använda en metod som jag kallar transitive closure table eller förkortat stängningsbord. I den här designen lagrar du varje väg genom hierarkin, som förfader/ättlingspar.

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

Observera att den här uppsättningen även inkluderar "vägarna" med längden noll, dvs. ett menyalternativ är en "förälder" till sig själv.

Nu kan du gå med i varje menyalternativ m till varje dess uppsättning förfäder a , genom att ansluta till sökvägar där m är descandant. Därifrån går du tillbaka till menyalternativet o som finns i uppsättningen av förfäder, och du kan komma åt order .

Använd GROUP_CONCAT() för att skapa en sträng av "brödsmulor" från order av varje i kedjan av förfäder, och detta blir en sträng som du kan sortera efter för att få den menyordning du vill ha.

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

Observera att brödsmulorna sorteras som en sträng, så om du har någon order siffror med 2 eller 3 siffror får du oregelbundna resultat. Se till att din order siffror har alla samma antal siffror.

Som ett alternativ kan du helt enkelt lagra ströbrödssträngarna i din ursprungliga menytabell:

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

Sedan kan du göra en enklare fråga:

SELECT * FROM menu ORDER BY breadcrumbs;

Men sedan är det upp till dig att manuellt räkna om alla påverkade brödsmulor, om du någonsin ändrar ordningen på menyalternativen.



  1. Förstå index i MySQL:Del tre

  2. Vad är skillnaden mellan PHPs addslashes och mysql(i)_escape_string?

  3. Hur LTRIM()-funktionen fungerar i MySQL

  4. Varför Optimizern inte använder Buffer Pool Knowledge