Toon posts:

Normalisatie probleempje

Pagina: 1
Acties:
  • 152 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Ik zit met een probleem. Ik moet voor mijn werk een database opstellen, waarvoor ik eerst moet normaliseren. Ik heb een aantal maanden geleden een snelcursus gehad maar het lukt toch niet op de een of andere manier om het in access te laten werken. Ik denk dat ik een fout heb gemaakt in het normaliseren.
Ik heb hier 2 voorbeeld figuren opgesteld met fictieve gegevens. Wat doe ik precies fout?


figuur 1
code:
1
2
3
4
5
6
7
8
9
10
Ziektemelding op 23-5-2002

Personeelslid   Reden                       Verwachte hersteldatum
412 Jansen  Gebroken been                     1-4-03
702  Mariniers  Griep                            30-1-03
210  Pouwels    Overspannen 
518  Tiepenhoof Poliklinisch onderzoek          24-3-02
Etc..       
        
Totaal aantal meldingen: 23


figuur 2
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Personeelskaart

Personeelslid:                      412       Jansen
Afdeling:                           Adm        Administratie
Geboortedatum:                    2-2-56
Datum Periodiek onderzoek:       15-12-02
----------------------------------------------------------------
Ziekmeldingen

Van                   Tot                       Reden

30-1-94             15-2-94                      GNK              gekneusde enkel 
21-8-96             15-11-96                    ZWV             zwangerschapverlof
21-1-03                                          GBB               gebroken been
etc..



figuur 1 normalisatie

