[MySQL] Foreign Key op tabel met meerdere regels

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Saeverix
  • Registratie: Maart 2002
  • Laatst online: 20-09 13:02
Ik ben met het maken van een webshop bezig, en zit op het moeilijkste punt: namelijk de database ontwerpen.
Ik wil gebruik maken van Foreign Keys, alleen loop ik tegen een onduidelijkheid aan.

Afbeeldingslocatie: http://emberapp.com/werner/images/sqleditor-1/sizes/m.png

U = Unique, P = Primary, F = Foreign ("orders_id" in de tabel "orders_content" hoort daar niet, is tijdens het tekenen per ongeluk blijven staan.)

In de tabel "orders_content" kunnen namelijk meerdere regels voor één bestelling komen. Dat is afhankelijk van het aantal bestelde producten.

Gaat het werken als ik zoals in het schema "orders_content_id" niet uniek maak en die gebruik als key?
Worden dan ALLE regels uit "orders_content" verwijderd zodra ik een order verwijder?

[ Voor 7% gewijzigd door Saeverix op 08-08-2010 19:42 ]

People who live in glass houses shouldn't throw stones.


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Elke primary key is tevens unique. ;)

Darnaast zou ik nooit iets als orders verwijderen, maar ze een bepaalde status of soft-deleted eigenschap geven.

{signature}


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Waarom heeft een order überhaupt een foreign key naar een orders_content? Orders_content heeft zelf een orders_id, het lijkt me dat dát de foreign key is die een orders_content aan een order koppelt. Het lijkt me verder ook onlogisch om een order te hebben die naar een orders_content verwijst die weer een ander orders_id heeft.

[ Voor 24% gewijzigd door .oisyn op 08-08-2010 18:55 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Saeverix
  • Registratie: Maart 2002
  • Laatst online: 20-09 13:02
Voutloos schreef op zondag 08 augustus 2010 @ 18:33:
Elke primary key is tevens unique. ;)

Darnaast zou ik nooit iets als orders verwijderen, maar ze een bepaalde status of soft-deleted eigenschap geven.
Je moet zo toch een keer verwijderen lijkt me. Anders krijg je verschrikkelijk grote databases.
Of is het een soort standaard om ze de status "verwijderd" mee te geven... Ik zie het nut er namelijk niet echt van in.
.oisyn schreef op zondag 08 augustus 2010 @ 18:50:
Waarom heeft een order überhaupt een foreign key naar een orders_content? Orders_content heeft zelf een orders_id, het lijkt me dat dát de foreign key is die een orders_content aan een order koppelt. Het lijkt me verder ook onlogisch om een order te hebben die naar een orders_content verwijst die weer een ander orders_id heeft.
Ja ik zie het nu ook, die staat verkeerd. Foutje tijdens het tekenen van de database. Die zit er oorspronkelijk niet in.



Mijn doel is dat ik tijdens het verwijderen van een order met één handeling ook automatisch alle bijhorende informatie uit andere tabellen verwijder.

Maar ik begrijp dan bovenstaand ontwerp niet gaat lukken. Is er dan een andere manier om dit wel te realiseren? Of zal ik de "orders_content" tabel met een losse query moeten bewerken als ik een order verwijder? Ook geen probleem, maar mijn gedachte was: 1 query is sneller dan 2 queries.

[ Voor 47% gewijzigd door Saeverix op 08-08-2010 19:56 ]

People who live in glass houses shouldn't throw stones.


Acties:
  • 0 Henk 'm!

  • cariolive23
  • Registratie: Januari 2007
  • Laatst online: 18-10-2024
Saeverix schreef op zondag 08 augustus 2010 @ 19:39:
[...]

Je moet zo toch een keer verwijderen lijkt me. Anders krijg je verschrikkelijk grote databases.
En wat is jouw definitie van "groot" ? Een database kan makkelijk vele TB's groot worden en vele miljarden records bevatten, dat hoeft echt geen probleem te zijn. Dat jij deze omvang wellicht niet meer kan bevatten, dat geeft niet, daarvoor schakel je nu juist een database in, die is daar voor gemaakt.

Dit leven ga je dus geen problemen meer tegenkomen, de kans dat jij met jouw bestellingen tegen capaciteitsproblemen aan gaat lopen, is nul komma niks.

Wanneer je constant 10 orders per seconde opslaat, heb je over 10 jaar net iets meer dan 3 miljard records in jouw tabel staan. Tegen die tijd ben je schatrijk en laat je iemand anders mogelijke problemen oplossen. Moraal van het verhaal: Ga geen problemen oplossen die je niet hebt, zonde van de tijd. Laat je data gewoon in je database staan, dan kun je er nog eens iets mee: Bijvoorbeeld de Belastingdienst blij maken met een correcte en vooral volledige boekhouding.

