Momenteel ben ik bezig een voetbal(statistieken) site te maken. Ik ben hier al een tijdje mee bezig en het vorderd gestaag, en ik vind het tijd geworden om wat commentaar te krijgen op wat ik tot nu toe gedaan heb.
GUI
Allereerst, de GUI (Graphical User Interface). Aangezien ik nog niet alles in XHTML en CSS heb staan, zullen jullie het moeten doen met wat screenshots. Ik zou graag willen weten wat jullie vinden van onder andere het kleurgebruik, positionering en algemene indruk. De 4 screenshots: klik #1 klik #2 klik #3 meest recente versie
De vierde afbeelding bevat nog een layer onder de footer, dit is een layer die bijvoorbeeld in de linker- of rechterbalk gepositioneerd kan worden.
Ik snap dat er nog vrij weinig content op de site te vinden is, maar dit komt later nog. Momenteel is elk commentaar op wat ik tot nu toe heb zeer welkom.
Data model
Natuurlijk hoort er een database achter een systeem als dit. Ik heb deze al ontworpen, volgens mij klopt 'ie aardig (qua normalisatie etc.). Voor het gemak heb ik even een schemaatje gemaakt: klik!
De veldtypes heb ik hier weggelaten (behalve bij Enumerated). Volgens mij zijn de types in orde, id's zijn INT, date(time) DATE(TIME) en verder nog vanzelfsprekende velden als title (VARCHAR) en content (TEXT).
Het gaat mij dus meer om het relationele gedeelte. Ook elk commentaar is hier welkom.
Het is een beetje lang verhaal geworden, maar ik hoop dat ik wat (beargumenteerde) commentaren binnenkrijg, zodat ik er wat mee kan. Voor een overzicht van het project zelf, check het eerste project op m'n site: klik!
Bvd!
Er zijn nog andere manieren om je database te optimaliseren, daarvoor hoef echt niet te denormaliseren.
Ik heb gisteren nog even aangetoond dat slimme queries een héél stuk sneller zijn! Wat normaal in 70 uur (!!!) werd ingevoerd, deed ik binnen 5 minuten.
Daarnaast zou je ook gewoon voor een snelle database kunnen kiezen, wanneer je voor MySQL kiest, kies je daar duidelijk niet voor. Een database die niet (goed) met multicore processors uit de voeten kan, daar heb je weinig aan wanneer je veel performance nodig hebt. Dat heeft niets met een datamodel te maken, dat is allemaal native performance.
Denormaliseren doe je pas wanneer je problemen hebt die niet op een andere manier zijn op te lossen. Dankzij de overvloedige aanwezigheid van onkunde, is het voor veel prutsers echter de enige oplossing/workaround, ze hebben geen idee hoe ze indexen, cache, etc. moeten toepassen.
Edit: En inderdaad, die presentatie gaat over een MySQL-database die niet vooruit is te branden. 8 cores, leuk en aardig, maar daar doet MySQL dus niets mee. 200 tot 300 connections? Dat wordt dus één grote rij wachtenden, daar kan MySQL namelijk niet goed mee uit de voeten.
Zie ook deze serie artikelen: Tweakers.net. Hier wordt hun zwaar geoptimaliseerde MySQL-database vergeleken met een eenvoudig opgezette PostgreSQL-database met dezelfde data. PostgreSQL rent rondjes om MySQL... Wanneer je de pgSQL-database dan ook nog eens gaat optimaliseren, dan wordt het verschil helemaal idioot groot. Maar goed, dan zul je even een DBA aan het werk moeten zetten, dat viel buiten de scope van hun tests.
Om te beginnen, iedereen bedankt voor de reacties.
Allereerst, zoals terecht opgemerkt, ben ik (veel) meer coder dan designer. Ikzelf vond de GUI er wel aardig uitzien, afgezien van de gradient, die beviel mij zelf ook niet. Mijn voornaamste inspiratiebron is hier te vinden. Ik zal er nog eens goed naar kijken, maar het blijft gewoon niet mijn sterkste kant.
@Robert_Deiman
Ik geef bij de competitie aan wat voor type de competitie is, met teamclubs of met nationale teams. Indien het type club 1 is, zal ik in PHP een JOIN maken met de tabel teams, anders met de tabel countries. Dat is het idee erachter.
EDIT: ik heb hier even over nagedacht, er komt dan een probleem met de FK op 'home' en 'away', deze verwijzen nu naar teams, maar dat klopt in sommige gevallen dus niet. Maar hier twee dezelfde tabellen voor één verschil maken staat me ook niet aan.
Die aparte tabellen voor status en formats zit inderdaad wel wat in, daar zal ik even naar kijken. Het competitiemodel ben ik zelf ook nog niet echt uit wat het handigst is, op het moment gaat het als volgt:
- een hoofdcompetitie wordt aangemaakt (bv. Champions League)
- childcompetities worden aangemaakt (bv poule A met type comp, semifinals met type knockout). Dit kan onbeperkt diep gaan.
@Hipska
Gisteren heb ik de event table sowieso al aan de lineup table gelinkt, immers een speler die scoort staat altijd in de lineup.
De mogelijkheid om bij te houden welke clubs een speler allemaal heeft gehad, is in dit model onmogelijk, ik houd per speler slechts bij wat de meest recente club is. Ik besef mij nu dat dit totaal niet past bij een statistiekensite, ik zal het vanmiddag aanpassen. De kolom 'tid' kan dan ook verdwijnen. De 'cid' naamgeving zal ik ook even aanpassen.
@Jurgen
Ik schaam het om te zeggen, maar ik heb het gewoon met Excel gemaakt:P. Aangezien ik recentelijk colleges Database op de VU heb gehad waar de opmaak er zo uitzag, heb ik dit overgenomen.
@Marien
Die 'portfolio'-website heb ik in één middag online geknalt, ik zou het inderdaad eens rustig over moeten lezen.
@pgFrank
Over PostgreSQL zit ik na te denken, ik ken de nadelen van MySQL. Desondanks houd ik het voorlopig bij MySQL, of ik zet beide databases naast elkaar om met beide compatible te blijven.
Wat betreft je datamodel, daar moet je nog wel even goed over nadenken. Zo heb je bijvoorbeeld een tabel 'substitutes', maar dit is eigenlijk ook gewoon een 'positie'. Ok niet in het veld, maar een bankzitter behoort ook tot het team.
In de lineups tabel heb je zeker een aparte tabel nodig voor de verschillende posities. Denk ook aan verschillende opstellingen (4-3-3, 4-4-2, etc) die je kunt spelen. Die mogelijkheid moet je zeker inbouwen.
Verder mis ik een tabel 'clubs'? Een team is vaak (maar niet per se) onderdeel van een club. Zo niet dan heb je dus bijvoorbeeld een competitie tussen nationale teams of bijvoorbeeld een competitie tussen vrienden teams. Dit bepaal je uiteraard niet via een kolom in de competities tabel, maar laat je afhangen van waar een team onderdeel van is.
Ook laat jouw huidige datamodel nog niet toe dat een speler in meerdere teams (e.g. club en nationaal) speelt. Een koppeltabel zul je hier echt nodig hebben.
Verder heb je ook nog geen rekening gehouden met transfers? Door eenvoudig in de koppeltabel van teams en spelers twee datumstempels op te nemen kun je precies zien wanneer een speler in een team kwam en wanneer hij eruit ging.
Ik heb even een opzetje gemaakt. Uiteraard zul je dit model nog verder aan willen passen en uit willen breiden met alle gegevens die jij erin wilt hebben, maar het geeft je een idee hoe je zoiets aan zou kunnen pakken.
doorgaans geld de vuistregel dat als je geen nerd bent met 2cm dikke glazen je gewoon moet normaliseren. Maar even zonder grappen:
Twitter is een zeer uitzoderlijk geval natuurlijk. De vrienden wisten van gekheid niet wat ze moesten doen, en dus hebben ze maar een ontzettend lelijke hack uitgevoerd zodat het ietsje sneller gaat.
Stellen het volgende:
Wanneer je erg veel joins nodig hebt om een factuur samen te stellen, en je hebt het erg vaak nodig, overweeg om het de dupliceren. Dupliceren wil zeggen: maak een kopie die snel toegankelijk is. Niet: defenestreer het hele idee van normalisatie. Dit zou bijvoorbeeld een kopie kunnen zijn waarbij aanpasseingen in het genormaliseerde model komen, en dat na het aanpassen er een gedenormaliseerde versie gemaakt wordt voor snelle(re) toegang. Een soort van hardcoded indexes.
Zulke grappen heb je natuurlijk niet nodig zolang je niet 100.000 bezoekers per dag hebt. En als je dat wel hebt, kan je eens na gaan denken over hoe je caching en dergelijke het slimst zou kunnen aanpakken.
Aanvulling op Arend: Dit gedenormaliseerde model laat je onderhouden door triggers vanuit het genormaliseerde model. Alle INSERT-, UPDATE- en DELETE-acties doe je op het genormaliseerde model en de SELECT's voer je uit op het gedenormaliseerde model. Mits je de juiste indexen en VIEW's hebt aangemaakt, kun je hier wel wat voordeel mee behalen.
Maar zoals je ziet, heb je nog steeds een genormaliseerde database nodig, die dwingt correcte data af. En dat is nog steeds één van de allerbelangrijkste functies van een database, je hebt namelijk helemaal niets aan een snelle maar onbetrouwbare database. En een gedenormaliseerd model leidt altijd tot onbetrouwbare data, je gaat data dubbel opslaan. Daar kunnen na updates dus verschillen in gaan ontstaan.
Ik heb het nog nooit nodig gehad en heb m'n databases toch al flink op hun donder gegeven. 1 grote complexe query kun je namelijk ook opknippen in meerdere eenvoudige queries. Met een paar simpele lusjes in een stored procedure kun je dan razendsnel dezelfde gegevens opvragen, maar dan ineens een stuk sneller. Tevens is het eenvoudiger te bouwen, ook de simpele ziel snapt het dan. Ik werk er niet voor niets mee... ;)
Aanvulling op Frank en Arend, zoiets maak je bijvoorbeeld door gebruik te maken van genormaliseerde tabellen en daar een view overheen te leggen. Deze view kan je materialized maken daardoor is hij net zo snel als een tabel. Je kan er voor kiezen dat te doen met een refreshrate van bijv 2 minuten waardoor die view elke twee minuten wordt bijgewerkt.
Als je dit ook nog doet op basis van een prebuilt table dan kan je ook nog de juiste index aanmaken en dergelijke. Veel sneller wordt het niet...
@TS
@pgFrank
Over PostgreSQL zit ik na te denken, ik ken de nadelen van MySQL. Desondanks houd ik het voorlopig bij MySQL, of ik zet beide databases naast elkaar om met beide compatible te blijven.
gebruik een databaseclass bijv PDO
Ik zelf werk momenteel aan webapplicatie op basis van een oracle database waarbij gegevens tabellen uit 4 verschillende databases middels een databaselink opgehaald worden. De gegevens staan binnen een seconde op je scherm waarvoor oracle denk ik ongeveer drie keer 7000 rijen door moet
@Klaasjan
Dat valt nog wel mee, ik ben nu bezig aan een systeem, waarbij *helaas gebruiken ze dan weer wel MySQL, omdat het systeem reeds bestond voor ik ermee ging werken, en ze dat graag zo houden* zo'n 50000 records doorlopen worden in 1 tabel, en ongeveer 10 keer zoveel in een daaraan gekoppelde tabel.
Deze tabellen zijn wel met indexen en dergelijke ge-optimaliseert.
Het betreft een tabel met alle mogelijke hypotheken hier in Nederland (worden ingelezen middels een csv bestand) en een andere tabel met de daarbij behorende rentestanden inclusief de gehele (bij ons bekende) rente historie.