Vinnaren i pepparkakshustävlingen!
  • 1
  • 2
2006-08-15, 12:42
  #1
Medlem
Hej!

Jag håller på att fixa lite grejer. I min webbapplikation ska man kunna lägga upp saker, och varje sak ska kunna kopplas till ett eller flera nyckelord. Det jag undrar är vad som blir effektivast, en one-to-many-relation där jag har en nyckelordstabell med kolumnerna grej_id och nyckelord, eller en many-to-many där jag har två tabeller, en med bara nyckelord och en som mappar grejer till nyckelord. Jag inser såklart att det första alternativet kommer ta mycket mer utrymme, eftersom de flesta nyckelord kommer förekomma flera gånger, men blir det inte också mer "optimerat"?
Citera
2006-08-15, 19:37
  #2
Medlem
1. Ett nyckelord kan kopplas från en till många saker
2. En sak kan kopplas från ett till många nyckelord

Med andra ord du bör använda many-to-many eftersom det är så som relationen är Oftast är det väldigt bra att forumlera relationerna i klartext, så som jag gjorde ovan, då brukar man enkelt kunna få fram vilken relation "problemet" har.

Citat:
Ursprungligen postat av kungdenknege
Jag inser såklart att det första alternativet kommer ta mycket mer utrymme, eftersom de flesta nyckelord kommer förekomma flera gånger, men blir det inte också mer "optimerat"?
Alternativ ett är helt värdelöst dvs felaktig databasdesign som skulle innebära en rejäl rendundans i databasen.
Citera
2006-08-15, 19:48
  #3
Moderator
Ruskigbusss avatar
I praktiken alltså tre tabeller - many-to-many realiseras med två one-to-many:

1. Grej-tabellen (grejid, grejattribut ... )
2. Nyckelord-tabellen (nyckelordsid, nyckelord)
3. Kopplingstabellen (grejid, nyckelordsid)

