[mysql] enum of een join

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Het is volgens mij zo dat enum velden alleen door mysql gebruikt worden (en dat is niet voor niets zo). Echter weet ik niet wat slim is om te doen. Als ik van een bepaald produkt heel veel titels in een database heb en deze onderscheiden zich alleen door 4 kenmerken. De produkten moeten met verschillende kenmereken gecombineerd weergegeven worden. En de produkten moeten per kenmerk worden weergegeven.

Wat kan ik dan het beste doen, voor elk kenmerk een aparte tabel maken of 1 grote tabel maken en dan de kenmerken in een enumveld zetten.

Als ik voor de 4 tabellen ga, dan kan ik ze combineren dmv unions.
Als ik voor 1 tabel ga, kan ik ze apart weergeven door te selecteren op het enum veld.

Zelf denk ik eigenlijk dat ik het beste 4 tabellen kan maken, maar ik weet het niet zeker. De tabellen kunnen overigens vrij groot worden qua hoeveelheid rows.

Acties:
  • 0 Henk 'm!

  • Johnny
  • Registratie: December 2001
  • Laatst online: 16:59

Johnny

ondergewaardeerde internetguru

Mijn ervaring is dat het heel erg afhankelijk is van de kenmerken die je wilt gebruiken. Voor bijvoorbeeld een veld "geslacht met de opties man/vrouw/NULL weet je van tevoren dat er niet zo snel iets bij zal komen en kan je dus goed een ENUM-veld gebruiken. Voor bepaalde productkenmerken zal hetzelfde gelden terwijl anderen in de toekomst wel veranderen.

In theorie is het wel zo netjes om alles te normaliseren en veel tabellen te gebruiken, maar als je dan in de praktijk enorme queries krijgt met heel veel joins die er heel lang over doen heb je daar weinig aan. Je zou de complexiteit van je queries wellicht kunnen reduceren door een VIEW te maken van de gecombineerde tabellen waarmee je net kan doen alsof je maar één tabel hebt.

Aan de inhoud van de bovenstaande tekst kunnen geen rechten worden ontleend, tenzij dit expliciet in dit bericht is verwoord.


Acties:
  • 0 Henk 'm!

  • Dido
  • Registratie: Maart 2002
  • Laatst online: 19:00

Dido

heforshe

Ik kan je verhaal niet helemaal volgen (ik snap bijvoorbeeld bij God niet waar je opeens unions vandaan haalt), maar ik heb het idee dat je zoiets bedoelt:

tabel: Product
Product_id
type
kleur
smaak
klasse

tabel: Type
Type_id
Omschrijving

tabel: Kleur
Kleur_id
Omschrijving

tabel: Smaak
Smaak_id
Omschrijving

tabel: Klasse
Klasse_id
Omschrijving

Een andere (en dynamischer) mogelijkheid is om met een kenmerk-tabel te gaan werken en een koppeltabel te maken tussen producten en kenmerken. Dat is vooral handig als je later extra kenmerken wilt gaan toevoegen.

Wat betekent mijn avatar?


Acties:
  • 0 Henk 'm!

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Ik bedoel met de 4 kenmerken dat als je als kenmerk neemt "Smaak", dat je dan de waardes "vanille", "kamille", "banaan" en "aardbei" oid hebt. Ik zou dan bijvoorbeeld de volgende 4 tabellen krijgen:

vanilleprodukten
kamilleprodukten
etc...

In dit geval zou ik dan als ik de nieuwste 10 vanilleprodukten wil ophalen een simpele query krijgen op de vanilleprodukten tabel. Terwijl als ik ze combineer en enum velden gebruik moet ik een where smaak='vanille' doen.

En volgens mij is een index op een enum veld niet aan te raden, omdat ik in mijn geval maar 4 soorten heb.

Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Dat wil je toch niet in verschillende tabellen opslaan, maar juist in één tabel zoals Dido al voorstelt? Normaliseren heet dat.

Ik zou een koppeltabel maken waarin je de producten aan smaken koppelt, want waar ga jij een aardbei/banaan-milkshake in opslaan?

Ik zie verder het probleem met een index op een ENUM niet, want die wordt intern gewoon als een integer opgeslagen. Retesnel en prima indexeerbaar. Alleen oppassen hoe je de data selecteert ;)

