Tutorials

Normalisatie

Een inleiding op

Pagina 1

Het datamodel.

De laatste tijd wordt er op phphulp veel gesproken over een goed datamodel. Hoewel voor de meeste kleine sites het datamodel van iets minder belang is, moet je er rekening mee houden dat je site ook wel eens groot zo kunnen worden. Dan is het bijzonder vervelend als jij je database behandeld hebt als een excel file, oftewel alles bij elkaar. Vanaf nu doen we dit anders.
Pagina 2

Waarom schrijf ik deze tut.

Eigenlijk heb ik maar een reden en dat is het feit dat er de laatste tijd zoveel over gesproken wordt dat het mij tijd leek dit te schrijven. Ik ga trouwens “maar” tot de derde normaalvorm. Volgens mij is dit in de meeste gevallen voldoende.
Pagina 3

In deze tut zal ik het volgende behandelen

Wat is normalisatie van een database
Wie heeft het bedacht
Waarom is het bedacht
Waarom is het handig voor mij
Pagina 4

Wat is normalisatie van een database.

Eerst een andere vraag: Wat is een database?
Een database is een verzameling gegevens welke middels onderlinge verbanden aan elkaar gerelateerd zijn.
Voorbeeld
Database fruit

Appel 		 	groen
Peer 			groen
Banaan			geel

Bovenstaande is een niet genormaliseerde zeer kleine database. Later kom ik op dit voorbeeld terug.
Pagina 5

de bedenker

De bedenker.
Er bestaat geen standaard om een database in een optimale vorm te krijgen. In 1970 werd Dr. E.F. Codd’s paper over “A Relational Model for Large Shared Databanks” gepubliceerd in Communications van ACM. Hierin introduceerde Codd het onderwerp data normalisatie. Later is Codd’s methode uitgebreid met een 4e en 5e normaal vorm. Dankzij Codd is er dus een algemene methode voor het normaliseren van databases welke bij navolging goed
ontworpen databases garandeert. Aangezien Codd’s methode sindsdien voor het
normaliseren van databases gebruikt wordt, zou men dus kunnen stellen dat Codds
methode een ongeschreven standaard is op dit gebied. Dit wordt zeker aannemelijk
gemaakt door het feit dat autohoriteiten op database gebied zoals Microsoft en
Oracle gebruik maken van de normalisatie methode van Codd.

Zoals uit bovenstaande blijkt gaat het normaliseren verder dan de 3e normaalvorm. Ik niet en dat heb ik al uitgelegd.
Bron: http://home.student.utwente.nl/s.p.ekkebus/portfolio/files/Paper_DB_normalisation.pdf
Pagina 6

Nu een veel belangrijker vraag

Waarom is de normalisatie bedacht. Zoals ik al eerder aangaf word de database vaak gebruikt als een veredelde spreadsheet. Dat is echter ver beneden de waardigheid van een database. Een database heeft namelijk behalve de gegevens, ook nog de mogelijkheid in huis de gegevens te bewaken.
Dat is de belangrijkste reden om te normaliseren.

Terug naar het voorbeeld van het fruit

Appel 	 		groon
Peer 			 groen
Banaan			geel

Zie je het verschil? De appel is groon geworden. Dat was met een goed datamodel niet gebeurt. Waarom zou je een appel de mogelijkheid geven een kleur aan te nemen welke niet eens bestaat?

Daarom hebben we nu 2 tabellen. 1 met fruit en 1 met kleuren.

Tabel fruit
Fruit_id    Fruit_naam Fruit_kleur_id
1            Appel             1       
2            Peer              1
3            banaan           2

Tabel kleuren
Fruit_kleur_id   Fruit_kleur
1                    Groen
2                    Geel
3                    Rood

Nu is het in ieder geval niet meer mogelijk voor een appel om groon te worden want die staat niet in het lijstje. Dit is een soort van constraint key. Deze keys zijn in de database wereld zeer geliefd. Mischien heb je wel eens de melding constraint key violation gehad. Bij zo'n melding beschermt de database de gegevens. Er wordt bijvoorbeeld iets weggegooid dat nog in gebruik is. Zie ook:
http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html
Pagina 7

2e reden

De 2e ook wel belangrijke reden is het feit dat een goed gemaakte database kleiner is dan een niet genormaliseerde database. Stel jij hebt een fruitwinkel en al je klanten wonen in Wijnjewoude.
Je wilt de klanten graag in een database met het adres van de klant zodat je de postduif er op af kunt sturen. Wat zou het nou jammer zijn als je het zo zou doen:

Naam	Voorletter	straat	           Nr	   Pc	       Plaats
Boven	  K	        Merkebuorren	 82	 9241GH	 Wijnjewoude

Er wonen namelijk ongeveer 2500 man in Wijnjewoude waarvan 200 aan de Merkebuorren. Dit houd in dat op de bovenstaande manier ik 2499 keer teveel de plaatsnaam in mijn database zet en 199 keer de straatnaam.

Dit is dus een beter idee.
Tabel klanten

Klant_id	Klant_voorlett	Klant_naam
1	           K	               Boven

Tabel adres

adres_id	plaats_id	straat_id	huisnummer
453	                1	       79000	        82


Tabel plaatsen

Plaats_id	Plaats_naam
1	           Wijnjewoude


Tabel straten

Straat_id	Straat_naam
79000	         Merkebuorren


Zoals je ziet is er geen relatie tussen de zeer gewaardeerde klant en het adres waar deze woont er moet dus nog een tabel komen.

Tabel adresklant

Klant_id	adres_id
1	           453


Een logische gedachte is om de straatnaam te koppelen aan de plaatsnaam. Dit is echter niet juist. De dorpstraat komt in praktisch alle plaatsen voor koppel je deze aan de plaatsnaam dan heb je weer dat een gegeven meerdere keren in je database voorkomt en dat willen we niet. De straat koppel je aan een adres. Een adres is uniek.
Pagina 8

de query

Zoals je ziet is het datamodel nogal veranderd. Nu ben je op het punt gekomen dat je de klanten database (bijna) niet verder kunt vereenvoudigen. Het doel van normaliseren is dat op het laatst elk gegeven maar een keer in de database voorkomt.

Als we nu het fruit er weer bijpakken:

Iemand koopt bij mij een appel.
Let op

Insert into verkopen
(fruit_id, fruit_aantal, klant_id, wanneer)Values(1,3,1,NOW())

Dat is een makkelijke Query en meer is er niet nodig voor je webshop.

Het uit de database halen van de gegevens gaat wat lastiger.
[code]
SELECT
a.klant_naam,
a.klant_voorlett,
b.adres_id,
b.huisnummer,
c.plaats_naam,
d.straat_naam,
e.fruit_naam,
e.fruit_prijs,
f.adres_id
FROM
Klanten AS a,
adres AS b,
Plaatsen AS c,
Straten AS d,
Fruit AS e,
Adresklant AS f
WHERE
f. Klant_id=a.klant_id
AND
c.plaats_id=b.plaats_id
AND
d.klant_id=a.klant_id
AND
f.straat_id=b.straat_id
AND
e.fruit_id=verkopen.fruit_id
AND
Verkopen.klant_id=a.klant_id
AND
Verkopen.waneer > een datum
/[code]
Hopelijk ben ik duidelijk geweest en snapt iedereen wat ik bedoel.
Reacties zijn welkom (leert iedereen weer van)

Klaasjan

Sorry voor de hoofdletters want ik werk in MS Word.
Ik heb de tut na gisteravond nog iets aangepast. Hopelijk klopt alles nog.

Reacties

0
Nog geen reacties.