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?
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.
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å.
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