[ Voor 26% gewijzigd door CodeCaster op 16-04-2009 10:28 ]

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 21:27

Creepy

Tactical Espionage Splatterer

Bij iets als smaak wat een kenmerk is van het product (en dus geen type product) is het onzinning om per smaak een extra tabel op te nemen. Je haalt nu echt twee verschillende dingen door elkaar. Je maakt alleen een extra tabel aan als de daadwerkelijk kenmerken (dus de velden in je tabel) ook daadwerkelijk verschillend zijn. Als er niet zo heel veel velden verschillend zijn dan heb je nog de optie om een type veld op te nemen en aan de hand hiervan te bepalen welke velden nu gebruikt worden.

Gebruik de oplossing van Dido of gebruik er een enum voor. Ikzelf heb een voorkeur voor de oplossing van Dido. Zo zit je niet vast aan eventuele limieten van een enum.

[ Voor 29% gewijzigd door Creepy op 16-04-2009 10:27 ]

"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!

  • Dido
  • Registratie: Maart 2002
  • Laatst online: 19:00

Dido

heforshe

Als je een tabel met vanilleproducten en een met aardbeiproducten hebt, en je gaat als kenmerk kleur toevoegen, dan heb je dus een tabel met blauwe vanilleproducten, een tabel met rode vanilleproducten, een tabel met blauwe aardbeiproducten en een tabel met rode aardbeiproducten.

En dan heb je maar twee smaken en twee kleuren. Ik neem aan dat wel duidelijk is waarom je geen aparte tabellen wilt hiervoor.

Een WHERE clause in een query is geen zonde, hoor. Dat is volkomen normaal gebruik van de mogelijkheden van SQL. Er is absoluut geen reden om je datanmodel te vern***en om een WHERE clause in je query uit te sparen. ;)

Wat betekent mijn avatar?


Acties:
  • 0 Henk 'm!

  • Johnny
  • Registratie: December 2001
  • Laatst online: 16:59

Johnny

ondergewaardeerde internetguru

RSD schreef op donderdag 16 april 2009 @ 10:17:
Ik bedoel met de 4 kenmerken dat als je als kenmerk neemt "Smaak", dat je dan de waardes "vanille", "kamille", "banaan" en "aardbei" oid hebt. Ik zou dan bijvoorbeeld de volgende 4 tabellen krijgen:

vanilleprodukten
kamilleprodukten
etc...

In dit geval zou ik dan als ik de nieuwste 10 vanilleprodukten wil ophalen een simpele query krijgen op de vanilleprodukten tabel. Terwijl als ik ze combineer en enum velden gebruik moet ik een where smaak='vanille' doen.
Op die manier aparte tabellen doen is een slecht idee, een enkele where toevoegen maakt is toch geen probleem?
En volgens mij is een index op een enum veld niet aan te raden, omdat ik in mijn geval maar 4 soorten heb.
Een ENUM is intern niet anders dan een 16-bit integer (getal) waarbij iedere mogelijkheid een eigen nummer heeft, een index er op is geen probleem.

Aan de inhoud van de bovenstaande tekst kunnen geen rechten worden ontleend, tenzij dit expliciet in dit bericht is verwoord.


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 21:34
Op de nodige verwarring over unions/joins/etc. na, heeft Johnny in zijn eerste reactie al het antwoord gegeven.

Een enum type of een enumeratietabel komt feitelijk op hetzelfde neer; in beide gevallen refereer je er aan met een getalletje. Het verschil zit 'm er in dat je mogelijke waarden ofwel in je schema vastlegt (en dus als onderdeel van de databasestructuur beschouwt) ofwel dynamisch toevoegt (en dus als onderdeel van de inhoud van de database ziet). De vraag wat het beste is, hangt er maar net vanaf over wat voor eigenschap je het hebt; bij normaal gebruik van een database verander je de structuur niet maar de inhoud wel.

Acties:
  • 0 Henk 'm!

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Okee, dat is duidelijk, ik meen eens gelezen te hebben dat het niet verstandig is om een index op een enum veld te plaatsen, maar dat is dus geen probleem ;-)

