Avatar billede bongii Nybegynder
10. december 2007 - 15:22 Der er 11 kommentarer og
1 løsning

Hjælp til databasedesign

Hej eksperter :)
Jeg er ved at lave en opgave hvor jeg skal have katagoriseret en masse katagorier til søgning.

F.eks: Drikkelse -> spiritus -> vin -> rødvin

Jeg kan ikke rigtig komme i gang, har prøvet noget databasedesign med f.eks. 4 tabeller med navnene level1, level2, level3 osv.

Er der en der har et godt forslag?
Avatar billede pidgeot Nybegynder
10. december 2007 - 15:26 #1
Det er jo reelt en træstruktur du har med at gøre, så der er jo muligheden for den helt simple løsning med tre felter:

id
name
parent_id
Avatar billede bongii Nybegynder
10. december 2007 - 15:31 #2
Ja, men er det nu også det smarteste? Jeg tænker bare på 5 niveauer.. SQL udtræk bliver rimeligt tungt.

Det skal være muligt at søge på "name" i alle niveauer. Dvs. 5 sql forespørgsler.
Avatar billede bongii Nybegynder
10. december 2007 - 15:36 #3
og det kan godt ske et produkt kun er tilknyttet katagorien "spiritus" og ikke længere ned i katagorierne. Hvordan får jeg det tilknyttet på "varer" tabellen?
Avatar billede pidgeot Nybegynder
10. december 2007 - 15:52 #4
Vare-tabellen har blot en felt der peger på dens kategori-id. Der er ingen grund til at den ikke kan pege på en der ikke ligger nederst i hierarkiet.

Når du søger kan du jo bare ignorere hvilket niveau det er på. Når du så skal bruge den fulde sti, kan du arbejde dig op igennem hierarkiet.

Et alternativ er at overveje den såkaldte nested set-model. Der er en beskrivelse (baseret på MySQL, men princippet er det samme for MSSQL) på http://dev.mysql.com/tech-resources/articles/hierarchical-data.html.

Om den ene eller den anden er bedst afhænger i høj grad af hvilke behov du har.
Avatar billede bongii Nybegynder
10. december 2007 - 16:14 #5
Artiklen er en stor hjælp. Smid et svar. Takker :)
Avatar billede pidgeot Nybegynder
10. december 2007 - 16:25 #6
Værsgo :)
Avatar billede bongii Nybegynder
10. december 2007 - 18:42 #7
forresten.

Hvordan udskriver jeg lettets og hurtigst hele hirakiet? hvis jeg har ID=7 vil jeg gerne have skrevet: Dagligvarer -> Drikkevarer -> øl
ID      NAME            ParentID
1    Dagligvarer    NULL
2    Computer    NULL
3    Børn            NULL
4    Mad            1
5    Drikkevarer    1
6    Sodavand    5
7    Øl            5
Avatar billede pidgeot Nybegynder
10. december 2007 - 18:57 #8
Du ville være nødt til at hente rekursivt, tagende et punkt af gangen (så du starter med Øl, hvilket fører dig til Drikkevarer, hvilket fører dig til Dagligvarer). Derfor var den anden model måske en ide (der er givet et eksempel i artiklen).

MSSQL2005 har vist fået tilføjet noget de kalder CTE, der med den simple struktur lader dig hente det hele med en query - men det er ikke noget jeg rigtigt har kigget på.
Avatar billede arne_v Ekspert
11. december 2007 - 03:18 #9
Jeg lavede engang et par eksempeler:

2000 style
----------

CREATE TABLE stuff (id INTEGER PRIMARY KEY,name VARCHAR(50),parent INTEGER)
GO

INSERT INTO stuff VALUES(1,'tools',0)
GO
INSERT INTO stuff VALUES(2,'hammer',1)
GO
INSERT INTO stuff VALUES(3,'screwdriver',1)
GO
INSERT INTO stuff VALUES(4,'fruits',0)
GO
INSERT INTO stuff VALUES(5,'yellow fruits',4)
GO
INSERT INTO stuff VALUES(6,'green fruits',4)
GO
INSERT INTO stuff VALUES(7,'apple',6)
GO
INSERT INTO stuff VALUES(8,'banana',5)
GO
INSERT INTO stuff VALUES(9,'grape',6)
GO

CREATE FUNCTION lookupone(@parent INTEGER) RETURNS VARCHAR(8000)
AS
BEGIN
    DECLARE @id INTEGER
    DECLARE @idlist VARCHAR(8000)
    SET @idlist = ''
    DECLARE c CURSOR FOR SELECT id FROM stuff WHERE parent = @parent
    OPEN c
    FETCH NEXT FROM c INTO @id
    WHILE @@FETCH_STATUS = 0
    BEGIN
        SET @idlist = @idlist + ',' + CAST(@id AS VARCHAR(9)) + dbo.lookupone(@id)
        FETCH NEXT FROM c INTO @id
    END
    CLOSE c
    DEALLOCATE c
    RETURN @idlist
END
GO

CREATE PROCEDURE lookup(@name varchar(50))
AS
BEGIN
    DECLARE @id INTEGER
    DECLARE @idlist VARCHAR(8000)
    DECLARE @sql VARCHAR(8000)
    SET @id = (SELECT id FROM stuff WHERE name = @name)
    SET @idlist = CAST(@id AS VARCHAR(9)) + dbo.lookupone(@id)
    SET @sql = 'SELECT * FROM stuff WHERE id IN (' + @idlist + ')'
    EXEC(@sql)
END
GO

EXEC lookup 'tools'
GO
EXEC lookup 'fruits'
GO

DROP PROCEDURE lookup
GO
DROP FUNCTION lookupone
GO

DROP TABLE stuff
GO

2005 style
----------

CREATE TABLE stuff (id INTEGER PRIMARY KEY,name VARCHAR(50),parent INTEGER)
GO

INSERT INTO stuff VALUES(1,'tools',0)
GO
INSERT INTO stuff VALUES(2,'hammer',1)
GO
INSERT INTO stuff VALUES(3,'screwdriver',1)
GO
INSERT INTO stuff VALUES(4,'fruits',0)
GO
INSERT INTO stuff VALUES(5,'yellow fruits',4)
GO
INSERT INTO stuff VALUES(6,'green fruits',4)
GO
INSERT INTO stuff VALUES(7,'apple',6)
GO
INSERT INTO stuff VALUES(8,'banana',5)
GO
INSERT INTO stuff VALUES(9,'grape',6)
GO

WITH x (id, name, parent) AS
(
    SELECT id,name,parent FROM stuff WHERE name = 'fruits'
    UNION ALL
    SELECT stuff.id,stuff.name,stuff.parent FROM stuff INNER JOIN x ON stuff.parent = x.id
)
SELECT * FROM x
GO

DROP TABLE stuff
GO
Avatar billede bongii Nybegynder
11. december 2007 - 15:24 #10
nice arne!!
Avatar billede bongii Nybegynder
11. december 2007 - 16:41 #11
Arne du har ikke tilfældigvis lavet et asp / javascript, således man som admin kan tilknytte et produkt til en katagori. Tænkte på noget dynamisk dropdown.
Avatar billede bongii Nybegynder
24. januar 2008 - 14:54 #12
Svar?
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester