04. oktober 2011 - 19:47Der er
25 kommentarer og 1 løsning
Opbygning af database til statistik af kampe
Hej Eksperter,
Jeg har knoklet det sidste stykke tid med at opsætte en mySQL database, men det er ikke lykkes mig at oprette den med normalisering af 3. grad og uden redundans.
Databasen skal bruges til en statistik-hjemmeside for fodboldkampe.
De tanker jeg har gjort mig angående opbygningen er følgende:
* Player (id, name, password) * Team (id, name, league) * Match (id, teamA, teamB) * PlayersInMatch (id, matchId, playerId, team)
Jeg synes ikke ovenstående virker logisk, men det er det bedste jeg er kommet frem med.
Meningen er at en kamp kan oprettes, hvor X antal spillere kan tilføjes til hvert hold. Dvs et hold kan have flere spillere.
Ud over selve kampene vil jeg gerne føre statistik på Gule kort, røde kort, mål scorer, straffe spark og lign.
Jeg har ikke kunne forbinde disse ting på en funktionel måde endnu.
Hvis der er nogen som har noget input eller ligger inde med en opbygget database vil jeg sætte stor pris på lidt hjælp.
altså bare antal gule kort, røde kort, straffespark osv. pr. kamp, eller hvordan? skal det også fremgå hvilken spiller der har fået kortet eller lavet straffesparket?
Jeg synes du er godt på vej med dine fire tabeller. Du tager højde for, at en player i tidens løb kan spille for forskellige teams.
Du kunne overveje at dele match tabellen op i en match tabel og en match-team tabel. I match tabellen får hver match en id, og du kan have felter for matchens dato, hvor den finder sted, o.s.v. hvem der er dommer, o.s.v. Match-team tabellen har to rækker for hver match, en for hvert team. Denne opdeling kan synes noget overdrevet, men så bliver det muligt at gemme oplysninger så som hvem der var holdleder for et team i en match, og om teamet spillede hjemme eller ude. Yderligere gør denne opdeling det mindre komplekst at holde rede på hvilke spillere der var på hvert team i hver kamp, og hvor mange mål og røde og gule kort hver spiller fik i de enkelte kampe. Såsom:
Player playerId navn password 1 Hans abd 2 Jens def 3 Knud ghi 4 Sven jkl 5 Bent mno
Team teamId, navn, league 1 KlubA LeagueK 2 KlubB LeagueF 3 KlubC LeagueM
Så der er spillet to kampe, den første mellem klubA, hjemme og klubB, den anden mellem klubA og klubC, hjemme. I den første kamp spillede Hans og Jens for klubA og Knud for klub B. Knud scorede et mål, de andre ingen (så det blev 0-1), og Jens og Knud fik henholdsvis et gult og et rødt kort.
Hvis du vil vide, for eksempel, hvor mange mål klubC har scoret i sæsonens løb spørger du:
SELECT COUNT(mål) FROM Team t JOIN Match-Team mt ON t.teamId = mt.teamId JOIN player-match pm ON mt.mtId = pm.mtId
Jeg har fået kigget dybere i kortene og tror faktisk dit forslag til opbygningen af databasen er den "rigtige" løsning. Jeg har hvertfald svært ved at se andre løsninger.
Dog har jeg lige et spørgsmål til player-Match tabellen. Kan det passe den ikke går op med hvordan du har forklaret kamp forløbet?
Jamen det glæder mig, at du kan bruge min foreslåede tabel struktur. Jeg tillader mig derfor at oprette dette som svar.
I Player-Match tabellen har jeg, af dovenskab, kun vist detaljer fra den første kamp (match-team id'en er 1 og 2 hvilket begge i Match-Team tabellen refererer til match 1), og naturligvis skulle der ikke kun have været henholdsvis 2 og 1 spiller men 13-14 spillere på hver side inklusiv udskiftningerne. Men jeg ser, at jeg har fyldt Match-Team tabellen forkert ud. Sidste linie skulle have været 4 2 4, således at i match 2 spiller klub 1, ude, mod klub 3, hjemme.
Hjælper det? Eller ser du andre problemer? I så fald fortæl.
Jeg tror jeg har bygget databasen korrekt op nu, men har nogle problemer ved udtræk fra den.
Har oprettet 6 databaser ud fra det som er skrevet @ #9:
[team_league] id name
[team] id name league_id
[player] id name password
[match] id date
[match_team] id player_id match_id goals
[match_player] id match_id team_id
Jeg prøver så nu at printe noget ala. følgende: <match id> <match date> - <team name> (<team players>, <team players>) vs <team name> (<team players>) - <team goals>:<team goals>
Jeg har forsøgt med noget JOIN, men har ikke kunne hitte den rette kombination.
b. Hvordan skal jeg forstå det med <team players>,<team players>...? Vil du på en række vise navnene på alle spillere på hvert hold? Det bliver en mega lang række og ikke særlig brugervenligt. Eller noget i denne 'henretning'?
Match Dato Team hjemme Team ude Mål : Mål 1 25:09:2011 Roskilde BK Bagsværd 3 1 Ole Bøg Hans Due Karl Thue Bo Riis ... ...
Hvis det er sådan noget som det sidste du vil have, så bliver det muligvis nemmest med to queries til databasen, først en query der finder match og team data, og så en query der for hver match finder spillerne frem. Du skal så nok loade resultaterne fra queryerne i nogle arrays og derfra formattere dem for tabellen. Jeg skal vende tilbage dertil når du fortæller mig mere om hvordan du gerne vil have det til at se ud.
Så må jeg lige stille endnu et spørgsmål: Hvem er John, Hans for FCK og hvem er Per, Claus for Brøndby, o.s.v.? Er det to tilfældige spillere af de 14-15 spillere (inklusiv udskiftninger) der har været på holdet i matchen? Eller hvad?
(Jeg kan ikke forestille mig at du vil vise #1 13/9-11 FCK (John, Hans, Søren, Nils, Jens, ..[15 navne]) 5 - 1 Brøndby (Per, Claus, Sofus, Anders, Tomas, .. [15 navne]). Det vil blive en meget lang linie, og i virkeligheden, udenfor test dataerne, vil spillere normalt have et længere navn bestående af et for og et efternavn.)
Målene er i match_player tabellen knyttet til players. Hvis du kun vil vise to af spillerne på hvert hold vil du sandsynligvis stadig vise alle målene, altså også mål scorede af spillere duikke viser.
Ok, hvis der er fire spillere tilknyttet et hold, hvor mange spillere vil du så vise? Alle fire? Eller kun to? Hvis kun to, hvordan vælger du så hvilke af de fire spillere du vil vise?
Nej alle de spillere som er tilknyttet Hold X i kampen mod Hold Y skal vises.
Dvs. hvis Hold X har 3 spillere og Hold Y har 1, så vises det f.eks. således: Hold X (spiller1, spiller3, spiller4) vs Hold Y (spiller2)
Giver det mening?
Har tidligere forsøgt at lave systemet men følte jeg for vild i opbygningen af databasen. Det skulle gerne blive noget ala http://2mas.org/_fifa/_old/?page=match.php som jeg forsøgte med på det tidspunkt.
Jeg prøver selv at sidde at rode med det. Tror sagtens jeg kan lave flere queries fra databasen og få det ønskede udtræk. Vil dog mene det burde kunne gøres på en simplere måde en at queue hver tabel som jeg "normalt" gør.
Jeg klarer ikke at fange dit ønskede output i et enkelt mysql query. Jeg tror det kan lade sig gøre af den der er klogere end jeg, men af tidshensyn bliver jeg nødt til at stoppe her og foreslå, at du, nu du har den rigtige tabelstruktur, får dine resultater udskrevet i php ved at hente dataerne i en serie mysql queries. Dit oprindelige spørgsmål gik på en database struktur normaliseret til 3de grad. Det mener jeg, at jeg har hjulpet dig med, så jeg håber du nu vil acceptere mit svar og lukke spørgsmålet. Det med at få en bestemt opstilling var egentligt et ekstra spørgsmål der gik udenfor det oprindelige spørgsmål.
Men jeg skal vise hvad jeg har rodet med i mysql. Måske kan du bruge det til at rode videre. Et kærne element er mysql funktionen GROUP_CONCAT(). (Den har jeg lært ar arne_v, tak hvis du læser med.) For eksempel hvis du har tabel Navne
id hold navn 1 1 Jens 2 1 Hans 3 2 Sven 4 2 Nils
så vil denne query
SELECT hold, GROUP_CONCAT(navn) AS navne FROM Navne GROUP BY hold
give dette resultat
hold navne 1 Jens,Hans 2 Sven,Nils
Jeg har forsøgt med denne query:
SELECT DISTINCT m.id, m.date, t1.name team1, GROUP_CONCAT(p1.name) player1, t2.name team2, GROUP_CONCAT(p2.name) player2 FROM match m JOIN match_team mt1 ON m.id = mt1.match_id JOIN team t1 ON mt1.team_id = t1.id JOIN match_player mp1 ON mt1.id = mp1.match_team_id JOIN player p1 ON mp1.player_id = p1.id JOIN match_team mt2 ON m.id = mt2.match_id JOIN team t2 ON mt2.team_id = t2.id JOIN match_player mp2 ON mt2.id = mp2.match_team_id JOIN player p2 ON mp2.player_id = p2.id WHERE mt1.team_id < mt2.team_id GROUP BY m.id
Den giver dette resultat:
id date team1 player1 team2 player2 1 2011-10-01 OB Jens,Jens,Hans,Hans Brøndby Bo, Bo, Nils, Nils 2 2011-10-11 KB Kaj,Kaj, Ole, Ole Frem Sven,Sven,Knud,Knud
Som du ser fordobler den navnene, og jeg har ikke nået at få det rettet, og heller ikke nået at få målene sat på.
Det er helt okay. Vi er bevæget os uden for det oprindelige spørgsmål :)
Jeg tror tabellerne er opsat helt korrekt, så det skal du selvfølgelig have point for.
Jeg prøver mig frem med det du er kommet op med - så kan det være jeg må stille et ekstra spørgsmål derefter.
Tak for hjælpen!
Synes godt om
Ny brugerNybegynder
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.