Acties:
  • 0 Henk 'm!

  • Saeverix
  • Registratie: Maart 2002
  • Laatst online: 20-09 13:02
En zoveel records in een database heeft geen nadelige gevolgen voor de snelheid?

Als dat niet zo is dan is het inderdaad makkelijker om de order status gewoon op 4 (Verwijderd/Verborgen) te zetten. Dan kan ik het hele Foreign Key verhaal laten varen.

People who live in glass houses shouldn't throw stones.


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Saeverix schreef op zondag 08 augustus 2010 @ 20:08:
En zoveel records in een database heeft geen nadelige gevolgen voor de snelheid?

Als dat niet zo is dan is het inderdaad makkelijker om de order status gewoon op 4 (Verwijderd/Verborgen) te zetten. Dan kan ik het hele Foreign Key verhaal laten varen.
Databases zijn juist otnwikkeld voor dit soort dingen dus een grotere database heeft maar een marginaal effect op de traagheid (afhankelijk van juist gebruik uiteraard). Mocht je order database echt zo groot worden dat de gemiddelde database omgeving het niet meer out of the box gaat trekken dan zullen de zaken ook wel zo goed gaan dat er een fatsoenlijke DBA-er ingehuurd kan worden.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Saeverix
  • Registratie: Maart 2002
  • Laatst online: 20-09 13:02
Haha ok. Dan is het duidelijk genoeg.

Ik vergeet het Foreign Key verhaal en markeer verwijderde bestellingen als Verwijderd.
Orders_content laat ik gewoon apart en bewerk ik met een eigen query.

Tenzij er nog iemand een betere manier weet, bedankt allemaal!

People who live in glass houses shouldn't throw stones.


Acties:
  • 0 Henk 'm!

  • Devil
  • Registratie: Oktober 2001
  • Niet online

Devil

King of morons

Ik zou het omdraaien. Geef orders_content een veld orders_id mee.
Orders_id verwijst naar de pk van orders.
Vervolgens kun je simpelweg al je producten ophalen via SELECT ... FROM orders_content WHERE orders_id = Het id van de order die je aan het ophalen bent.
Je haalt je order dan met 2 query's binnen. 1 op orders op de status op te vragen en 1 op orders_content met daarin een join op alle producten.

Je kunt het zelfs allemaal in 1 query prakken, maar dat wordt al snel onoverzichtelijk en met losse query's kun je beter gebruik maken van je indexen (en je hebt er minder nodig).

[ Voor 18% gewijzigd door Devil op 08-08-2010 22:44 ]

After all, we are nothing more or less than what we choose to reveal.


Acties:
  • 0 Henk 'm!

  • Saeverix
  • Registratie: Maart 2002
  • Laatst online: 20-09 13:02
Ja klopt, zo bedoelde ik hem ook. Dan doen we het dus gewoon op de oorspronkelijke manier die ik al had.

Zijn er situaties waar je wel gebruik moet maken van Foreign Keys? Het werkt toch alleen bij het verwijderen van een record?
Bij het ophalen van een record moet je toch een JOIN gaan gebruiken.

Of heb ik een verkeerde gedachte bij Foreign Keys?

[ Voor 93% gewijzigd door Saeverix op 08-08-2010 22:51 ]

People who live in glass houses shouldn't throw stones.


Acties:
  • 0 Henk 'm!

  • Devil
  • Registratie: Oktober 2001
  • Niet online

Devil

King of morons

Met een Foreign Key vertel je MySQL wat de relatie is tussen tabellen. Op die manier kan MySQL voor jou de consistentie van je database bewaken. Op het moment dat jij een ongeldige waarde in een FK veld probeert te inserten of updaten lukt dit niet en krijg je een foutmelding.
Voor wat betreft het deleten van records moet je bij het aanmaken van de FK aangeven wat MySQL er precies mee moet doen, want standaard staat dit op 'No Action'. Je kunt dan kiezen uit set default,set null, cascade en restrict. Wat jij bedoelt is 'cascade'.

Je datamodel moet dan wel perfect in elkaar zitten, want een klein foutje in de declaraties van de key's kan hele nare gevolgen hebben, omdat 1 delete een 'waterval' (cascade) van andere deletes in gang zet.

ps.
In je bovenstaande model is orders_content.orders_id een PK naar orders.orders_id als je dan in geval cascade een delete doet op je orders wordt orders_content ook gedelete, andersom niet. Op het moment dat je namelijk de orders delete dan staat er in orders_content.orders_id een waarde die niet meer bestaat en dat 'mag niet'.

[ Voor 18% gewijzigd door Devil op 08-08-2010 23:31 ]