Acties:
  • 0 Henk 'm!

  • cariolive23
  • Registratie: Januari 2007
  • Laatst online: 18-10-2024
Let er wel op dat bij een ENUM geen enkele controle zit op de waarde en of deze waarde ook daadwerkelijk in gebruik is. Het is géén foreign key en je kunt dus zonder enig probleem een waarde uit een ENUM verwijderen, ook als deze nog in gebruik is. Jammer dat je dan een corrupte database oploopt, maar dat hoort nu eenmaal bij het gebruik van een ENUM in MySQL.

Een aparte tabel en een foreign key, is een veel beter idee met waardes die kunnen wijzigen. Bij 'man', 'vrouw' of de dagen van de week, mag je wel aannemen dat daar niet veel meer aan zal veranderen, maar andere gegevens kun je veiliger opslaan in aparte tabellen.

Acties:
  • 0 Henk 'm!

Verwijderd

Ik zou het persoonlijk zo dynamisch mogelijk houden, zodat je kenmerken e.d. makkelijk aan kan maken.

Waarschijnlijk zal het iets worden wat lijkt op:

code:
1
2
3
4
5
6
+----+----------------------+
| id | naam                 |
+----+----------------------+
|  1 | milkshake aardbei    |
|  2 | milkshake banaan     |
+----+----------------------+

code:
1
2
3
4
5
6
+----+---------------+
| id | naam          |
+----+---------------+
|  1 | kleur         |
|  2 | smaak         |
+----+---------------+

code:
1
2
3
4
5
6
7
8
9
10
+----+------------+---------+
| id | kenmerk_id | waarde  |
+----+------------+---------+
|  1 |          1 | groen   |
|  2 |          1 | geel    |
|  3 |          1 | rood    |
|  4 |          2 | banaan  |
|  5 |          2 | aardbei |
+----+------------+---------+
* kenmerk_id -> kenmerk(id)

code:
1
2
3
4
5
6
7
8
9
10
+----+------------+-----------+
| id | product_id | waarde_id |
+----+------------+-----------+
|  1 |          1 |         3 |
|  2 |          1 |         5 |
|  3 |          2 |         2 |
|  4 |          2 |         4 |
+----+------------+-----------+
* product_id -> product(id)
* waarde_id  -> waarde(id)


Kenmerken van een product ophalen:
SQL:
1
SELECT k.naam, kw.waarde FROM product_waarde pw LEFT JOIN kenmerk_waarde kw ON kw.id = pw.waarde_id LEFT JOIN kenmerk k ON k.id = kw.kenmerk_id WHERE pw.product_id = 1;


Zou moeten returnen:
code:
1
2
3
4
5
6
+----------+----------+
| naam     | waarde   |
+----------+----------+
| kleur    | rood     |
| smaak    | aardbei  |
+----------+----------+


even snel getypt... moet aardig kloppen, zo niet.. dan komt het wel aardig in de buurt denk ik. :+

* = foreign key

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Ik zie alleen de meerwaarde van de tabel product_waarde/kenmerk_waarde niet.

Je kunt in de tabel kenmerk_waarde toch ook gewoon meteen het product_id opnemen.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

Verwijderd

Woy schreef op vrijdag 17 april 2009 @ 15:56:
Ik zie alleen de meerwaarde van de tabel product_waarde/kenmerk_waarde niet.

Je kunt in de tabel kenmerk_waarde toch ook gewoon meteen het product_id opnemen.
Dat zou kunnen, maar dat zou betekenen dat er maar 1 product kan zijn met een bepaalde waarde. Als dat voldoende is dan zou het inderdaad in de tabel kenmerk_waarde erbij kunnen.

Had er nu meer aan gedacht dat je dan een selectie kon maken, dat de mogelijke waarde's vast stonden (net als in een enum).

@hieronder: helemaal goed verwoord O+

[ Voor 3% gewijzigd door Verwijderd op 17-04-2009 16:08 ]


Acties:
  • 0 Henk 'm!

  • Dido
  • Registratie: Maart 2002
  • Laatst online: 19:00

Dido

heforshe

Woy schreef op vrijdag 17 april 2009 @ 15:56:
Ik zie alleen de meerwaarde van de tabel product_waarde/kenmerk_waarde niet.

