login  Naam:   Wachtwoord: 
Registreer je!
 Nota's op tutorial:

Tutorials > MySQL > Complexe tabellen (koppelingen)
Pagina:

Reacties op de tutorial Complexe tabellen (koppelingen)


Offline  ikkedikke
Gepost op: 14 februari 2007 - 18:12
PHP expert

dit geeft niet echt de mogelijkheden van subqueries en joins. miss dat erin verwerken?

Offline  ranco
Gepost op: 19 december 2007 - 19:13
PHP gevorderde

"Koppeling: DJ's - genres"

Maak je in deze tabel een nieuw id aan?
Waarom? Een dj en genre kunnen gewoon beide als primary key geplaatst worden waardoor er geen uniek id bij verzonnen hoeft te worden.

Offline  Wim
Gepost op: 20 december 2007 - 00:15
Crew algemeen

Als je het met een webinterface update is het imo handiger. Je kan dan beide kollomen samen wisselen en je moet maar 1 post waarde meer meegeven: het ID

Offline  Thomas
Gepost op: 14 januari 2015 - 14:56
Moderator

Nu is deze tutorial al redelijk gedateerd, maar deze legt enkele fundamentele zaken niet (goed) uit. Het gebruikte voorbeeld is hier in principe prima geschikt voor, dus die zal ik aanhouden om e.e.a. toe te lichten.

Laten we bij het begin beginnen. Een partij (PartyCore.be) wil graag overzichten delen van feesten die zij (mede) organiseren, voor publiciteit en wellicht ook voor kaartverkoop et cetera. Deze feesten hebben een of meerdere muziekgenres. DJ's kunnen op deze fuiven optreden, en verzorgen dan muziek...

En dat is eigenlijk al iets dat ik hier mis: welke DJ's treden op op een fuif? Het zou logisch zijn dat als een fuif enkel het hardstyle genre heeft, dat dan een DJ (of meer?) aangetrokken wordt die bekend is met dit genre. Maar welke DJ's die iets met dit genre hebben treden dan op? Vast niet allemaal? Mogelijk ontbreekt er dus nog een koppeltabel fuif - DJ's. Dit wordt wel in de inleiding genoemd, maar deze tabel is dan even vergeten ofzo .

Maar dit is in zijn algemeenheid hoe je begint met het opstellen van een "complexe" database: je schrijft een lopend verhaal en probeert hier de verschillende "spelers" (entiteiten) te ontdekken (fuif, DJ, genre). Meestal verdienen de belangrijk(st)e entiteiten een eigen database-tabel.

Vervolgens ga je kijken naar de relaties tussen deze verschillende entiteiten. Daarbij kijk je ook naar hoe deze relatie er uitziet.

