Goedemorgen,

Het EK is nog niet voorbij, en ik hou me alweer bezig met het WK (je kan nooit te vroeg beginnen). Ik was bezig om een WK poule te maken, en daarvoor wou ik eerst een goed speelschema opzetten. Hiervoor heb ik een databaseontwerp gemaakt, en vraag me af of dit een goede manier is.

PK = primary key
FK = foreign key

WK DATABASE

	- Team
		- team_id (PK)
		- naam_full
		- naam_short
		- website
		
	- Spelers
		- speler_id (PK)
		- voornaam
		- achternaam
		- geboortedatum
		- team_id (FK)
	
	- Doelpunten
		- goal_id (PK)
		- wedstrijd_id (FK)
		- speler_id (FK)
		- team_id (FK)
		- minuut	
		
	- Wedstrijden
		- wedstrijd_id (PK)
		- thuis_team_id (FK)
		- uit_team_id (FK)
		- datetime
		- stadion_id (FK)
		- type_id (FK)
		- scheidsrechter_id (FK)
		
	- westrijd_type (kwalificatie, groepswedstrijd, kwartfinale enz.)
		- naam
		- type_id (PK)
	
	- Stadion
		- stadion_id (PK)
		- naam
		- plaats
		- capaciteit
		
	- Poule 
		- poule_id (PK)
		- naam	
	
	- Scheidsrechter
		- scheidsrechter_id (PK)
		- naam
	- indeling
		- indeling_id (PK)
		- poule_id (FK)
		- team_id (FK)
		- indeling_type_id (FK)
		- continent_id (FK)
	- indeling_type
		- id (PK)
		- name (UNIQUE) (kwalificatie of eindronde)

	- continenten
		- continent_id (PK)
		- name (UNIQUE)
Dat mag, altijd interessant. Capaciteit is inderdaad een goede, maar nu niet van toepassing voor mij. En voor uitslagen heb je inderdaad wel alle doelpunten nodig.
Wel wat uitgebreider dan alleen de poule/wedstrijden. Is globaal de structuur die ik dus gebruik voor mijn eigen voetbal-website waarin ik al wel rekening hield met meerdere teams/competities/landen. Ook zitten er tabellen bij voor het bijhouden van een toto.

accommodatie
accommodatie_id
accommodatie_naam
accommodatie_opening

capaciteit
capaciteit_id
capaciteit_accommodatie
capaciteit_aantal
capaciteit_datumbegin
capaciteit_datumeind

adres
adres_id
adres_categorie
adres_wie
adres_straat
adres_huisnummer
adres_huisletter
adres_huisnummertoevoeging
adres_huisnummeraanduiding
adres_locatieomschrijving
adres_postcode
adres_plaats
adres_land

bond
bond_id
bond_naam_volledig
bond_naam_weergave
bond_landid
bond_datumoprichting

categorie
categorie_id
categorie_omschrijving

club
club_id
club_naam
club_naamsortering
club_datumoprichting
club_plaats
club_land
club_accommodatie

clubstraf
clubstraf_id
clubstraf_seizoen
clubstraf_wedstrijd
clubstraf_team
clubstraf_minpunten
clubstraf_reden

competitie
competitie_id
competitie_omschrijving
competitie_bondid
competitie_type

competitieseizoen
competitieseizoen_id
competitieseizoen_seizoen
competitieseizoen_competitie

contact
contact_id
contact_categoriewat
contact_categoriewie
contact_wie
contact_omschrijving
contact_geldig

contract
contract_id
contract_persoon
contract_club
contract_begindatum
contract_einddatum
contract_huur

foto
foto_id
foto_wie
foto_url

gebeurtenis
gebeurtenis_id
gebeurtenis_wedstrijdid
gebeurtenis_gebeurtenistypeid
gebeurtenis_positieid
gebeurtenis_teamid
gebeurtenis_persoon1
gebeurtenis_persoon2
gebeurtenis_minuut
gebeurtenis_volgorde
gebeurtenis_scorethuis
gebeurtenis_scoreuit

gebeurtenistype
gebeurtenistype_id
gebeurtenistype_omschrijving

indeling
indeling_id
indeling_seizoenid
indeling_teamid
indeling_positie
indeling_voorkeurstijd

land
land_id
land_naam
land_isonummer
land_iso2
land_iso3
land_fifa
land_ioc

logo
logo_id
logo_wat
logo_wie
logo_bestandsnaam

nationaliteit
nationaliteit_id
nationaliteit_persoon
nationaliteit_land

persoon
persoon_id
persoon_naam
persoon_voorvoegsel
persoon_voornaam
persoon_geboortedatum
persoon_geboorteplaats
persoon_landid
persoon_overlijdensdatum

positie
positie_id
positie_omschrijving
positie_afkorting
positie_afbeeldingid

seizoen
seizoen_id
seizoen_omschrijving
seizoen_datumbegin
seizoen_datumeind

