Avatar billede tanis13 Nybegynder
04. oktober 2011 - 19:47 Der 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.

Med venlig hilsen
Thomas
Avatar billede majbom Novice
04. oktober 2011 - 20:00 #1
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?
Avatar billede tanis13 Nybegynder
04. oktober 2011 - 20:01 #2
Ja synes det kunne være fedt både at trække statistik ud fra spilleren og holdet.
Avatar billede decoon Nybegynder
04. oktober 2011 - 22:00 #3
Hvad med at dele det "fuldstændigt" op? Tænker på:

Spiller(Id, navn, hold)
Hold(Id, navn, ligaid)
Liga(Id, navn)
Kamp(Id, hold1, hold2)
Maal(Id, KampId, SpillerId, Tid)
Kort(Id, Farve, Spiller, KampId)

Osv.? Bare et rigtigt hurtigt forslag. :)
Avatar billede tanis13 Nybegynder
04. oktober 2011 - 23:38 #4
Det lyder fornuftigt,
har også selv tænkt på dette, men hvordan forbinder man brugeren til et hold/kamp?
Avatar billede majbom Novice
05. oktober 2011 - 06:19 #5
-> #4 - går ud fra at du mener en spiller?

Kamp(Id, hold1, hold2)

hold1 og hold2 er id'et på

Hold(Id, navn, ligaid)

og på en spiller er hold også id'et på

Hold(Id, navn, ligaid)

(jeg ville så nok kalde hold1 for hold1_id og hold2 for hold2_id i kamp-tabellen og hold for hold_id i spiller-tabellen osv.
Avatar billede tanis13 Nybegynder
05. oktober 2011 - 11:26 #6
Hmm. Den fik jeg ikke helt fat på, hvordan du ville kæde spilleren sammen med et bestemt hold i kampen.

Hvor mange tabeller vil du samlet have?

Hold(id, navn)
Kamp(id,hold1_id, hold2_id)
Spiller(id, navn)
Avatar billede majbom Novice
05. oktober 2011 - 12:22 #7
du er nødt til at have hold_id med i spiller-tabellen også.

så relaterer de tre tabeller jo til hinanden
Avatar billede tanis13 Nybegynder
05. oktober 2011 - 12:27 #8
Jeg vil gerne have muligheden for atfå spilleren på flere hold.
Derfor tænker jeg måske en ekstra tabel til håndtering af dette.
05. oktober 2011 - 15:16 #9
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

Match
matchId, dato, sted, ..
1 13-7-2011 Odense
2 20-7-2011 Fåborg

Match-Team
mtId matchId teamId hjemme
1 1 1 ja
2 1 2 nej
3 2 1 nej
4 2 4 ja

player-Match
pmId, playerId, mtId, mål, gultkort, rødtkort
1 1 1 0 0 0
2 2 1 0 1 0
3 3 2 1 0 1

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
Avatar billede tanis13 Nybegynder
09. oktober 2011 - 22:00 #10
Hej Christian,

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?

Mvh
10. oktober 2011 - 05:51 #11
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.
10. oktober 2011 - 09:29 #12
Om igen - sidste linie i Match-Team tabellen skulle være 4 2 3 ja.
Avatar billede tanis13 Nybegynder
10. oktober 2011 - 11:41 #13
Alright.

Jeg forsøger lige engang at smide noget mere data op og lave et udtræk. Hæng gerne på, så accepterer jeg svaret straks.
Avatar billede tanis13 Nybegynder
10. oktober 2011 - 15:55 #14
Hej igen,

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.
Avatar billede tanis13 Nybegynder
10. oktober 2011 - 16:27 #15
kan se jeg har byttet rundt på [match_team] og [match_player]..
10. oktober 2011 - 16:59 #16
To spørgsmål retur:

a.  Hvordan vil du skrive det ud? I en tabel ved hjælp af html/php?  Såsom:

<table>
<tr><th>Match</th><th>Dato</th><th>Team hjemme</th>....</tr>
<tr><td>1</td><td>25:09:2011</td><td>Roskilde</td></tr>.....
</table>

eller hvordan?

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.
Avatar billede tanis13 Nybegynder
10. oktober 2011 - 18:55 #17
Hej,

a) ja vil printe det som html/php. F.eks:

#1 13/09-11 FCK (John, Hans) 5 - 1 Brøndby (Per, Claus)
#2 14/09-11 OB (Per, Hans) 1 - 1 AaB (John, Claus)
..osv...

Har også overvejet to queries, men ville forsøge i første omgang om det kunne lade sig gøre med en. Er bare ikke så skarp til JOIN.
10. oktober 2011 - 20:06 #18
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.

Fortæl mere.
Avatar billede tanis13 Nybegynder
10. oktober 2011 - 20:19 #19
Hej,

Meningen er ikke der skal være i alt 11-14 spillere på listen. Højst 1-2 John + Hans er 2 spillere.

Der vil højst være 4 spillere tilknyttet 1 hold.

Selve tabellen skal bruges til en Fifa turnering på computer, derfor ikke de 11 eller 14 spillere.

Giver det mening?

På længere sigt vil jeg også registrerer gule kort, røde kort mm.
10. oktober 2011 - 21:34 #20
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?
Avatar billede tanis13 Nybegynder
10. oktober 2011 - 21:46 #21
Hej,

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.
Avatar billede tanis13 Nybegynder
11. oktober 2011 - 09:43 #22
Hov kan se linket er forkert. Her er det: http://2mas.org/_fifa/_old/?page=matches.php
11. oktober 2011 - 11:31 #23
(Jeg kikker, men det er komplekst, så det tager nok nogen tid, måske i aften eller i morgen).
Avatar billede tanis13 Nybegynder
11. oktober 2011 - 15:18 #24
Det lyder godt. Tak :)

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.
11. oktober 2011 - 22:19 #25
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å.

Held og lykke med den videre udvikling.
Avatar billede tanis13 Nybegynder
11. oktober 2011 - 23:12 #26
Hej,

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!
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