After all, we are nothing more or less than what we choose to reveal.


Acties:
  • 0 Henk 'm!

  • Saeverix
  • Registratie: Maart 2002
  • Laatst online: 20-09 13:02
Ok volgens mij is het al aardig duidelijk. Maar werkt het dan ook met meerdere regels zoals die in orders_content kunnen voorkomen? Dat was de uiteindelijke vraag in dit topic.

Ik hoef het nu niet meer te gebruiken, maar het antwoord kan altijd nog eens van pas komen.

People who live in glass houses shouldn't throw stones.


Acties:
  • 0 Henk 'm!

  • cariolive23
  • Registratie: Januari 2007
  • Laatst online: 18-10-2024
Saeverix schreef op zondag 08 augustus 2010 @ 20:08:
En zoveel records in een database heeft geen nadelige gevolgen voor de snelheid?
Uiteraard heeft het aantal records invloed op de performance. Maar de invloed van een brakke query of een foute/ontbrekende index is vele malen groter. En deze kunnen al tot problemen leiden bij een minuscuul kleine database. Wanneer je meer wilt weten over de performance, zorg er dan voor dat je de ins en outs van jouw merk database kent en ga met EXPLAIN aan de slag. Zonder deze kennis blijft het giswerk en kun je nooit fatsoenlijk inschatten wat de performance gaat worden, laat staan zorgen voor een stabiele performance.
Als dat niet zo is dan is het inderdaad makkelijker om de order status gewoon op 4 (Verwijderd/Verborgen) te zetten. Dan kan ik het hele Foreign Key verhaal laten varen.
Waarom zou je nu in eens de FK's kunnen laten varen? Wanneer je een relationele database wilt maken, en daar lijkt het op, zul je FK's moeten gebruiken. Anders zijn er voor de database géén relaties aanwezig en degradeer jij jouw database tot een kladblok.

Acties:
  • 0 Henk 'm!

  • Devil
  • Registratie: Oktober 2001
  • Niet online

Devil

King of morons

Saeverix schreef op maandag 09 augustus 2010 @ 00:00:
Ok volgens mij is het al aardig duidelijk. Maar werkt het dan ook met meerdere regels zoals die in orders_content kunnen voorkomen? Dat was de uiteindelijke vraag in dit topic.

Ik hoef het nu niet meer te gebruiken, maar het antwoord kan altijd nog eens van pas komen.
Het werkt niet op de manier zoals het in jouw tekening staat. Een primary key is namelijk altijd uniek. In jouw voorbeeld kan er dus altijd maar 1 orders_content zijn.
Als je de pijl omdraait dus van orders_content.order_id -> orders.order_id dan kan het wel.
Elke orders_content verwijst dan naar 1 orders. Dus als die orders gedelete wordt worden alle bijbehorende orders_content ook gedelete (mits on delete cascade)

After all, we are nothing more or less than what we choose to reveal.


Acties:
  • 0 Henk 'm!

  • Saeverix
  • Registratie: Maart 2002
  • Laatst online: 20-09 13:02
Devil schreef op maandag 09 augustus 2010 @ 12:20:
[...]
Als je de pijl omdraait dus van orders_content.order_id -> orders.order_id dan kan het wel.
Elke orders_content verwijst dan naar 1 orders. Dus als die orders gedelete wordt worden alle bijbehorende orders_content ook gedelete (mits on delete cascade)
Oh dus in mijn geval moet ik het gewoon omdraaien.

Ik meende namelijk dat er alleen naar de Foreign Keys gekeken werd in de tabel waar je een record uit verwijderd. Maar volgens jou werkt het dus ook andersom?

"orders.orders_id" is dan de PK en "orders_content.orders_id" is dan de FK.
En werkt het dan ook voor meerdere regels?

Afbeeldingslocatie: http://emberapp.com/werner/images/sqleditor-2/sizes/m.png

Zo bedoel je het dan toch? (Heb voor het gemak alle overbodige kolommen weg gelaten.)

[ Voor 3% gewijzigd door Saeverix op 09-08-2010 20:09 ]

People who live in glass houses shouldn't throw stones.


Acties:
  • 0 Henk 'm!

  • bindsa
  • Registratie: Juli 2009
  • Niet online
Saeverix schreef op maandag 09 augustus 2010 @ 20:07:
[...]

Oh dus in mijn geval moet ik het gewoon omdraaien.

Ik meende namelijk dat er alleen naar de Foreign Keys gekeken werd in de tabel waar je een record uit verwijderd. Maar volgens jou werkt het dus ook andersom?

"orders.orders_id" is dan de PK en "orders_content.orders_id" is dan de FK.
En werkt het dan ook voor meerdere regels?

[afbeelding]