selectie
selectie_id
selectie_seizoen
selectie_team
selectie_persoon

team
team_id
team_club
team_elftal

toto
toto_id
toto_omschrijving

totowedstrijd
totowedstrijd_id
totowedstrijd_wedstrijd
totowedstrijd_toto

uitslag
uitslag_id
uitslag_wedstrijd
uitslag_thuis_45
uitslag_uit_45
uitslag_thuis_90
uitslag_uit_90
uitslag_thuis_105
uitslag_uit_105
uitslag_thuis_120
uitslag_uit_120
uitslag_thuis_penalty
uitslag_uit_penalty

voorspelling
voorspelling_id
voorspelling_speler
voorspelling_totowedstrijd
voorspelling_thuis
voorspelling_uit

wedstrijd
wedstrijd_id
wedstrijd_soort
wedstrijd_seizoen
wedstrijd_ronde
wedstrijd_datum
wedstrijd_accommodatie
wedstrijd_thuisteam
wedstrijd_uitteam
wedstrijd_toeschouwers
wedstrijd_afgelast

wedstrijdsoort
wedstrijdsoort_id
wedstrijdsoort_omschrijving
Waarom een aparte tabel voor de uitslagen, dat is een overbodige 1 op 1 relatie met de wedstrijden.
@Ger Dat heb ik gedaan omdat niet elke wedstrijd een uitslag heeft (nog niet gespeeld, afgelast, uitgesteld) en ik het dan handiger vind om het in een aparte tabel te hebben staan (ook al is het dan misschien niet nodig)
Maar dan kan je die uitslag nog verder normaliseren, waardoor het zelfs nog een beetje nut heeft. Nu heb je uitslag 45, 90, 115, 120, penalties staan. Als je nu een extra veld hebt (zeg minuten) dan heb je alleen nog uit en thuis nodig en kan je meerdere records per wedstrijd hebben. Nu heb je voor verreweg de meeste wedstrijden een aantal lege velden (115, 120, penalties komen niet vaak voor).
@Jeroen,
Dat vermoeden had ik al maar strikt genomen is 'handiger' geen goed argument voor een 1 op 1 relatie tussen 2 tabellen. Het punt is dat je een extra join in de query krijgt, en dat kost perfomance.
@Erwin: Dat is inderdaad nog wat netter. Heb nu twee tabellen toegevoegd:
score
score_id
score_wat
score_wedstrijd
score_thuis
score_uit

scoretype
scoretype_id
score_omschrijving

waarbij ik in scoretype dan 45, 90, 105, 120 en penalties heb opgenomen
Voor de mensen die het nog niet gezien hebben, in de startpost vind je mijn databaseontwerp (nederlandse versie), nu heb ik een vraag over een query, wat is de beste manier om de gewonnen wedstrijden op te halen? Ik heb het volgende maar ik heb het idee dat het korter kan:


(
	SELECT 
		COUNT(matches.match_id) 
	FROM 
		matches 
	WHERE(
		matches.team_id_home = t.team_id
	AND (
		SELECT COUNT(goals.goal_id) 
		FROM	 
			goals 
		WHERE 
			matches.match_id = goals.match_id 
		AND
			goals.team_id = matches.team_id_home
		) > (
		SELECT 
			COUNT(goals.goal_id) 
		FROM 
			goals 
		WHERE 
			matches.match_id = goals.match_id 
		AND
			goals.team_id = matches.team_id_away
		)
	) OR (
		matches.team_id_away = t.team_id
	AND (
		SELECT 
			COUNT(goals.goal_id) 
		FROM	 
			goals 
		WHERE 
			matches.match_id = goals.match_id 
		AND
			goals.team_id = matches.team_id_home
		) < (
		SELECT 
			COUNT(goals.goal_id) 
		FROM 
			goals 
		WHERE 
			matches.match_id = goals.match_id 
		AND
			goals.team_id = matches.team_id_away
		)
	)		
) AS gewonnen_wedstrijden
Ik denk wel dat het wat korter kan, maar eerst even een vraag c.q opmerking:
Nu wil je het aantal gelijke spelen bepalen hoe maak jij het verschil tussen een 0-0 wedstrijd en een wedstrijd die nog niet is gespeeld?

Overigens zal bovenstaande query een foutmelding opleveren want je bent vergeten te joinen.
Ik heb het maken van de stand afgehandeld in PHP en niet SQL.
Ik haal eerst (per team van de poule) alle wedstrijden in de betreffende poule op. Vervolgens loop ik de wedstrijden door en verhoog per wedstrijd de tellers voor winst/verlies/gelijk (afhankelijk van resultaat) en ook het doelsaldo houdt ik dan bij.

Deze schrijf ik weg in een array die ik vervolgens sorteer op punten, wedstrijden, doelsaldo en naam.

Reageren