0 NV:
ZIEKTEDATUM (datum, RG(pers#,persnaam,reden, verwhersteldatum))

1 NV:
ZIEKTEDATUM (datum)
ZIEKTEREGEL (datum, pers#, reden, verwhersteldatum)

2 NV:
ZIEKTEDATUM (datum)
ZIEKTEREGEL (datum, pers#, reden, verwhersteldatum)
PERSOON (pers#, persnaam)

3 NV = 2NV
ZIEKTEREGEL (datum, pers#, reden, verwhersteldatum)
PERSOON (pers#, persnaam)

figuur2
0 NV

PERSOON (pers#, persnaam, afdcode, afdnaam, gebdatum, datumpo, RG(aanvdatum, einddatum, ziektecode, reden)

1 NV
PERSOON (pers#, persnaam, afdcode, afdnaam, gebdatum, datumpo, ziekte#)
ZIEKTE (pers#, ziekte#, aanvdatum, einddatum, ziektecode, reden)

2 NV
PERSOON (pers#, persnaam, afdcode, afdnaam, gebdatum, datumpo, ziekte#)
ZIEKTE (pers#, ziekte#)
PERIODE (ziekte#, aanvdatum, einddatum, ziektecode, reden)

3 NV
PERSOON (pers#, persnaam, afdcode, afdnaam, gebdatum, datumpo, ziekte#)
AFDELING (afdcode, afdnaam)
ZIEKTE (pers#, ziekte#)
MANKEMENT (ziektecode, reden)
PERIODE (ziekte#, aanvdatum, einddatum, ziektecode)

  • whoami
  • Registratie: December 2000
  • Laatst online: 11:20
Het werkt niet? Wat werkt er dan niet?
Zie ook hier:
Welkom in P&W -> Quickstart (update 2/10/2002)

Als je de moeite wilt nemen om uw ganse datamodel te posten, kun je toch ook nog vermelden wat je nu eigenlijk wilt bereiken, en wat er niet lukt.

https://fgheysels.github.io/


  • thomaske
  • Registratie: Juni 2000
  • Laatst online: 14-07 14:28

thomaske

» » » » » »

kleine aanpassing op figuur 2:
3NV:
PERSOON (pers#, persnaam, afdcode, afdnaam, gebdatum, datumpo, ziekte#)
AFDELING (afdcode, afdnaam)
ZIEKTE (pers#, ziekte#)
MANKEMENT (ziektecode, reden)
PERIODE (ziekte#, aanvdatum, einddatum, ziektecode)
3NV:
PERSOON (pers#, persnaam, afdcode, gebdatum, datumpo)
AFDELING (afdcode, afdnaam)
PERIODE (pers#, aanvdatum, einddatum, ziektecode)
MANKEMENT (ziektecode, reden)

Brusselmans: "Continuïteit bestaat niet, tenzij in zinloze vorm. Iets wat continu is, is obsessief, dus ziekelijk, dus oninteressant, dus zinloos."


  • Night-Reveller
  • Registratie: September 2000
  • Laatst online: 23-08 22:29
Ten eerste: Dat heb je netjes gedaan, goed nagedacht!

Ten tweede: Je hebt (IMO) een klein dingetje gemist in figuur 2, van 0e nv naar de 1e nv: In de tabel PERSOON heb je ziekte# laten staan, terwijl deze afleidbaar is middel de tabel ZIEKTE(pers#, ziekte#).
...
te laat, thomaske was me voor en heeft zelfs de tabel ziekte weggehaald.

Hitpoint, dan nog een kleine tip: de db moet de werkelijkheid weerspiegelen. Zodenkende weet je dat een ziekte over een periode gaat, dat je tegelijk meerdere ziektes onder de leden kunt hebben, en dat je vaker dezelfde ziekte kunt hebben, dus PERSOON (#pers) en ZIEKTE(#pers, ziektecode, startdatum, einddatum) en dan eventueel die ziektecode in een aparte tabel zetten met een PK erop.

[edit]
oops. loop ik mezlef tegen te spreken... je moet kiezen: óf startdatum, óf einddatum, óf allebei erbij als PK. Anders kan een persoon maar 1 keer verkouden worden in zijn leven :+

[ Voor 14% gewijzigd door Night-Reveller op 30-01-2003 13:45 ]


Verwijderd

Topicstarter
Moet ik dan ook aanvangsdatum of einddatum nog als sleutel maken? Nee toch??

  • whoami
  • Registratie: December 2000
  • Laatst online: 11:20
Ik gebruik zowiezo geen 'te gebruiken data' als primary key columns. Ik maak altijd liever zelf een extra veld (autonummering meestal) die ik dan gebruik als primaire sleutel.

https://fgheysels.github.io/


  • thomaske
  • Registratie: Juni 2000
  • Laatst online: 14-07 14:28

thomaske

» » » » » »

whoami schreef op 30 januari 2003 @ 14:06:
Ik gebruik zowiezo geen 'te gebruiken data' als primary key columns. Ik maak altijd liever zelf een extra veld (autonummering meestal) die ik dan gebruik als primaire sleutel.
Inderdaad, daar ben ik het mee eens!
het wordt dan zo:
PERIODE (ziekte#, pers#, aanvdatum, einddatum, ziektecode)
waarbij je pers#, aanvdatum en ziektecode als UNIEK definieert..

Brusselmans: "Continuïteit bestaat niet, tenzij in zinloze vorm. Iets wat continu is, is obsessief, dus ziekelijk, dus oninteressant, dus zinloos."


  • Night-Reveller
  • Registratie: September 2000
  • Laatst online: 23-08 22:29
whoami schreef op 30 January 2003 @ 14:06:
Ik gebruik zowiezo geen 'te gebruiken data' als primary key columns. Ik maak altijd liever zelf een extra veld (autonummering meestal) die ik dan gebruik als primaire sleutel.
Wat is de reden dat je dat 'liever' gebruikt? Die extra kolom voegt nl. niets toe en is in verband met normalisering niet nodig.

Ik vind het lelijk! (want al die ID kolommen zijn overbodig)

Hipoint: Als je het zonder ID-kolom doet, moet je wel aanvangsdatum (of einddatum, dat is arbitrair) meenemen als PK. Anders is (Jansen, verkouden, '01-11-02' '07-11-02') al aanwezig (PK!) als Jansen weer verkouden is: (Jansen, verkouden, '01-01-03' '07-01-03'). Jansen mag niet weer verkouden worden... :)

  • whoami
  • Registratie: December 2000
  • Laatst online: 11:20
[nohtml]
Night-Reveller schreef op 30 januari 2003 @ 14:57:
[...]


Wat is de reden dat je dat 'liever' gebruikt? Die extra kolom voegt nl. niets toe en is in verband met normalisering niet nodig.
Ik vind het lelijk! (want al die ID kolommen zijn overbodig)
Neen, die voegt idd niets toe. Die wordt enkel gebruikt als 'administratie' door de database.
Met de huidige opslagcapaciteit doet het er niet meer toe of een column nu overbodig is of niet in dit geval. Het is gewoon veel makkelijker en eenvoudiger om op die manier een record een uniek veld te geven.

Als je op die manier een PK aan een record geeft, dan is het imho ook sneller om een record adhv de PK terug te vinden. Een query op een numeriek veld zal nl. sneller gaan dan een query op een string-veld bv.

https://fgheysels.github.io/


Verwijderd

Topicstarter
Maar Night Reveller, kunnen er dan wel twee mensen ziek zijn geweest op dezelfde dag?

[ Voor 12% gewijzigd door Verwijderd op 30-01-2003 15:26 ]


  • Night-Reveller
  • Registratie: September 2000
  • Laatst online: 23-08 22:29
Verwijderd schreef op 30 januari 2003 @ 15:18:
Maar Night Reveller, kunnen er dan wel twee mensen ziek zijn geweest op dezelfde dag?
Misschien leg ik het verkeerd uit. Ik adviseer de volgende kolommen als PK te nemen: Persoon, ziektecode en aanvangsdatum. Zodoende zijn:
(Pietje, verkouden, '01-01-01', '02-01-01'),
(Puk, verkouden, '01-01-01', '02-01-01'),
(Pietje, AIDS, '01-01-01', '02-01-01'), ;(
(Puk, verkouden, '02-02-02', '03-02-02')
allemaal unieke records.

Er zullen zo geen unieke records worden toegevoegd:
Als de persoon én ziekte gelijk zijn, is de aanvangsdatum anders!
Als de persoon én aanvangsdatum gelijk zijn, is de ziekte anders!
Als de ziekte én aanvangsdatum gelijk zijn, is de persoon anders!
Dit rijtje klopt volgens mij ook met de werkelijkheid.

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 21-08 21:44

MBV

Alleen gaat zo wel je performance onderuit. en wil je ernaar verwijzen, heb je 3 kolommen nodig! maakt het niet echt overzichtelijk. Dit is inderdaad wel de schooloplossing.

  • Night-Reveller
  • Registratie: September 2000
  • Laatst online: 23-08 22:29
MBV schreef op 30 januari 2003 @ 16:01:
Alleen gaat zo wel je performance onderuit. en wil je ernaar verwijzen, heb je 3 kolommen nodig! maakt het niet echt overzichtelijk. Dit is inderdaad wel de schooloplossing.
psies, en daarom vind ik dit mooi.

Ernaar verwijzen zal nooit op alle drie de kolommen gebeuren. Zoals whoami al stelde: het zijn 'te gebruiken data' kolommen. Terug naar wat Hitpoint wil:
figuur 1. Een overzicht van ziektemeldingen van vandaag
figuur 2. Een personeelskaart van een meewerker

Ad1:
code:
1
2
3
4
5
6
7
8
9
Select 
    P.persnaam as Personeelslid, 
    M.reden, 
    Z.Hersteldatum as 'Verwachte hersteldatum'
from Persoon P 
    Inner Join Ziekte Z on P.Pers# = Z.Pers#
    Inner Join Mankement M on M.Ziektecode = Z.Ziektecode
where 
    date() between Z.Aanvangsdatum and Z.hersteldatum

Ad2:
code:
1
2
3
4
5
6
7
8
9
Select 
    M.reden, 
    Z.Aanvangsdatum as Van,
    Z.Hersteldatum as Tot
from Persoon P 
    Inner Join Ziekte Z on P.Pers# = Z.Pers#
    Inner Join Mankement M on M.Ziektecode = Z.Ziektecode
where 
    P.pers# = :Persooneelslid


Als de oplossing gekozen wordt met ID's moet je op exact hetzelfde aantal kolommen joinen. Je zal dan ipv een join op ziektecode, ID zien. Ja, nee das lekker duidelijk. Persoonlijk vind ik het zo erg overzichtelijk.

P.S. Ik zie nu ook dat je soms wil dat er geen einddatum opgegeven hoeft te worden. Dan is er geen keus en zal je hersteldatum niet als PK mogen gebruiken.

MBV: Wat performance betreft heb je wellicht gelijk, maar veel zal het nooit kunnen uitmaken. Ik werk nu op een Athlon 1200, en gebruik in mijn tabellen geen ID-kolommen (soms zelfs strings als PK!). In sommige tabellen zitten enkele 100K rijen en nooit duurt een query langer dan de irritatie-grens (dwz: het is snel!). Bovendien kan je altijd een nieuwe pc kopen of met indexen fine-tunen. Daarbovenop wil ik stellen dat performance iets is wat je áchteraf moet bijstellen, mocht het zo zijn dat er soms iets bóven de irri-grens valt. in 99 van de 100 gevallen is het toch snel genoeg zoder vooraf tijd te besteden aan performance. Zeker in dit stadium kan Hitpoint de extra complexiteit nog niet beheersen en heeft 'ie waarschijnlijk de tijd er ook niet voor.
In het stadium waar Hitpoint mee bezig is, moet hetgeen wat 'ie doet overzichtelijk en duidelijk voor hemzelf zijn.

[ Voor 25% gewijzigd door Night-Reveller op 30-01-2003 16:38 ]


  • Night-Reveller
  • Registratie: September 2000
  • Laatst online: 23-08 22:29
[off-topic]
Overigens vind ik dat de pc zelf mag uitmaken hoe hij de beste performance (indexen) kan creëeren. Hij is goed in rekenen, meer dan 1 miljard bewerkingen per seconde maar kan nog geen koe in een kameelspak onderscheidden van een kameel in een koepak. Als er 100K+ rijen in een db zitten ga ik niet doen of ik beter weet hoe extra performance behaald kan worden.
De mens (ik) ben goed in nadenken; waar haal ik de informatie vandaan, wie wil het hebben, waarom etc. Wat zijn overzichtelijke en handige reportjes voor de eindgebruiker, etc, etc. Hou het daarbij! Besteed al je aandacht waar jij goed in bent. Dus niet in stoer programmeren, maar in stabiliteit, consistentie en het belangrijkste: de eindgebruiker.

  • whoami
  • Registratie: December 2000
  • Laatst online: 11:20
Night-Reveller schreef op 30 januari 2003 @ 16:46:
[off-topic]
Overigens vind ik dat de pc zelf mag uitmaken hoe hij de beste performance (indexen) kan creëeren. Hij is goed in rekenen, meer dan 1 miljard bewerkingen per seconde maar kan nog geen koe in een kameelspak onderscheidden van een kameel in een koepak.
Tja, maar rekenen met integers / nummertjes gaat nog altijd sneller dan rekenen met strings.
Als er 100K+ rijen in een db zitten ga ik niet doen of ik beter weet hoe extra performance behaald kan worden.
Hier ga je toch een beetje in de fout. Hoe komt het dat bepaalde software sneller is dan andere programma's die net hetzelfde doen? Hier komt de toegevoegde waarde naar boven die een goede programmeur kan bieden. Het is de programmeur die ervoor kan zorgen dat zijn programma snel of sloom is.
De mens (ik) ben goed in nadenken; waar haal ik de informatie vandaan, wie wil het hebben, waarom etc. Wat zijn overzichtelijke en handige reportjes voor de eindgebruiker, etc, etc. Hou het daarbij! Besteed al je aandacht waar jij goed in bent. Dus niet in stoer programmeren, maar in stabiliteit, consistentie en het belangrijkste: de eindgebruiker.


Tja, hoe bekom je stabiele code? Door te weten waarmee je bezig bent. En door eventueel 'stoer' te programmeren. ('t is natuurlijk te zien wat jij verstaat onder stoer programmeren ;) ).

Over die primary keys. Die PK is gewoon nodig om een record uniek te kunnen identificeren, het is dus gewoon een 'administratie' column voor de databank. Of dat nu nietszeggende data is, of data die wel relevant is voor de eindgebruiker, dat is een persoonlijke keuze.
Zelf vind ik het beter dat je een extra id kolom gebruikt. Of jij nu joined op een id-kolom of op een datum kolom, dat maakt het er voor de gebruiker niet duidelijker op. Ik vind het gewoon duidelijker als ik iedere keer een id-kolom gebruik. (Het gaat trouwens sneller ook.)

Een nadeel van het gebruik van 'data-columns' als primary key is nu wel dat je problemen kunt hebben met het consistent houden van uw data.
Stel dat je in uw geval een data column, die ook dienst doet als PK wijzigt/updated, dan moet je ook alle velden die foreign key zijn voor die pk gaan updaten.

https://fgheysels.github.io/


Verwijderd

Topicstarter
Gelukkig alles werk zoals het moet :) Nog bedankt maar ik heb nu een ander probleempje met het maken van 2 query's.

Ik moet namelijk een query maken waarmee voor alle personeelsleden per personeelslid het totale aantal afwezigheidsdagen kan worden bepaald.

En een query met het aantal ziektedagen in het jaar 2002 met daar ook bij hoeveel ziekmeldingen dit betreft.

Ik heb neit echt een idee hoe ik hier en query van maak.
Ik weet wel zeker dat ik volgende week ff bij mijn baas aanklop en vraag of ik weer op cursus kan voor het maken van dit soort databases.

  • whoami
  • Registratie: December 2000
  • Laatst online: 11:20
[nohtml]
Verwijderd schreef op 31 januari 2003 @ 09:24:

Ik moet namelijk een query maken waarmee voor alle personeelsleden per personeelslid het totale aantal afwezigheidsdagen kan worden bepaald.

En een query met het aantal ziektedagen in het jaar 2002 met daar ook bij hoeveel ziekmeldingen dit betreft.
Je zult eens in een sql-manual moeten kijken naar de aggregated functions zoals sum, count, .... en naar de group by clausule...

Je zult mbhv een datum-functie het verschil moeten maken van de 'datum tot' en 'datum van' - ziekte, en per medewerker dan die aantallen gaan optellen:

code:
1
2
3
select sum ( datumtot - datumvan), medewerkernaam
from medewerker
group by mederwerkernaam

[ Voor 22% gewijzigd door whoami op 31-01-2003 09:29 ]

https://fgheysels.github.io/


  • Night-Reveller
  • Registratie: September 2000
  • Laatst online: 23-08 22:29
whoami schreef op 31 januari 2003 @ 08:41:
[...]
Een nadeel van het gebruik van 'data-columns' als primary key is nu wel dat je problemen kunt hebben met het consistent houden van uw data.
Stel dat je in uw geval een data column, die ook dienst doet als PK wijzigt/updated, dan moet je ook alle velden die foreign key zijn voor die pk gaan updaten.
[off-topic (nog één keertje dan)]
Ik klik "Cascade Update Related Fields" en "Cascade Delete Related Fields" aan bij een FK in SQLServer en dan gaat het updaten en deleten van de FK automatisch...handig!

[on-topic]
Ben een beetje brak, dus wat toegevelijker; Whoami, ik kan niet anders dan je (deels) gelijk te geven. Het is sneller, dat kan ik niet ontkennen. Overigens heb ik het nooit getest, dus ik weet niet hoeveel sneller, maar dat het sneller is, ok.

Hitpoint, kan je vertellen hoe je structuur er nu uit ziet? Kan je ook de verbeteringen en overwegingen daarbij aangeven? Dit vind ik nl altijd interessant, het maakt me niet uit wat je hebt gekozen, maar waarom. (Misschien zeik ik nu teveel (tis vrijdag)). Je bent nl goed bezig geweest met b.v. normaalvormen en ben benieuwd of de nieuwe structuur nog daaraan voldoet.

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 24-08 21:28

Creepy

Tactical Espionage Splatterer

Night-Reveller schreef op 30 januari 2003 @ 15:46:
[...]

Misschien leg ik het verkeerd uit. Ik adviseer de volgende kolommen als PK te nemen: Persoon, ziektecode en aanvangsdatum. Zodoende zijn:
(Pietje, verkouden, '01-01-01', '02-01-01'),
(Puk, verkouden, '01-01-01', '02-01-01'),
(Pietje, AIDS, '01-01-01', '02-01-01'), ;(
(Puk, verkouden, '02-02-02', '03-02-02')
allemaal unieke records.

Er zullen zo geen unieke records worden toegevoegd:
Als de persoon én ziekte gelijk zijn, is de aanvangsdatum anders!
Als de persoon én aanvangsdatum gelijk zijn, is de ziekte anders!
Als de ziekte én aanvangsdatum gelijk zijn, is de persoon anders!
Dit rijtje klopt volgens mij ook met de werkelijkheid.
Ik ben verkouden, heb hoofdpijn, nekklachten, m'n hooikoorts speelt ineens op, brak gisteren m'n been tijdens het wintersporten en dan heb ik ook nog een besmettelijke ziekte... eeeh... oops?

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney

Pagina: 1