Normaliesierung
Hagen
- datenbank
0 Frank (no reg)0 Hagen
0 LeKuchen0 Ilja
Hallo,
es ist ein Freitag morgen und ich sitz hier bei meinem Praktikum und hab nix zu tun... deshalb wollte ich mal n bissel was für die grauen zellen tun und was "php-schustern". Hier mein gewähltes Problem-meine Ellis haben ne Gaststätte-es ist WM- und von UrKrostizer gibts son komisches Gewinnspiel-wer am besten beim tippen von ergebnissen ist kann ne Reise gewinnen oder so...
Nur ist das "Ausrechenprogramm" was die mitgeschickt habe besch... . Also sag ich "mutti ich bau dir n neues". Und da steh ich nun.
Zunächst will ich mich auf die Vorrunde beziehen:
Spieler können tippen für beliebige noch kommende Spiele, tipp richtig=3pkt.; Tendenz=1pkt; sonst 0;
Es wurde auch schon getippt die alten Tipps müsste ich von hand nachtragen. oder halt dann über das Programme aber das ist erstmal egal.
Es soll immer eine Tabelle wer gerade führend ist zu sehen sein.
Nun gehts mir um die Tabellenstruktur und wie sie am sinnvollsten wäre, dabei würde ich mich gern an die "Normalisierungsregeln" halten ums wenigstens einmal richtig zu machen, meine IDEE:
1. TAB: Spieler
ID NAME PUNKTE
2. TAB:Spiele
ID MANNSCH1 MANNSCH2 TORE1 TORE2
3. TAB:Tipps
SPIELID SPIELERID TIPPTORE1 TIPPTORE2
So nun meine Frage wie ließe sich diese Tabelle normaliesieren?
Soweit ich das sehe ist die 1NF erfüllt. alle Einträge wären "ATOMAR". 2NF: Seh ich schon in der ersten Tabelle ein Problem PUNKTE ist nicht von NAME abhängig sondern würde eher in TAB 3 passen?
Naja schonmal vielen dank für eure Tipps...
MFG HAgen
Hallo,
du könntest die Mannschaften in eine eigene Tabelle normalisieren,
also:
Tab "Mannschaft"
Id, Name
---------
1, Schweiz
2, Trinidad & Tobago
3, Vietnam
Tab "Spiel"
Id, Mannschaft1Id, Mannschaft2Id
---------------------------------
1, 1, 2
2, 1, 3
3, 2, 3
Da zum Glück pro Partie nur 2 Mannschaften gegeneinander spielen,
gibt es definitiv keinen realen Nutzen Tipps sowie Spielergebnisse
in eine vertikale Ausrichtung (Zeilen statt Spalten) zu bringen.
Für eine Auswertung mit dem Mannschaftsnamen müsstest du dann
allerdings die Tabelle Mannschaften 2mal zur Tabelle "Spiel"
joinen.
Der Rest der Auswertung ist dann nur noch ein recht einfaches
"SELECT" mit ein paar arithmetischen Operationen hinsichtlich
der Tore.
Und [Punkte] ist sehr wohl von [Name] abhängig. Jeder Name kann
eine unterschiedliche Punktzahl haben.
Ciao, Frank
Hallo,
ja auf die sache mit den mannschaften bin ich grad auch schon beim ersten programmieren gekommen...
Danke für deine Antwort
MFG Hagen
Hallo Hagen,
Nur ist das "Ausrechenprogramm" was die mitgeschickt habe besch... . Also sag ich "mutti ich bau dir n neues". Und da steh ich nun.
Ich habe hier immer Freitags oder in der Mittagspause mit einem Kollegen in einem kleinen Wettbewerb ein WM-Tippspiel zusammengebastetlt: Er mit MySQL und PHP und meine Wenigkeit mit Access und ASP.NET.
Hier meine Lösung für die Datenbank:
Tab1: [teams]
teamabbreviation (PK)
teamname
[group]
[rank]
[lot]
Tab2: [games]
gameid (PK)
teamhome
teamaway
scorehome
scoreaway
addinfo
penaltyhome
penaltyaway
venue
gamedate
gameplayed
Tab3: [bets]
userid (PK)
gameid (PK)
bethome
betaway
points
[timestamp]
Aus den Tabellen läßt sich über Views und parametriesierbare Abfragen alles wunderschön herleiten. Einfachste Übung ist eine Punkterangliste:
SELECT users.userid, SUM(bets.points) AS points
FROM users LEFT JOIN tips ON users.userid=bets.userid GROUP BY users.userid ORDER BY SUM(bets.points) DESC
Für die Ausgabe der Gruppentabellen muss man etwas überlegen. Habe mehrere Views angelegt, um die siegreiche und unterlegene Mannschaft rauszubekommen, hier ein Bspl für die "hometeamwins":
SELECT gameid, teamhome, teamaway, scorehome, scoreaway, gameplayed
FROM games
WHERE (scorehome>scoreaway AND games.gameplayed=True)
Die Heim- und Auswärtssiege habe ich dann zu "wins" geuniont:
SELECT gameid, teamaway as winner, teamhome as looser, scoreaway as winnergoals, scorehome as loosergoals FROM awayteamwins WHERE gameid<49 UNION select
gameid, teamhome as winner, teamaway as looser, scorehome as winnergoals, scoreaway as loosergoals FROM hometeamwins WHERE gameid<49
Dann wieder eine Union wins, draws und losses zu "groupphasegames":
SELECT * FROM wins UNION SELECT * FROM losses UNION SELECT * FROM draws
Die daraus entstehende view kann man dann mit der TeamTab joinen zu "view_tablegoals":
SELECT teams.teamabbreviation, Count(groupphasegames.looser) AS numbergamesplayed, Sum(groupphasegames.winnergoals) AS goalsshot, Sum(groupphasegames.loosergoals) AS goalsconceded, ([goalsshot])-([goalsconceded]) AS goaldifference
FROM teams LEFT JOIN groupphasegames ON teams.teamabbreviation=groupphasegames.winner
GROUP BY teams.teamabbreviation
Dann benötigt man noch die Anzahl der Siege, Niederlagen und Unentschieden pro Team, zB:
SELECT teams.teamabbreviation, Count(wins.winner) AS numberwins
FROM teams LEFT JOIN groupphasegames ON teams.teamabbreviation=wins.winner GROUP BY teams.teamabbreviation
Daraus kann man sich wiederum die Punkte errechnen als "view_tablepoints":
SELECT teams.group, teams.teamname, teams.teamabbreviation, numberwins.numberwins, numberdraws.numberdraws, numberlosses.numberlosses, ((numberwins.numberwins*3)+(numberdraws.numberdraws*1)) AS points
FROM ((numberlosses INNER JOIN teams ON numberlosses.teamabbreviation = teams.teamabbreviation) INNER JOIN numberwins ON teams.teamabbreviation = numberwins.teamabbreviation) INNER JOIN numberdraws ON teams.teamabbreviation = numberdraws.teamabbreviation
ORDER BY ((numberwins.numberwins*3)+(numberdraws.numberdraws*1)) DESC
Und zum Schluss dann noch der Join zwischen den Views view_tablegoals und view_tablepoints....
Mit ein bisschen Nachdenken eigentlich ganz logisch...;o)
Gruß
LeKuchen
yo,
- TAB: Spieler
ID NAME PUNKTE
punkte hat schon mal gar nichts in keiner tabelle verloren, weil es sich hier um einen errechneten wert handelt. diese spalte fliegt also komplett raus und wird später durch einen einzigen select für alle spieler erzeugt. und da es ja grundsätzlich um die Liste geht, wer am besten getippt hat, kannst du dir die tabelle spieler auch ganz sparen und anstelle die ID als fremdschlüssel in der Tipp tabelle zu führen, schreibst du dort die klarnamen rein. somit haben wir uns schon mal eine tabelle komplett gespart. es sei den, du willst auch eine ausgabe haben für personen, die keinen tipp abgegeben haben. aber das würde irgendwie keinen sinn machen.
- TAB:Spiele
ID MANNSCH1 MANNSCH2 TORE1 TORE2- TAB:Tipps
SPIELID SPIELERID TIPPTORE1 TIPPTORE2
diese zwei tabellen brauchen wir wirklich, weil zwischen den beiden entitäten eine 1:n bezeihung besteht. anstelle der spielerid in der zweiten tabelle kommt dort der klarname der jeweiligen person rein. allerdings können wir uns heir auch die mannschaften sparen, wenn du nur die liste brauchst. was übrig bleibt ist folgendes.
tabelle spiele:
ID, Tore1, tore2
tabele tipps:
Tipper, spiele_id, tipptore1, tipptore2
wobei in der zweiten tabelle, tipper und spiele_id zusammen einen primary key bilden und spiele_id natürlich der fremdschlüssel auf die erste tabelle ist.
diese beiden tabellen mit den spalten reichen aus, um deine liste auszugeben.
Ilja