webForumDet fria alternativet

Spara kategorier i flera nivåer på bästa sätt?

Databaser & SQL

5 svar · 519 visningar · startad av inspiro

Medlem sedan sep. 2005673 inlägg
Frågan#1

Hej! Jag ska skapa grupper och undergrupper i flera nivåer i en sql-serverdatabas och skulle behöva lite hjälp med vilken modell som är bäst (ska användas till en "treeview" på en webb.

Exmpelvis så här ska det se ut:

A
  A1
  A2
  A3
    A3a
    A3b
B
C
  C1
  C2

Viktigt är att jag kan hämta ut ALLA underkategorier till A, inte bara i ett led utan i flera led, i exemplet ovan så vill jag kunna få ut A3a och A3b genom att bara stå i A.

En lösning som jag vet fungerar är att ha en nyckel i databasen som ser ut så exempelvis här:

01.02.13

Vilket då betyder att jag befinner mig i huvudgruppen 01, i underkategorin 02 och sedan i en underkategori till den underkategorin 13.

Då kan jag få fram allt som finns under kategori 01 genom att skriva:

... LIKE '01%'

...och vill jag ha ut detsom finns i den tredje nivån (och neråt ytterligare om det finns ännu fler nivåer) genom att skriva

... LIKE '01.02.13%'

Men jag misstänker att detta är en dålig och långsam lösning? Ett alternativ är ju att använda ID och ParentID men jag lyckas inte få ut alla undernivåer i flera led från toppnivån? Några tips?

Medlem sedan dec. 20025 483 inlägg
#2

Genom att en ParentId-modell låter det som att CTE kan vara lösningen: http://msdn.microsoft.com/en-us/library/ms175972.aspx

Medlem sedan sep. 2005673 inlägg
#3

Hej! Jo, kan det nog vara men det verkar himla knepigt, får det inte att fungera... min andra lösning, är den väldigt mycket långsammare?

Undrar också om det blir någon hastighetsökning att använda 101010 och datatypen int istället för en varchar och skriva nyckeln 10.10.10?

Medlem sedan dec. 20025 483 inlägg
#4

Prestandan kan jag inte bedöma. Men jag gissar att antalet kategorier inte är _så_ många att DBMS skulle få för sig att strejka och tycka att livet är ett helvete.

Hur menar du att du skulle kunna använda tal i stället?

Personligen skulle jag nog ändå försöka mig på CTE.

Medlem sedan sep. 2005673 inlägg
#5

Tänkte att man kan använda tal om man förutsätter att varje kategori alltid består av 2 siffror (det blir aldrig fler än 99 i någon nivå ändå).

Men tjoho, jag tror jag har kommit en bra bit på vägen med CTE! :D Nu kan jag få fram alla underkategorier rekursivt under en kategori, fungerar klockrent och känns superdynamiskt. Så här ser koden ut:

WITH C(CategoryID, ParentID, Lvl, Field) AS 
(
    SELECT CategoryID, ParentID, 0 AS Lvl, Field
    FROM Categories
    [B][FONT="Arial Black"]WHERE ParentID IS NULL AND CategoryID = 2[/FONT][/B]
    UNION ALL
    SELECT e.CategoryID, e.ParentID, Lvl + 1, e.Field
    FROM Categories e
        INNER JOIN C
        ON e.ParentID = C.CategoryID 
)
SELECT CategoryID, ParentID, Lvl, Field 
FROM C

...och vill jag utgå från en kategori längre ned i hierarkin är det bara att justera parentid och categoryid where-satsen (i fetstil).

Men om jag vill gå andra hållet, hur gör jag då? Säg att jag är längst ned i den sista underkategorin och vill veta alla överordnade kategorier? Det lyckas jag inte få ut...

Medlem sedan feb. 20041 816 inlägg
#6

MySQL har en artikel om hur man kan spara och använda en hierarkisk struktur med en metod som de kallar för Nested Set Model. Det är inget jag använt mig av själv men det ser ganska sjyst ut. http://dev.mysql.com/tech-resources/articles/hierarchical-data.html

Finns det nån här som använt den metoden och kan säga några ord, lite snabbt bara?

257 ms totalt · 4 externa anrop · v20260731065814-full.6fe65c25
120 ms — deklarationer (db)
0 ms — hämta statistik (cache)
133 ms — hämta tråd, inlägg och bilagor (db)
121 ms — ändringar (db)