Zo bedoel je het dan toch? (Heb voor het gemak alle overbodige kolommen weg gelaten.)
Schrijf je verhaal eens op in pseudo code dan begrijp je het vanzelf:

- MySQL ziet dat jij record 12345 wilt verwijderen uit orders_content
- MySQL denkt 'oh, een foreign key naar orders, wat moet ik dan doen?'
- MySQL ziet 'on delete cascade'
- Dus delete MySQL uit de tabel orders het record/records waarbij orders_content_id gelijk is aan orders_content_id uit orders_content
- Terwijl MySQL dat record verwijderd ziet het dat er op orders_status_id ook een foreign key zit die ook op on delete cascade staat
- Dus gaat MySQL ook uit de tabel orders_status het record verwijderen waarbij orders_status_id gelijk is aan orders_status_id uit de tabel orders

Het antwoord op je vraag is dus ja ;)

Acties:
  • 0 Henk 'm!

  • jbdeiman
  • Registratie: September 2008
  • Laatst online: 08:59
Even terugkomend op de 1e opzet:
Wat is het voor online shop? Ik zie iets met kleuren staan, dus ik neem aan dat je zelf iets te kiezen hebt. Mocht color het enige zijn en je echt geen andere keuze hebben, kan dit prima, maar een tabel met de verschillende opties erin kan (voor onderhoud) wel eenvoudig zijn. (ivm het maar op 1 plek aan te hoeven passen van de kleur)
Daarnaast kan het in veel gevallen zo zijn dat je een product hebt die niet in alle "standaard" kleuren te leveren is.

Als je meer opties / keuzes hebt als klant, is het misschien handiger om een tabel te maken waarin je de verschillende keuzes opslaat en vervolgens de keuzemogelijkheden aan een product koppelt. Heb je meer vrijheid in je systeem.

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
L0calh0st schreef op maandag 09 augustus 2010 @ 20:17:
- MySQL ziet dat jij record 12345 wilt verwijderen uit orders_content
- MySQL denkt 'oh, een foreign key naar orders, wat moet ik dan doen?'
- MySQL ziet 'on delete cascade'
(op basis van laatste schema):
Nope, het is enkel in 1 richting. Indien de relatie ON DELETE CASCADE heeft, worden de order_content row(s) verwijderd als de order verwijderd wordt. Niet vice versa.

Dat zou ook niet wenselijk zijn, want dan krijg je een stom effect als iemand 1 dingetje uit z'n winkelwagentje knikkert. ;)

@jbdeiman: jep. En met enkel kleur als eigenschap ga je er niet komen. Zelfs van een blik verf kan je nog genoeg andere eigenschappen opslaan. :P

[ Voor 10% gewijzigd door Voutloos op 09-08-2010 20:50 ]

{signature}


Acties:
  • 0 Henk 'm!

  • Saeverix
  • Registratie: Maart 2002
  • Laatst online: 20-09 13:02
jbdeiman schreef op maandag 09 augustus 2010 @ 20:46:
Even terugkomend op de 1e opzet:
Wat is het voor online shop? Ik zie iets met kleuren staan, dus ik neem aan dat je zelf iets te kiezen hebt. Mocht color het enige zijn en je echt geen andere keuze hebben, kan dit prima, maar een tabel met de verschillende opties erin kan (voor onderhoud) wel eenvoudig zijn. (ivm het maar op 1 plek aan te hoeven passen van de kleur)
Daarnaast kan het in veel gevallen zo zijn dat je een product hebt die niet in alle "standaard" kleuren te leveren is.

Als je meer opties / keuzes hebt als klant, is het misschien handiger om een tabel te maken waarin je de verschillende keuzes opslaat en vervolgens de keuzemogelijkheden aan een product koppelt. Heb je meer vrijheid in je systeem.
Hoe bedoel je dat precies? Op dit moment kun je alleen kiezen welke kleur je wilt hebben. Dit gebeurt middels een dropdown box naast het te bestellen product. Dit zijn vooraf bekende kleuren. Via de admin kun je per product aangeven welke kleuren beschikbaar zijn.
Vervolgens zit er in de "products" tabel een kolom met daarin een string met bijvoorbeeld "1,2,4,6". Dat zijn de ID's van de kleuren uit de "colors" tabel.

Bij het weergeven van de producten die ik 1 query op de "colors" tabel en plaats die in een Array. Vervolgens explode in de "colors" string uit de "products" tabel en ga ik met een loop door de "colors" array om de dropdown box aan te maken.