Bijvoorbeeld: elke DJ zal geassocieerd zijn met een of meer genres (hierbij gaan we er even van uit dat er geen DJ's zijn zonder genres). Dit wordt ook wel een een-op-veel relatie genoemd. De aanduiding van zo'n verhouding (een-op-een, een-op-veel, veel-op-een, veel-op-veel) wordt ook wel kardinaliteit genoemd. Kardinaliteit zegt iets over hoeveel (andere) entiteiten er aan een entiteit gekoppeld kunnen zijn. Dit kan je helpen bij het bouwen van je database-tabellen.

Heb je namelijk een een-op-een relatie, bijvoorbeeld in het geval waarbij een DJ altijd maar één genre zou draaien, dan zou je kunnen overwegen om (het id dat verwijst naar) dit genre op te nemen in de tabel met DJ-informatie. Je zou echter ook kunnen overwegen om uit oogpunt van flexibiliteit (uitbreidbaarheid) hier toch een koppeltabel voor aan te leggen.

Een koppeltabel wordt doorgaans gebruikt voor een-op-veel of veel-op-veel relaties. Tenzij er extra informatie aan gehangen wordt en de koppeltabel enkel gebruikt wordt om twee of meer tabellen (entiteiten) aan elkaar te knopen is het niet echt noodzakelijk om hier een extra id (primary key) aan te hangen. De opmerking van ranco hierboven is dus terecht. Aan de andere kant: de combinatie van verwijzingen naar entiteiten uit andere tabellen + extra informatie in een koppeltabel kan gezamenlijk een nieuwe entiteit vormen (dit is dus meer dan enkel een relatie) en dan is het wellicht wel verstandig om hier een primary key (PK) aan te hangen.

Het argument van Wim is niet echt valide want je bent zelden rechtstreeks de informatie van een relatie aan het editten, je edit meestal een van de entiteiten (bijvoorbeeld de DJ) en neemt daarbij de relaties mee (een multiselect formulier element voor de genres die de DJ eigen is).

Dan, bij het bijwerken van een entiteit en haar relaties, bijvoorbeeld de DJ's en de genres die deze draait, wordt meestal de koppeltabel leeggegooid en opnieuw gevuld. Dit is (een stuk) simpeler dan controleren of er al een relatie bestond tussen DJ en genre, en zoniet, dat je deze toevoegt. En omgekeerd, wanneer een relatie bestond maar nu niet meer, dat je die dan verwijdert. De koppeltabel (deels) opschonen en opnieuw vullen is echt vele malen simpeler. Dit garandeert ook dat een een-op-veel relatie uniek blijft binnen zo'n koppeltabel.

Ook kan het helpen bij het opstellen van zo'n database, naast het schrijven van een lopend verhaal, dat je een plaatje tekent van de tabellen en haar verbanden (en de kardinaliteit hiervan).

Dan nog een aantal andere zaken:
* In de code-voorbeelden wordt gebruik gemaakt van een template-engine en een database-laag. De code wordt daardoor nogal abstract. En zoals ikkedikke terecht opmerkt: het was wellicht een beter idee geweest om subqueries te gebruiken. Als je een SELECT-query in een loop ziet staan is er meestal iets niet helemaal in orde . (En als je dan toch een database-wrapper gebruikt had je hier toch ook wel een escape functie in op kunnen nemen die gebruik maakt van _real_escape_string()?)

* Wat ook HEEL ERG BELANGRIJK is is een consistente naamgeving van je tabellen en kolommen. Als je dit goed doet, wordt je database "zelf-documenterend": het is dan vrij snel duidelijk wat alles betekent en hoe de gegevens gerelateerd zijn.

Het grootste gemis van deze tutorial is echter het volgende: er komt geen enkele tabel-declaratie in voor en er wordt ook met geen woord gerept over welke STORAGE ENGINE wordt gebruikt. Dit bepaalt namelijk of je een echte relationele database gebruikt, of een collectie van tabellen die als los zand aan elkaar hangt. Omdat ik nergens iets zie staan over foreign keys vermoed ik dat de database van de auteur is opgezet met de MyISAM storage engine. In dit geval betreft het geen echte relationele database: MySQL weet dan niet dat kolommen in de koppeltabel echt behoren tot deze of gene tabel. Voor MySQL zijn dit gewoon kolommen met nummers en geen verwijzingen van foreign keys naar primary keys. Dit heeft ook tot gevolg dat er bij MySQL geen alarm zal afgaan als je iets in de gegevens verandert dat zou kunnen zorgen voor inconsistenties in je informatie.

Het liefst zou je deze beperkingen (constraints) die ervoor zorgen dat je data kloppend blijft in je database zelf aanbrengen en niet in je code. Je wilt namelijk (op zijn minst) dat de data in je database kloppend blijft. Deze beperkingen in (onder andere) de vorm van foreign keys kun je op je data aanbrengen als je gebruik maakt van het InnoDB database type. Als het belangrijk is dat je (overwegend administratieve) informatie onderling kloppend blijft, is het zeker de moeite waard om te overwegen om van deze storage engine gebruik te maken.

Alleen bij gebruikmaking van InnoDB heb je "echte" relaties tussen tabellen. Als je dan wijzigingen in de inhoud probeert aan te brengen die ervoor zorgen dat de geldende regels verstoord zouden worden dan zal MySQL hierover klagen en de wijzigingen niet doorvoeren. Als je gebruik zou maken van MyISAM tabellen dan klaagt MySQL hier niet over, dus tenzij je dan al die regels in je code zou hebben zitten zouden deze (foutieve) wijzigingen gewoon doorgevoerd worden.

Een ander middel wat verder bijdraagt aan het (onderling) kloppend houden van je database-informatie (dit wordt ook wel referentiële integriteit genoemd) is het gebruik van transacties. Een transactie zorgt ervoor dat een set van meerdere queries in zijn geheel wordt uitgevoerd, of in zijn geheel niet. Transacties worden ondersteund door InnoDB, maar (nog) niet door MyISAM.

Stel dat je gebruik maakt van MyISAM en je werkt het profiel van een DJ bij. Stel dat het bijwerken van het profiel van een DJ uit meerdere queries bestaat (wat niet geheel ondenkbaar is). En stel nu eens dat er halverwege deze bijwerk-operatie iets misgaat (PHP code crasht, een query gaat mis, whatever). Je informatie is nu voor de helft bijgewerkt en misschien heb je dit niet eens in de gaten omdat PHP/je databaselaag/je produktie-omgeving fouten onderdrukt. Je data is nu "corrupt". En misschien komt dit (veel) later pas naar buiten (en op een veel grotere schaal omdat ondertussen op die manier al een heleboel DJ profielen zijn bijgewerkt). Dit is iets wat je wilt vermijden. Vooral als je systeem vele malen complexer is dan dit. Bij de interactie met je database moet er dus ergens op een of andere manier een "waakhond" zijn die ervoor zorgt dat je gegevens kloppend blijven.

Zie ook: referentiele integriteit en kardinaliteit

Pagina:

Enkel aanvullende informatie is welkom. Geen prijzende of afkeurende reacties.
 
© 2002-2024 Sitemasters.be - Regels - Laadtijd: 0.029s