"Hvilket jeg ikke syntes er særlig optimalt at arbejde med, så hvordan for jeg "Resultat #1"".
Jeg kan ikke se hvordan du kan få mysql til at give dig resultat 1. De forskellige opskrifter ligger netop i forskellige rækker, med forskelligt indhold, så det er vel logisk at du får alle rækkerne ud (på trods af at de har nogle ens rækker).
Jeg ville håndtere det i din efterfølgende kode, evt. lave en funktion du lige kan sende resultatet til som så ordner det for dig og returnerer et array i det format du vil have.
Jeg bruge MySQL, og mit mål er sådan set at have en normaliseret database. Som gør det muligt at søge efter flere kategorier uden at skulle ud i noget RegExp.
er egenlig ikke det SQL og relational databases er konstrueret til at give. Meningen er at du i SQL skal traekke data og deres relationer ud, og skal du have det formatteret paa specielle maader goer du det i din application, for eksempel en php side.
Hvor mange tabeller du i din normalisering skal lave afhaenger af naturen af dine data. Inden jeg saa intenz's indlaeg med de fire tabeller havde jeg for test lavet tre tabeller, andreas_opskrift, andreas_kategori, og andreas_opskrift_kategori idet jeg gik ud fra at en karakteristik for en ret var dens land saa du for eksempel ikke har Supperis fra flere forskellige lande. Hvis du vil kunne skelne mellem dansk supperis, fransk supperis, o.s.v. giver jeg intenz ret i de fire tabeller.
Her er tabellerne:
CREATE TABLE andreas_opskrift(id INT, navn VARCHAR(20), land VARCHAR(20)); CREATE TABLE andreas_kategori(id INT, kategory VARCHAR(20)); CREATE TABLE andreas_opskrift_kategori(opskrift_id INT, kategori_id INT);
Hvis du saa vil have opskrifter fra Danmark i to kategorier, forret og suppe, saa virker denne query:
SELECT navn, land, kategory FROM andreas_opskrift o JOIN andreas_opskrift_kategori ok ON o.id = ok.opskrift_id JOIN andreas_kategori k ON ok.kategori_id = k.id WHERE kategory = 'Forret' OR kategory = 'Suppe' AND land = 'Danmark'
som giver dette resultat:
navn land kategory suppe ris Danmark Forret suppe ris Danmark Suppe
og at faa det paa en linie er saa efter min mening en opgave for den application du bruger til at kalde og behandle sql querien.
Tak det var specielt den sidste linje: "og at faa det paa en linie er saa efter min mening en opgave for den applikation du bruger til at kalde og behandle sql querien." Der var enlig svaret på mit spørgsmål.
Jeg går ud fra at jeg så ved hjælp af opskriftens id kan finde ud af i min applikation, om der er tale om den samme opskrift og så samle det til en række, og til sidst præsenter det for brugeren i en tabel.
I forbindelse med denne tråd er har spørgsmålet "Er normalisering en fordel" strejfet mig. Er det noget i kan kaste lys over?
Normalisering er en fordel ved at du kun har en værdi ét sted i din database.
Hvis du f.eks. vil ændre en kategori eller et land, er det nemmere bare at skulle ændre det ét sted i stedet for xx steder i din tabel. Det gør det også nemmere at udvide system (afhængigt af opbygning. Derudover er det nemmere at overskue systemet når det hele ikke er rodet sammen i en (eller flere) tabeller.
Du får også en fordel ved dine joins, idet det er hurtigere for mysql at søge på INT felter (keys) end på VARCHAR/CHAR felter. Så ved kun at skulle slå f.eks. Danmark op i én tabel, hente dens ID og så joine på det ID med opskrift tabeller vil det (alt andet lige) være hurtigere end at skulle scanne hele opskrift tabellen efter for "Danmark".
Lige for at svare på denne her: "Men jeg kan ikke helt se hvordan jeg med dit eksempel vil få mulighed for at have mere end en kategori til en opskrift"
Hvis du vil have flere kategorier, opretter du bare den samme opskrift igen, bare med et andet land_id.
Og til denne: "Jeg går ud fra at jeg så ved hjælp af opskriftens id kan finde ud af i min applikation, om der er tale om den samme opskrift og så samle det til en række, og til sidst præsenter det for brugeren i en tabel." Er svaret ja. Hvert ID vil vise om opskriften, landet eller kategorien er den samme. Så kan din logik i applikationen samle det hele til det format du ønsker.
Bare lige en ekstra info. Der er efterhånden begyndt at komme flere andre databaser der fungerer som objectorienterede databaser eller key/value databaser, i modsætning til relationelle databaser (som f.eks. MySQL). De er en del af det der kendes som NoSQL databaser. Ved at bruge sådan en ville man kunne gemme dataet på den måde du gerne vil have, uden at skulle bruge joins eller lign.
Det er dog ikke noget du umiddelbart kan bruge, da de ikke understøttes af typiske webhoteller (som jeg kender til). Og det er heller ikke en teknologi der er udbredt nok til at man nemt kan få hjælp til at bruge dem, så det er ikke noget man lige gør.
Men om nogle år begynder det måske så småt at være en reel løsning til det bruger du stiller op :)
1. Det synes at du har faaet kastet lys over dit oprindelige spoergsmaal og at mit indlaeg har vaeret til nytte. Jeg opretter derfor et svar for pointgivning. (Hvis du mener at andre skal have points ogsaa vil du nok opfordre dem til at lave svar.)
2. Saa opstaar der nye spoergsmaal saasom hvordan du i din applikation for udformet resultatet af sql queryen efter oenske. Det vil nok vaere mest hensigtsmaessigt at behandle det i et nyt spoergsmaal (hvis noedvendigt) i stedet for en udvidelse af dette. Saa bliver det set af flere medlemmer hvoraf nogle maaske har bedre ideer end mig. (I et saadan nyt spoergsmaal vil du naturligvis forklare hvilken applikation du bruger og hvilken SQL version o.s.v.)
3. Og saa til slut spoergsmaalet om normalisering er en fordel. Det kan jeg give et entydigt svar paa: "Det afhaenger af omstaendighederne!" Hvis du for eksempel skal have lavet en liste over medlemmerne i din soen's fodboldklub saa du eller han kan ringe/emaile/besoege og det ikke er sandsynligt at det skal bruges til mere saa er det nok spild af tid at proeve at normalisere noget. Saa saet det op paa et simpelt Excel regneark. Men hvis det kunne taenkes at du kommer i bestyrelsen i klubben og ogsaa skal kende spillernes foraeldre, holde styr paa om der er betalt kontingent, holde regnskab med spillernes resultater, indberette til forbundet, o.s.v., saa er normalisering uundvaerlig. Hvis hver "slags" data sidder i sin egen tabel, tabellerne relaterer til hinanden med fremmednoegler, tabellerne og relationerne er udformet ud fra logikken og strukturen i dataerne, ikke ud fra de resultater du oensker at se, altsaa hvis dataerne er normaliserede, saa vil du ud fra tabellerne i fremtiden kunne traekke svar ud paa spoergsmaal du ikke havde taenkt paa da du konstruerede databasen og du vil nemt kunne udbrede databasen.
Jeg har ikke noget at tilføje; intenz og CB svar er spitzeklasse, specielt CB's pkt. 3 er nemlig uhyre vigtigt at have i tankerne; it depends :)
Læs evt. lidt om Boyce Codd, opfinderen af relationelle db'er. The key, the whole key and nothing but the key, So help me Codd *GG*
Jeg har dog lige en til intenz -> "Du får også en fordel ved dine joins, idet det er hurtigere for mysql at søge på INT felter (keys) end på VARCHAR/CHAR felter." - Igen så afhænger det af størrelsen på dine varchars. En int fylder 4 byte, en varchar(2) 2 byte. Dvs. eks.vis landekoder hvis datatypen er int, måske burde laves som varchar(2), valuta ligeså osv. ellers skal man ned til tinyint (1byte) Eller smallint som fylder 2 byte, her vil man måske styre et flag, 1 for update, 0 for insert, 2 for delete; ved at bruge char(1), U eller I eller D vil man spare 1 byte. (+ performance penalty ved joinet)
Igen så afhænger det af brugen, løsningen med U, I, D, landekoder mv. vil være nemmere at læse efter alle har glemt betydningen af 0, 1 og 2 osv. eller skal til at lave et yderligere join.
Men igen Andreas... som budskabet er i denne tråd, nemlig "it depends!"
-> #14 Ja, det er jeg enig i, i de specielle situationer :) Men jeg ville aldrig joine noget på en varchar, med mindre det var en _meget_ specifik situation. Men ja, det kan være anderledes afhængigt af omstændighederne :)
Udover det fylder varchar(2) mellem 1 og 3 bytes, da det er en varchar (indeholder en ekstra byte, da den kan have en variabel længde, derfor vil den indholde mellem 0-2 bytes + 1 ekstra).
En char(2) fylder derimod altid 2 bytes (da den er fast defineret og derfor altid vil have en længde på 2, uanset hvad man putter i den).
Andreas, #12, pointsfordeling - det tillader Eksperten ikke i et hug. Du oprettede spoergsmaalet med 50 points, og det er alt hvad du (i foerste omgang) kan fordele.
Hvis du alligevel vil af med flere points (jeg siger ikke nej) saa synes udvejen at vaere at oprette et nyt spoergsmaal "Points til xxxx." Om det skriver FAQ dette:
"Hvordan giver jeg en anden bruger flere point?
Først skal vi have på plads at du ikke må udlove mere end 200 point for et spørgsmål, heller ikke fordelt over flere spørgsmål.
Metoden er forholdsvis simpel. Opret et nyt spørgsmål i samme kategori som det oprindelige spørgsmål og kald det "Point til [brugernavn]" hvor du erstatter [brugernavn] med navnet på den bruger du ønsker skal have point. Husk at skrive et link til spørgsmålet hvor du normalt skriver en længere beskrivelse af dit problem."
Synes godt om
Slettet bruger
01. april 2010 - 16:22#19
Syntes ikke jeg så nogle nævne det, men du kunne bruge MySQL's funktion Group_Concat() til at samle data fra en enkelt kolonne i én enkelt række. Har dog ikke sat mig helt ind i hvad det er du prøver på at opnå og hvilke kommentarer de andre er kommet med.
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.