Dat was de meest logische oplossing die ik kon bedenken. Misschien dat een ander brein met een andere gedachte een veel logischere en makkelijkere oplossing heeft. Dus ik zou graag weten wat jij in gedachte hebt.
L0calh0st schreef op maandag 09 augustus 2010 @ 20:17:
[...]
- MySQL ziet dat jij record 12345 wilt verwijderen uit orders_content
- MySQL denkt 'oh, een foreign key naar orders, wat moet ik dan doen?'
- MySQL ziet 'on delete cascade'
- Dus delete MySQL uit de tabel orders het record/records waarbij orders_content_id gelijk is aan orders_content_id uit orders_content
- Terwijl MySQL dat record verwijderd ziet het dat er op orders_status_id ook een foreign key zit die ook op on delete cascade staat
- Dus gaat MySQL ook uit de tabel orders_status het record verwijderen waarbij orders_status_id gelijk is aan orders_status_id uit de tabel orders

Het antwoord op je vraag is dus ja ;)
De bedoeling is dat ik alleen een record uit "orders" verwijder. Zodra ik dat doe zou hij de bijhorende records ook uit "orders_status" en "orders_content" moeten verwijderen.
Het verhaal wat ik van jou lees is dat je begint met verwijderen in "orders_content". Dat is juist wat ik niet handmatig wil doen.
Voutloos schreef op maandag 09 augustus 2010 @ 20:48:
[...]
(op basis van laatste schema):
Nope, het is enkel in 1 richting. Indien de relatie ON DELETE CASCADE heeft, worden de order_content row(s) verwijderd als de order verwijderd wordt. Niet vice versa.

Dat zou ook niet wenselijk zijn, want dan krijg je een stom effect als iemand 1 dingetje uit z'n winkelwagentje knikkert. ;)

@jbdeiman: jep. En met enkel kleur als eigenschap ga je er niet komen. Zelfs van een blik verf kan je nog genoeg andere eigenschappen opslaan. :P
Behalve dat zijn/haar uitleg verkeerd was werkt het wel op de manier die ik probeer te bereiken?

Met bovenstaande tekening in gedachte zou het volgende gebeuren als ik een record uit "orders" verwijder?
  • Record uit "orders" verwijderen.
  • Oh een record in "orders_status" die nu ook verwijderd kan worden.
  • Ah kijk eens, ook nog meerdere regels in "orders_content" die ik ook moet verwijderen.
Bovenstaande met de juiste ON CASCADE instelling natuurlijk...

[ Voor 61% gewijzigd door Saeverix op 09-08-2010 21:58 ]

People who live in glass houses shouldn't throw stones.


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Wat bevat order_status nou? Ik dacht eerst dat het een tabel met alle statuswaarden was, maar blijkbaar is het de status per order? Dan moet je juist in die tabel een order_id doen ipv andersom. Dan kan je dankzij de 1:N tenminste bijhouden wanneer de order van status veranderd is.

O enne, in een relationele db moet je niet zomaar 'ff makkelijk' een kolom met comma separated values stoppen. ;)

{signature}


Acties:
  • 0 Henk 'm!

  • jbdeiman
  • Registratie: September 2008
  • Laatst online: 08:59
Saeverix schreef op maandag 09 augustus 2010 @ 21:47:
[...]

Hoe bedoel je dat precies? Op dit moment kun je alleen kiezen welke kleur je wilt hebben. Dit gebeurt middels een dropdown box naast het te bestellen product. Dit zijn vooraf bekende kleuren. Via de admin kun je per product aangeven welke kleuren beschikbaar zijn.
Vervolgens zit er in de "products" tabel een kolom met daarin een string met bijvoorbeeld "1,2,4,6". Dat zijn de ID's van de kleuren uit de "colors" tabel.

Bij het weergeven van de producten die ik 1 query op de "colors" tabel en plaats die in een Array. Vervolgens explode in de "colors" string uit de "products" tabel en ga ik met een loop door de "colors" array om de dropdown box aan te maken.

Dat was de meest logische oplossing die ik kon bedenken. Misschien dat een ander brein met een andere gedachte een veel logischere en makkelijkere oplossing heeft. Dus ik zou graag weten wat jij in gedachte hebt.
Hierzo zit een ander brein in ;)

Ik werk ook best veel met databases en vaak is een koppeltabel een handigere oplossing. Ook dat is prima met één query eruit te halen, om de kleuren weer te geven. Je krijgt dan 1 extra tabel, maar dat is ook geen probleem voor een database. Voordeel van een systeem op een dergelijke (genormaliseerde) manier op te bouwen is dat je in de toekomst ook minder gauw met beperkingen van een eerder (puur voor die situatie) bedachte geschikte manier. De tabellen voor de producten heb je al, een tabel met de kleuren ook begrijp ik?
Je hebt dan een koppeltabel nodig: product_colors waarin je een kolom hebt voor product_id en een kolom voor color_id. In principe kan je het geheel van de kolommen dan als primary key gebruiken, omdat een bepaald product niet 2 keer een bepaalde kleur zal hebben als mogelijke eigenschap.