(Bonus är att du också kan kategorisera dina nyckelord:
4. Kategoritabell (kategorid, kategoritext)
5. Nyckelkategoritabell (kategoriid, nyckelordsid)
Citera
2006-08-16, 13:06
  #4
Medlem
Tack! Jorå, jag är medveten om att det blir massa redundans med alt 1, men visst måste det gå mycket snabbare?

Om jag t.ex. ska leta fram en grej efter ett nyckelord krävs först en scanning av nyckel-ordstabell, sedan en scanning av grejtabell med alternativ ett. Med alternativ två krävs först en scanning av nyckelordstabell, sedan en scanning av associationstabell och sedan en scanning av grejtabell. Även vid insert blir det mycket mer jobb, först en scanning av nyckelordstabell (sannolikt måste hela scannas igenom eftersom de flesta nyckelord till att börja med inte kommer ge match), sedan eventuellt en insert i nyckelordstabell, insert i associationstabell och sist insert i grejtabell. Är det värt att offra massa prestanda för att slippa redundans?
Citera
2006-08-16, 13:30
  #5
Medlem
Y0dAs avatar
Citat:
Ursprungligen postat av kungdenknege
Tack! Jorå, jag är medveten om att det blir massa redundans med alt 1, men visst måste det gå mycket snabbare?

Om jag t.ex. ska leta fram en grej efter ett nyckelord krävs först en scanning av nyckel-ordstabell, sedan en scanning av grejtabell med alternativ ett. Med alternativ två krävs först en scanning av nyckelordstabell, sedan en scanning av associationstabell och sedan en scanning av grejtabell. Även vid insert blir det mycket mer jobb, först en scanning av nyckelordstabell (sannolikt måste hela scannas igenom eftersom de flesta nyckelord till att börja med inte kommer ge match), sedan eventuellt en insert i nyckelordstabell, insert i associationstabell och sist insert i grejtabell. Är det värt att offra massa prestanda för att slippa redundans?
Fast har du en jävligt stor tabell med grejer så är det möjligt att alternativ 1 blir långsammare. Sen kan man ju även fråga sig varför du oroar dig så för prestandan. Som regel när det gäller såna här grejer så är det bäst att göra en snygg design från början och om resultatet i slutändan blir för slött så får man optimera det då.
Citera
2006-08-16, 13:55
  #6
Moderator
Ruskigbusss avatar
En aspekt till är risken för felinmatningar.

Om du - eller ännu vanligare flera olika personer - skall skriva in nyckelordet "Riesenschnauscher" på flera olika grejer, hur stora är oddsen tror du att du kommer att få många olika varianter på detta ord?
Citera
2006-08-23, 05:15
  #7
Medlem
korbens avatar
Citat:
Ursprungligen postat av Ruskigbuss
En aspekt till är risken för felinmatningar.

Om du - eller ännu vanligare flera olika personer - skall skriva in nyckelordet "Riesenschnauscher" på flera olika grejer, hur stora är oddsen tror du att du kommer att få många olika varianter på detta ord?
Man ser ju till att användaren inte kan välja fritt vilken indata/nyckelord ska matas in. När det gäller en webbapplikation så fungerar dropdown-boxar bra för ett sådant ändamål.
Citera
2006-08-26, 00:20
  #8
Medlem
Njaeäh, sällan när man leker med nyckelord... Kika flickr till exempel. Svårt att få snygga dropdowns med X*10^5 olika alternativ
Citera
2006-08-29, 20:28
  #9
Medlem
Drar upp tråden igen! Har köpt era argument och har nu en fullständigt normaliserad db. Nu till kruxet; jag vill söka efter en grej som har både nyckelordet A och nyckelordet B.

Kod:
SELECT * FROM grej, keyword WHERE grej.id = keyword.grej_id AND keyword.keyword = "A" AND keyword.keyword = "B";
kommer ju självklart inte ge mig några resultat, eftersom det inte finns några rader efter JOIN:en som har både nyckelord A och B. Hur göra?
Citera
2006-08-29, 21:46
  #10
Moderator
Ruskigbusss avatar
Istället för AND - så använd OR - så får du de som har antingen den ena eller den andra.

Dvs:
Kod:
SELECT * FROM grej, keyword 
WHERE grej.id = keyword.grej_id AND 
( keyword.keyword = "A" OR keyword.keyword = "B" );
Citera
2006-08-29, 22:39
  #11
Medlem
fulltexts avatar
exists:

Kod:
SELECT *
FROM grej
WHERE EXISTS(
    SELECT * keyword WHERE grej.id = keyword.grej_id AND keyword.keyword = "A"
) AND EXISTS(
    SELECT * keyword WHERE grej.id = keyword.grej_id AND keyword.keyword = "B"
)

join:
Kod:
SELECT g.*
FROM grej AS g
JOIN keyword AS k1 ON g.id = k1.grej_id AND k1.keyword = "A"
JOIN keyword AS k2 ON g.id = k2.grej_id AND k2.keyword = "B"
Citera
2006-08-29, 23:24
  #12
Medlem
Citat:
Ursprungligen postat av Ruskigbuss
Istället för AND - så använd OR - så får du de som har antingen den ena eller den andra.

Dvs:
Kod:
SELECT * FROM grej, keyword 
WHERE grej.id = keyword.grej_id AND 
( keyword.keyword = "A" OR keyword.keyword = "B" );

Ursäkta min dryghet ärade moderator men - DAAH!
Grejen är att jag vill ha möjlighet att hämta bara de med båda (eller flera) nyckelorden. En fungerande men ful lösning hade varit att köra din fråga och sedan sortera bort de man inte vill ha i "runtomkring-programmet", ett PHP-skript i det här fallet. Desvärre funkar inte det heller eftersom min fråga inte alls ser ut så, utan grupperas efter grej_id i ett senare skede och alltså kommer ändå bara ett record, med ett keyword, tillbaka från frågan. Men tack iallaflal!

Citat:
Ursprungligen postat av fulltext
exists..
Tack! Det där kan jag nog använda.
Citera
  • 1
  • 2

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback