Hoi Marc,
Dat is een hele wezenlijke vraag, en inderdaad een kernvraag als het gaat om databases. Het probleem ligt denk ik echter niet zozeer bij het bepalen van de relaties die je moet leggen, als wel bij de stap ervoor: hoe haal je uit een tabel de herhalende gegevensgroepen die niet afhankelijk zijn van de sleutel? Want dat is dus de moeilijkste stap. Ik zal het met een paar voorbeeldjes proberen uit te leggen.
Als basis neem ik eerst een bedrijf dat artikelen levert aan jouw bedrijf. Dan kun je een tabel maken waarin je begint met de leveranciergegevens (Naam, Adres, Contactpersoon) gevolgd door het Artikelnummer, Omschrijving, Kleur en Prijs. (Ik hou het bewust even simpel). Als je 20 artikelen moet invoeren, moet je 20 keer de leveranciergegevens invoeren, en 20 keer de artikelgegevens. Daarbij ga je vermoed ik al snel denken: waarom moet ik elke keer opnieuw dezelfde leveranciergegevens inkloppen; die héb ik toch al een keer ingevoerd? Die vraag zul je jezelf niet stellen als het om de artikelen zelf gaat; die vul je namelijk maar één keer in. Je kunt dus zeggen dat de artikelgegevens uniek zijn, en de leveranciergegevens herhalend. Daarbij loop je ook nog eens het risico dat de ene werknemer V & D intypt, de volgende V&D en de derde van de oude stempel is, en Vroom en Dreesmann inklopt. Alle drie dezelfde bedrijven hebben dan wél weer hetzelfde adres... D.w.z.: is Burg. Oudlaan hetzelfde als: Burgemeester Oudlaan? Kortom: de kans op afwijkende namen maakt het alleen maar lastiger om de gegevens op de juiste manier bij elkaar te houden.
Op zo'n moment moet je de tabel gaan splitsen in 2 tabellen: een tabel Leveranciers, en een tabel Artikelen. Beide tabellen krijgen een eigen sleutelveld op basis waarvan je de opgeslagen records uniek kunt identificeren. Een artikel krijgt dus een veld ArtikelNummer, en een leverancier een veld LeverancierID. De tabellen zijn nu genormaliseerd volgend de 1e normaal. De regel die hieraan ten grondslag ligt zegt namelijk: gegevensgroepen die niet afhankelijk zijn van de andere gegevens haal je weg uit die tabel en zet je in een eigen tabel. Leveranciers hebben niets met artikelgegevens te maken (leveranciers niet uniek in de tabel, en artikelen wel). Dus de leveranciers haal je er uit.
Alleen rijst dan de vraag: hoe ga je die gegevens koppelen?
Daar is het antwoord op dit moment nog niet op te geven, want er moet nog een belangrijke vraag worden gesteld, namelijk: heb je één leverancier, of meerdere? In het eerste geval is het simpel: zet in de tabel Artikelen ook een veld LeverancierID en vul per artikel het betreffend LeverancierID in. Omdat een leverancier meerdere artikelen levert (zie hierboven) is het LeverancierID in de tabel Artikelen nooit uniek. Je krijgt dus een één-op-veel relatie tussen Leveranciers en Artikelen. Zou je het veld LeverancierID in de tabel Artikelen ook uniek maken, dan mag elke leverancier maar één artikel leveren, en dat schiet natuurlijk niet op.
Anders wordt het dus als je meerdere leveranciers hebt; dan gaat bovenstaand verhaal niet op (overigens denkt Microsoft daar anders over, maar ik wil het niet te ingewikkeld maken). Want als 4 leveranciers hetzelfde artikel kunnen leveren, dan heb je nog steeds maar één artikel dat je levert, maar heb je 4 leverancierID's die je moet opslaan. Wat ik dan vaak zie (ook hier op het forum) dat mensen dan maar 4 velden aanmaken voor een leverancierID. Dan kun je immers 4 leveranciers opslaan voor dat artikel.Probleem opgelost! Hoewel? Is dat wel zo? op het eerste gezicht kun je wel even vooruit, met je 4 leveranciers. Maar wat nu als je voor een specifiek artikel 6 leveranciers nodig hebt? Of, wat veel waarschijnlijker is, dat je 5 leveranciers hebt, die allemaal een andere prijs rekenen voor hetzelfde artikel? Je hebt maar één veld voor de prijs. Moet je dan nu ook 5 velden maken voor prijs?
Kijken we naar de volgende normalisatieregel, dan valt je op dat je nu niet te maken hebt met groepen gegevens die per record herhaald worden, zoals bij de leveranciers, maar per veld. Vijf velden voor leverancier, 5 velden voor prijs, en wellicht nog meer herhalende velden. Die extra velden zijn niet afhankelijk van het hele record, maar van een deel ervan, namelijk LeverancierID en van ArtikelID. Ook deze gegevens (die veel vervelender zijn voor een database dan de eerste variant) moeten dus de tabel uit, naar een eigen tabel. Die tabel zou je bijvoorbeeld Leverancier_Artikel kunnen noemen. Wat je hier in ieder geval in vastlegt is het LeverancierID en het ArtikelID, en de herhaalde velden. In het voorbeeldje hier is dat het veld Prijs, maar dat kunnen er dus meer zijn.
Waarom LeverancierID? Omdat je wilt vastleggen welke leverancier welk artikel levert. Waarom ArtikelID? Zelfde reden! Nu kun je een onbeperkt aantal leverancier en artikelen invoeren; elke combinatie van artikelnummer en leverancierID moet uniek zijn (elke leverancier mag elk artikel maar één keer leveren) dus de combinatie van ArtikelNummer en LeverancierID zou een goede sleutel kunnen zijn. En het veld Prijs gebruik je om voor elke combinatie een prijs vast te leggen.
Hoe ligt deze tabel nu in de relaties? Er is een één-op-veel relatie tussen Leveranciers en Leverancier_Artikel en tussen Artikelen en Leverancier_Artikel. Elke leverancier kan nog steeds veel artikelen leveren (net als in de situatie dat elk artikel maar één leverancier had) en elk artikel kan meerdere leveranciers hebben. Er is dus feitelijk een veel-op-veel relatie gelegd tussen Artikelen en Leveranciers: Veel leveranciers kunnen veel artikelen leveren, en veel artikelen worden door veel leveranciers geleverd.
Het is een beetje technisch verhaal, maar dat is het onderwerp nu eenmaal ook; ik hoop dat het wat duidelijker is geworden?