Voor een eventuele uitbreiding kan je aan zoiets dergelijks denken (er zijn meerdere opties mogelijk):
Tabellen: Property_names, Values, product_propertys
In property_names sla je de naam op van verschillende eigenschappen die een product kan hebben, bijvoorbeeld: kleur, maat of gewicht.
In Values geef je alle waarden in van alle property_names. Bijv "Rood", 46, "80 gram" (met de eenheden kan je ook weer verschillende mogelijkheden bedenken), maar je koppelt hier ook meteen de mogelijke waarden aan een eigenschap (property_name) in dezelfde tabel.
Vervolgens heb je al een lijst waarin je voor bepaalde producteigenschappen de mogelijke waarden hebt staan.
Enige wat dan nog overblijft is het koppelen van deze eigenschappen aan producten wat je in eenzelfde soort tabel doet als wat ik al eerder aangaf. Product-id, value_id

Je kan zo ook nog verder denken en de eigenschappen niet meteen aan het product koppelen, maar de producten categoriseren, en op die manier per productcategorie aangeven welke property_names daarbij mogelijk zijn. => Dit is dan weer eenvoudig voor de administratie. (je gaat bij een dvd niet de optie "kleur" tonen bijvoorbeeld, als je de eigenschappen wil vullen)


Een mooie regel is:
Laat je in de toekomst niet beperken door een snelle oplossing die je voor een bepaald probleem heb bedacht. Denk aan mogelijke uitbreidingen in de toekomst en probeer (redelijk, niet té!) generiek te werken. Daar heb je later alleen maar voordeel van.

[ Voor 4% gewijzigd door jbdeiman op 09-08-2010 22:44 ]


Acties:
  • 0 Henk 'm!

  • bindsa
  • Registratie: Juli 2009
  • Niet online
Voutloos schreef op maandag 09 augustus 2010 @ 20:48:
[...]
(op basis van laatste schema):
Nope, het is enkel in 1 richting. Indien de relatie ON DELETE CASCADE heeft, worden de order_content row(s) verwijderd als de order verwijderd wordt. Niet vice versa.

Dat zou ook niet wenselijk zijn, want dan krijg je een stom effect als iemand 1 dingetje uit z'n winkelwagentje knikkert. ;)

@jbdeiman: jep. En met enkel kleur als eigenschap ga je er niet komen. Zelfs van een blik verf kan je nog genoeg andere eigenschappen opslaan. :P
Sorry voor de verwarring ik ben in mijn verhaal uitgegaan van de openingspost en niet het schema wat later gepost werd. :? Maar de werking van ON DELETE CASCADE lijkt me inmiddels wel duidelijk.

Acties:
  • 0 Henk 'm!

  • cariolive23
  • Registratie: Januari 2007
  • Laatst online: 18-10-2024
;)
Voutloos schreef op maandag 09 augustus 2010 @ 22:39:
O enne, in een relationele db moet je niet zomaar 'ff makkelijk' een kolom met comma separated values stoppen. ;)
'ff makkelijk' wordt al snel ''héél lang héél erg moeilijk"...

CSV in je RDBMS gebruik je vooral om jezelf een oor aan te naaien en niet om een probleem op te lossen. En zolang je niet goed weet hoe je moet normaliseren en met fk's om moet gaan, blijf dan vooral van de uitzonderingen af, die ga je verkeerd toepassen waardoor je extra problemen in je systeem aanmaakt. En dat wil je echt niet, zonde van de tijd en frustratie.

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Saeverix schreef op maandag 09 augustus 2010 @ 21:47:

Met bovenstaande tekening in gedachte zou het volgende gebeuren als ik een record uit "orders" verwijder?
  • Record uit "orders" verwijderen.
  • Oh een record in "orders_status" die nu ook verwijderd kanmoet worden.
  • Ah kijk eens, ook nog meerdere regels in "orders_content" die ik ook moet verwijderen.
Bovenstaande met de juiste ON CASCADE instelling natuurlijk...
En als ik mag mierenneuken is het eigenlijk:


Record uit "orders" proberen te verwijderen.

Oh een record in "orders_status". Conflicterende FK Wat moet ik doen?

if (on cascade delete)
probeer ook order_status record te verwijderen
else
gooi dikke error en gooi helemaal niks weg. consistentie is heilig!

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • cariolive23
  • Registratie: Januari 2007
  • Laatst online: 18-10-2024
En hou ook nog even de deferrable FK constraints in de gaten, dan mag je tijdens een transactie de FK constraint overtreden en wordt deze pas bij de commit gecontroleerd. Je kunt "fout-situaties" dan tijdens de transactie oplossen, wat erg handig kan zijn.