Je kunt in de tabel kenmerk_waarde toch ook gewoon meteen het product_id opnemen.
Maar dan kun je alleen gele milkshakes (kleur, geel) hebben, en geen gele koekjes. Tenzij je het redundant gaat opslaan.

Wat betekent mijn avatar?


Acties:
  • 0 Henk 'm!

  • susscorfa
  • Registratie: Augustus 2006
  • Laatst online: 11:13
Woy nu kun je meerdere kenmerken aan i product toekennen als ik eht voorbeeld goed begrijp maar volgens mij wil de topic starter dat helemaal neit

Acties:
  • 0 Henk 'm!

  • Dido
  • Registratie: Maart 2002
  • Laatst online: 19:00

Dido

heforshe

susscorfa schreef op vrijdag 17 april 2009 @ 16:08:
Woy nu kun je meerdere kenmerken aan i product toekennen als ik eht voorbeeld goed begrijp maar volgens mij wil de topic starter dat helemaal neit
Meerdere kenmerken wel (kleur, smaak).

Het nadeel is dat het lastiger wordt een check in te bouwen op meerdere kleuren. Je kunt je milkshake dus geel en rood maken als je niet oppast.

De flexible opzet is heel leuk, maar ik verwacht dat het een beetje overkill is voor wat de TS wil. Het maakt e.e.a. er in ieder geval niet overzichtelijker op :)

Wat betekent mijn avatar?


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
mmm, ja my bad.

Als je een beperkte set mogenlijkheden hebt, waar het in dit topic over gaat, is het inderdaad wel makkelijk met een extra koppel tabel. Ik zat meer aan een systeem te bedenken waar de gebruikers zelf ook nieuwe opties kunnen invoeren.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

Verwijderd

Dido schreef op vrijdag 17 april 2009 @ 16:11:
[...]

Het nadeel is dat het lastiger wordt een check in te bouwen op meerdere kleuren. Je kunt je milkshake dus geel en rood maken als je niet oppast.
Meerdere kleuren niet mogelijk maken is makkelijk op te lossen door kenmerk_id toe te voegen aan de arikel_waarde en een unique key toevoegen.
Woy schreef op vrijdag 17 april 2009 @ 16:13:
mmm, ja my bad.

Als je een beperkte set mogenlijkheden hebt, waar het in dit topic over gaat, is het inderdaad wel makkelijk met een extra koppel tabel. Ik zat meer aan een systeem te bedenken waar de gebruikers zelf ook nieuwe opties kunnen invoeren.
Dat kan nu ook, door een waarde toe te voegen aan kenmerk_waarde.

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Verwijderd schreef op vrijdag 17 april 2009 @ 16:18:
[...]
Dat kan nu ook, door een waarde toe te voegen aan kenmerk_waarde.
Ja het kan wel, maar wat is de toegevoegde waarde als je 10001 verschillende waardes er in hebt staan.

Stel je hebt iets van een profielen-site waar je dynamische properties nodig hebt, dan kan je wel alle waardes los bijhouden, maar 99% vult verschillende dingen in.

[ Voor 22% gewijzigd door Woy op 17-04-2009 16:24 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

Verwijderd

Woy schreef op vrijdag 17 april 2009 @ 16:23:
[...]

Ja het kan wel, maar wat is de toegevoegde waarde als je 10001 verschillende waardes er in hebt staan.

Stel je hebt iets van een profielen-site waar je dynamische properties nodig hebt, dan kan je wel alle waardes los bijhouden, maar 99% vult verschillende dingen in.
Oh zit weer verkeerd te lezen denk ik, bedoelde natuurlijk dat de beheerder het kan toevoegen. Maak zelf meer systemen waar de "gebruiker" meer de klant is, en geen profiel achtige dingen, dus vandaar... :)

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Verwijderd schreef op vrijdag 17 april 2009 @ 16:31:
[...]

Oh zit weer verkeerd te lezen denk ik, bedoelde natuurlijk dat de beheerder het kan toevoegen. Maak zelf meer systemen waar de "gebruiker" meer de klant is, en geen profiel achtige dingen, dus vandaar... :)
Ja een gebruiker is natuurlijk een nogal ruim begrip, waar inderdaad ook de beheerder onder valt ;)

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”

Pagina: 1