MySQL ondersteunt dit trouwens niet, MySQL heeft wel de mogelijkheid om helemaal geen controles op FK's uit te voeren... Dat is dé manier om jouw database naar de bliksem te helpen, ondanks de FK's die je hebt aangemaakt.

Acties:
  • 0 Henk 'm!

  • Saeverix
  • Registratie: Maart 2002
  • Laatst online: 20-09 13:02
CSV in de database was inderdaad een dirty oplossing, maar hij werkte.
Op dat moment kon ik ook geen andere optie bedenken om in 1 record de opties van een product te zetten.

Als iemand me daarmee een stukje op weg kan helpen ben ik diegene zeer dankbaar.

@jbdeiman: Bedankt voor je uitgebreide verhaal. Zal er zo eens voor gaan zitten en het proberen uit te werken.

@ Alle anderen: Ook bedankt. Bij de grotere projecten (webshop in dit geval) kom je er al snel achter dat het ontwerpen van de database niet iets is wat je even op een namiddagje doet. Maar ik wist van te voren dat een goed ontworpen database het halve werk is, vandaar dat ik zeker wil weten of ik het goed doe.

Ik ga nu proberen met alle tips in dit topic mij complete database opnieuw uit te tekenen.

People who live in glass houses shouldn't throw stones.


Acties:
  • 0 Henk 'm!

  • Devil
  • Registratie: Oktober 2001
  • Niet online

Devil

King of morons

Saeverix schreef op dinsdag 10 augustus 2010 @ 11:07:
CSV in de database was inderdaad een dirty oplossing, maar hij werkte.
Op dat moment kon ik ook geen andere optie bedenken om in 1 record de opties van een product te zetten.

Als iemand me daarmee een stukje op weg kan helpen ben ik diegene zeer dankbaar.

@jbdeiman: Bedankt voor je uitgebreide verhaal. Zal er zo eens voor gaan zitten en het proberen uit te werken.

@ Alle anderen: Ook bedankt. Bij de grotere projecten (webshop in dit geval) kom je er al snel achter dat het ontwerpen van de database niet iets is wat je even op een namiddagje doet. Maar ik wist van te voren dat een goed ontworpen database het halve werk is, vandaar dat ik zeker wil weten of ik het goed doe.

Ik ga nu proberen met alle tips in de topic mij complete database opnieuw uit te tekenen.
Als elk product altijd een kleur heeft die gekozen kan worden dan maak je gewoon een extra tabel product_color als je meerdere opties wilt dan moet je met verschillende opties en koppelingstabellen gaan werken.

After all, we are nothing more or less than what we choose to reveal.


Acties:
  • 0 Henk 'm!

  • Saeverix
  • Registratie: Maart 2002
  • Laatst online: 20-09 13:02
Weten jullie misschien een Tutorial of How-to site die in gaat op Koppelingstabellen en alles daar omheen?

Ik heb deze gevonden: http://www.plus2net.com/sql_tutorial/sql_linking_table.php
Alleen kan nog niet helemaal inbeelden hoe dat zou werken in het geval van de kleuren voor mijn producten.

Of moet ik dan per product voor elke kleur een apart record toevoegen aan de link tabel?

Stel product1 heeft keuze uit 5 kleuren. En product2 keuze uit 10 kleuren.
Moet ik dan alleen voor die 2 producten al 15 records toevoegen aan de link tabel? Of zit ik nu compleet verkeerd te denken?

People who live in glass houses shouldn't throw stones.


Acties:
  • 0 Henk 'm!

  • cariolive23
  • Registratie: Januari 2007
  • Laatst online: 18-10-2024
Precies, je krijgt dan 15 records. En nee, dat is geen probleem, stelt niks voor.

Acties:
  • 0 Henk 'm!

  • Saeverix
  • Registratie: Maart 2002
  • Laatst online: 20-09 13:02
Dan zou de volgende database layout gaan werken?

Afbeeldingslocatie: http://emberapp.com/werner/images/sqleditor-4/sizes/m.png

Per product doe ik een query op "product_properties".
In de WHERE geef ik dan "product-id" en "property_name_id" (ID van property Kleur) mee.
In die zelfde query doe ik een JOIN op de tabellen "property_names" en "property_values".

Als ik dat zo lees zou het moeten gaan werken. Dat zou dan de vervanger zijn van de CSV entries in mijn records. Tenzij ik iets over het hoofd zie, of verkeerd doe.

edit:
Ik zie net in de phpMyAdmin van mijn host het volgende: InnoDB free: 87040 kB. Terwijl er vrijwel niets in staat. Ik gok de totale ruimte dan op 90 MB. Mocht dat bij de uiteindelijke host ook zo zijn dan lijkt het me beter om de oude orders WEL te verwijderen. De huidige host kost me dan ook maar 30 euro per jaar...

[ Voor 28% gewijzigd door Saeverix op 10-08-2010 15:04 ]

People who live in glass houses shouldn't throw stones.


Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 15:14

Creepy

Tactical Espionage Splatterer

Saeverix schreef op dinsdag 10 augustus 2010 @ 12:15:
Weten jullie misschien een Tutorial of How-to site die in gaat op Koppelingstabellen en alles daar omheen?
Zoek eens op "normaliseren".

"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


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Natuurlijk wel icm het sleutelwoord "database"

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • cariolive23
  • Registratie: Januari 2007
  • Laatst online: 18-10-2024

Acties:
  • 0 Henk 'm!

  • Devil
  • Registratie: Oktober 2001
  • Niet online

Devil

King of morons

Saeverix schreef op dinsdag 10 augustus 2010 @ 14:57:
edit:
Ik zie net in de phpMyAdmin van mijn host het volgende: InnoDB free: 87040 kB. Terwijl er vrijwel niets in staat. Ik gok de totale ruimte dan op 90 MB. Mocht dat bij de uiteindelijke host ook zo zijn dan lijkt het me beter om de oude orders WEL te verwijderen. De huidige host kost me dan ook maar 30 euro per jaar...
Mysql heeft altijd een bepaalde overhead vanwege zijn system tabellen. Ook als je database volkomen leeg is. In phpMyAdmin kun je per tabel zien hoeveel ruimte deze inneemt.
Als dat 0.5kb per record (inclusief indexes) is dan is dat fors. Zelfs dan passen er nog 16000 records in.
Ik heb hier een vergelijkbare webshop database met 2000 records en die is 500Kb groot.
Dus zoals al eerder gezegd, maak je vooral niet druk over dat soort dingen, want tegen de tijd dat ruimte of bandbreedte een probleem gaat worden kun je je wel meer dan 30 euro per jaar veroorloven ;)

After all, we are nothing more or less than what we choose to reveal.


Acties:
  • 0 Henk 'm!

  • Saeverix
  • Registratie: Maart 2002
  • Laatst online: 20-09 13:02
Hier ben ik weer even. Zit nog te stoeien met het database ontwerp.

Het "Property / Value met koppelingstabel" idee snap ik wel aardig. Alleen kwam ik op het volgende punt: Via de admin moet het mogelijk zijn om zelf Values toe te voegen/verwijderen. Ik moet dus per Property Name alle Values uit kunnen lezen. Daarom heb ik een veld aan Product_Values toegevoegd zodat ik kan zien bij welke Property_Name de values horen.

Tevens moet het zo zijn dat hij de Product Properties verwijderen zodra er een Value verwijderd wordt.
Voorbeeld:
  • Ik heb de property "Kleur". (Die zit als record in Property_Names).
  • In de Property_Values tabel zitten 4 kleuren/records: Rood, Groen, Blauw en Geel.
  • Op een product heb ik alle 4 kleuren toegepast. Er zitten dus 4 records in de Product_Properties tabel.
Nu moet het zo zijn dat als ik een Kleur verwijderen uit de keuze mogelijkheden (Property_Values) dat hij automatisch (Cascade) de records met de verwijderde kleur verwijderd van de producten (Product_Properties). Zodat er geen Kleuren bij het product blijven staan die er niet meer zijn.

Afbeeldingslocatie: http://emberapp.com/werner/images/sqleditor-5/sizes/m.png

Ik heb daarvoor gekozen voor een "1 on Many" relatie. Is dat juist? Heb ik mijn huiswerk goed gedaan?

People who live in glass houses shouldn't throw stones.


Acties:
  • 0 Henk 'm!

  • Saeverix
  • Registratie: Maart 2002
  • Laatst online: 20-09 13:02
Kan iemand me bevestigen of ik het goed door heb? Of dat ik nog volledig verkeerd zit?

People who live in glass houses shouldn't throw stones.


Acties:
  • 0 Henk 'm!

  • Devil
  • Registratie: Oktober 2001
  • Niet online

Devil

King of morons

Op zich klinkt het allemaal logisch. Het beste kun je gewoon even een test database maken en daar wat records in gooien. Dan kun je daar spelen met het oprvragen, editen en deleten van records en dan zie je precies wat er gebeurt en wat er eventueel anders moet.

After all, we are nothing more or less than what we choose to reveal.


Acties:
  • 0 Henk 'm!

  • Saeverix
  • Registratie: Maart 2002
  • Laatst online: 20-09 13:02
Dat is waar, ga ik dat eens ff doen. Dankje.

People who live in glass houses shouldn't throw stones.

Pagina: 1