Veel verschillende producten met ieder eigen attributen

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • mcdronkz
  • Registratie: Oktober 2003
  • Laatst online: 16-04 12:44
Ik ben bezig met het modelleren van de databasestructuur voor een pricewatch-achtig product, maar dan voor de metaalbranche. Deze database bevat vele duizenden producten, ingedeeld in honderden productsoorten. Deze productsoorten hebben op hun beurt weer uiteenlopende attributen (producteigenschappen).

Wat is het meest geschikte ontwerp voor een dergelijke database?

De wensen/eisen zijn als volgt:
  • Onderhoudbaarheid is belangrijk
  • Performance is belangrijk
  • Meertaligheid is in de toekomst belangrijk
  • Gebruikers hoeven zelf geen productsoorten of attributen toe te voegen
  • Consistente/correcte attribuutnamen en waarden zijn belangrijk
  • Sommige attributen hebben meerdere waarden
  • Producten moeten eenvoudig met elkaar vergeleken kunnen worden, ongeacht de productsoort
M'n initiële gedachte was om een EAV-achtige structuur toe te passen, maar al snel bleek dat een dergelijke oplossing tal van nadelen heeft. Zo wordt het onmogelijk om te garanderen dat de database consistente data bevat.

Ik lees overal dat een aparte tabel per productsoort de voorkeur heeft. Ik zie de voordelen van een puur relationele structuur, maar is dit enigszins te onderhouden... Betekent dit dat er in Laravel (waarin de applicatie geschreven wordt) voor iedere productsoort een migration en model moet worden aangemaakt? Is dit een wenselijke situatie?

Beste antwoord (via mcdronkz op 29-08-2016 17:32)


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

mcdronkz schreef op zaterdag 27 augustus 2016 @ 22:29:
Ik ben bezig met het modelleren van de databasestructuur voor een pricewatch-achtig product, maar dan voor de metaalbranche. Deze database bevat vele duizenden producten, ingedeeld in honderden productsoorten. Deze productsoorten hebben op hun beurt weer uiteenlopende attributen (producteigenschappen).
Toevallig weet ik wel iets van de Pricewatch ;)

Wij gebruiken ook 'gewoon' een EAV-model. Productsoorten is daarbij losgetrokken en heet bij ons categorie. Die hebben een hierarchisch model (effectief een tree), overigens gewoon met een parentId-veld in de category-tabel.
Wat is het meest geschikte ontwerp voor een dergelijke database?
Ik zou er op voorhand rekening mee houden dat er niet één geschikt model is. Voor opslag, bewerken en tonen van specifieke productpagina's zal een RDBMS best goed werken (bij ons iig wel). Voor het doorzoeken, zeker zodra dat gefacetteerd moet (zie specificatie-filters in de PW) gaat een SQL-database niet goed werken.
Een ondertussen redelijk klassieke oplossing is om de data primair in je RDBMS op te slaan. Voor het efficient doorzoeken wordt het dan vaak gedenormalizeerd e.o.a. document database, vaak Elastic Search.
Onderhoudbaarheid is belangrijk
Hier zullen meerdere databasetypen geschikt zijn. Maar ik kan me voorstellen dat een klassieke RDBMS-aanpak icm EAV hier goed presteert.
Performance is belangrijk
De grootste performance-obstakel zal zijn zodra je de lijsten wilt kunnen doorzoeken of in lijsten specifieke attributen wilt tonen. Daar komt dan ook de combinatie met Elastic Search of een andere document store bij kijken.
Meertaligheid is in de toekomst belangrijk
Dan is het vooral verstandig dat je je attributen netjes normaliseert. Met name tekstuele attributen die voor meerdere producten gelden wil je zo min mogelijk herhalen. Door ze te normaliseren kan je eenvoudig extra vertalingen toevoegen.
Hier gaan veel NoSQL-stores onderuit doordat veelal verwacht wordt dat je de boel gedenormalizeerd opslaat. Een extra taal per attribuut wordt dan erg lastig, tenzij die database ook ondersteuning heeft voor een zekere mate van normalisatie.

In de RDBMS+ES oplossing zou je per taal een losse ES-collection kunnen bouwen en zo automatisch de juiste vertalingen hebben tijdens het zoeken.
Consistente/correcte attribuutnamen en waarden zijn belangrijk
Dat maakt kunnen normaliseren extra belangrijk :P
Sommige attributen hebben meerdere waarden
Dat zal je dan op voorhand in je EAV-model moeten meenemen. Zolang je geen unique constraint op de combinatie van product+attribuuttype zet, zou je dat gedrag vanzelf moeten krijgen :P
Producten moeten eenvoudig met elkaar vergeleken kunnen worden, ongeacht de productsoort
Dat is denk ik niet zo relevant voor de opslag. Uiteindelijk zit het er dik in dat je dat soort vergelijkingen toch wel in je applicatie moet doen, waarbij het dus vooral belangrijk je in memory makkelijk kan vergelijken (bijvoorbeeld door de attributen in een hashmap te stoppen). Hoe dat in een database opgeslagen zit is daar eigenlijk nauwelijks relevant voor.
Als je van plan bent vele producten met elkaar te vergelijken (bijv een lijstje met vergelijkbare producten), dan wordt het natuurlijk weer een ander verhaal. Maar daar hebben diverse databases dan weer wel ondersteuning voor, iig Elastic Search kent een 'more like this'-functie.
M'n initiële gedachte was om een EAV-achtige structuur toe te passen, maar al snel bleek dat een dergelijke oplossing tal van nadelen heeft. Zo wordt het onmogelijk om te garanderen dat de database consistente data bevat.
Maar is dat een onacceptabel probleem? De enige die volgens mij echt lastig is om te garanderen, is het garanderen dat een product alleen de voor dat type product bedoelde attribuut heeft. De beschikbare type attributen kan je domweg met een tabel vastleggen en via FK's forceren. De eventuele keuzeopties bij een attribuut kan je ook op die manier vastleggen (hoewel het afdwingen dat de keuzeoptie daadwerkelijk bij het type attribuut hoort wel weer lastiger is).
Ik lees overal dat een aparte tabel per productsoort de voorkeur heeft. Ik zie de voordelen van een puur relationele structuur, maar is dit enigszins te onderhouden... Betekent dit dat er in Laravel (waarin de applicatie geschreven wordt) voor iedere productsoort een migration en model moet worden aangemaakt? Is dit een wenselijke situatie?
Dat klinkt als een erg bewerkelijke manier van werken en met honderden productsoorten ook als een onaagename beheerstaak... Je moet dan sowieso database aanpassen bij elke nieuwe productsoort en/of elk nieuwe type attribuut. Ga er maar vanuit dat je attributen ook wilt kunnen toevoegen, aanpassen en verwijderen. En misschien wil je ook wel je producten zelf een keer aanpassen, dan moet je zelfs al die honderden tabellen modificeren.

Dit klinkt me in ieder geval niet beter dan de EAV-oplossing waarbij je je database 1x hoeft op te zetten en daarna vrijwel ongelimiteerd attributen en productsoorten kunt aanpassen of toevoegen.

[ Voor 4% gewijzigd door ACM op 28-08-2016 11:48 ]

Alle reacties


Acties:
  • 0 Henk 'm!

  • The Eagle
  • Registratie: Januari 2002
  • Laatst online: 22:33

The Eagle

I wear my sunglasses at night

Ik heb geen verstand van Laravel maar dit zou ik niet in een RDBMS oplossen. Kijk naar Bol of Amazon, wat zij in de webshops hebben staan is exact wat jij zoekt. Toevallig weet ik dat daar Hbase onder draait. En daar kan wat jij wilt allemaal prima mee :)

Al is het nieuws nog zo slecht, het wordt leuker als je het op zijn Brabants zegt :)


Acties:
  • +1 Henk 'm!

  • ThomasG
  • Registratie: Juni 2006
  • Laatst online: 23-09 14:00
Je kunt dit prima uit een RDBMS doen, vooral om de integriteit van de gegevens te garanderen. Omdat dit wel nadelig is voor de prestaties, zul je de gegevens moeten gaan cachen. Je kunt in Laravel heel eenvoudig je queries cachen in Redis, met bijvoorbeeld Lada-cache. Lada-cache heb ik onlangs nog gebruikt in een project, en werkt geheel automatisch. Alle cached queries hebben tags, als je bijvoorbeeld rij 4 van tabel X bijwerkt, worden alle cached queries die rij 4 van tabel X gebruiken invalidated, en dus opnieuw opgehaald; terwijl de ongewijzigde resultaten gewoon in de cache blijven. De RDBMS wordt dan vrijwel geheel ontlast, en Redis is super snel.

Je zou ook een NoSQL database als slave voor een RDBMS kunnen gebruiken. Maar dat is in Laravel relatief ingewikkeld te implementeren, door de manier hoe de Eloquent modellen werken.

Acties:
  • 0 Henk 'm!

  • mcdronkz
  • Registratie: Oktober 2003
  • Laatst online: 16-04 12:44
The Eagle schreef op zaterdag 27 augustus 2016 @ 22:50:
Ik heb geen verstand van Laravel maar dit zou ik niet in een RDBMS oplossen. Kijk naar Bol of Amazon, wat zij in de webshops hebben staan is exact wat jij zoekt. Toevallig weet ik dat daar Hbase onder draait. En daar kan wat jij wilt allemaal prima mee :)
Die oplossing wordt in de toekomst zeker overwogen. Voor nu is dat iets teveel van het goede. Is te lastig om te implementeren in Laravel.
ThomasG schreef op zaterdag 27 augustus 2016 @ 23:20:
Omdat dit wel nadelig is voor de prestaties, zul je de gegevens moeten gaan cachen.
Nadelig ten opzichte van wat? Ik heb juist begrepen dat een relationele structuur een goede performance levert, zeker ten opzichte van EAV.
Je kunt in Laravel heel eenvoudig je queries cachen in Redis, met bijvoorbeeld Lada-cache. Lada-cache heb ik onlangs nog gebruikt in een project, en werkt geheel automatisch. Alle cached queries hebben tags, als je bijvoorbeeld rij 4 van tabel X bijwerkt, worden alle cached queries die rij 4 van tabel X gebruiken invalidated, en dus opnieuw opgehaald; terwijl de ongewijzigde resultaten gewoon in de cache blijven. De RDBMS wordt dan vrijwel geheel ontlast, en Redis is super snel.

Je zou ook een NoSQL database als slave voor een RDBMS kunnen gebruiken. Maar dat is in Laravel relatief ingewikkeld te implementeren, door de manier hoe de Eloquent modellen werken.
Goede adviezen!

Acties:
  • Beste antwoord
  • +4 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

mcdronkz schreef op zaterdag 27 augustus 2016 @ 22:29:
Ik ben bezig met het modelleren van de databasestructuur voor een pricewatch-achtig product, maar dan voor de metaalbranche. Deze database bevat vele duizenden producten, ingedeeld in honderden productsoorten. Deze productsoorten hebben op hun beurt weer uiteenlopende attributen (producteigenschappen).
Toevallig weet ik wel iets van de Pricewatch ;)

Wij gebruiken ook 'gewoon' een EAV-model. Productsoorten is daarbij losgetrokken en heet bij ons categorie. Die hebben een hierarchisch model (effectief een tree), overigens gewoon met een parentId-veld in de category-tabel.
Wat is het meest geschikte ontwerp voor een dergelijke database?
Ik zou er op voorhand rekening mee houden dat er niet één geschikt model is. Voor opslag, bewerken en tonen van specifieke productpagina's zal een RDBMS best goed werken (bij ons iig wel). Voor het doorzoeken, zeker zodra dat gefacetteerd moet (zie specificatie-filters in de PW) gaat een SQL-database niet goed werken.
Een ondertussen redelijk klassieke oplossing is om de data primair in je RDBMS op te slaan. Voor het efficient doorzoeken wordt het dan vaak gedenormalizeerd e.o.a. document database, vaak Elastic Search.
Onderhoudbaarheid is belangrijk
Hier zullen meerdere databasetypen geschikt zijn. Maar ik kan me voorstellen dat een klassieke RDBMS-aanpak icm EAV hier goed presteert.
Performance is belangrijk
De grootste performance-obstakel zal zijn zodra je de lijsten wilt kunnen doorzoeken of in lijsten specifieke attributen wilt tonen. Daar komt dan ook de combinatie met Elastic Search of een andere document store bij kijken.
Meertaligheid is in de toekomst belangrijk
Dan is het vooral verstandig dat je je attributen netjes normaliseert. Met name tekstuele attributen die voor meerdere producten gelden wil je zo min mogelijk herhalen. Door ze te normaliseren kan je eenvoudig extra vertalingen toevoegen.
Hier gaan veel NoSQL-stores onderuit doordat veelal verwacht wordt dat je de boel gedenormalizeerd opslaat. Een extra taal per attribuut wordt dan erg lastig, tenzij die database ook ondersteuning heeft voor een zekere mate van normalisatie.

In de RDBMS+ES oplossing zou je per taal een losse ES-collection kunnen bouwen en zo automatisch de juiste vertalingen hebben tijdens het zoeken.
Consistente/correcte attribuutnamen en waarden zijn belangrijk
Dat maakt kunnen normaliseren extra belangrijk :P
Sommige attributen hebben meerdere waarden
Dat zal je dan op voorhand in je EAV-model moeten meenemen. Zolang je geen unique constraint op de combinatie van product+attribuuttype zet, zou je dat gedrag vanzelf moeten krijgen :P
Producten moeten eenvoudig met elkaar vergeleken kunnen worden, ongeacht de productsoort
Dat is denk ik niet zo relevant voor de opslag. Uiteindelijk zit het er dik in dat je dat soort vergelijkingen toch wel in je applicatie moet doen, waarbij het dus vooral belangrijk je in memory makkelijk kan vergelijken (bijvoorbeeld door de attributen in een hashmap te stoppen). Hoe dat in een database opgeslagen zit is daar eigenlijk nauwelijks relevant voor.
Als je van plan bent vele producten met elkaar te vergelijken (bijv een lijstje met vergelijkbare producten), dan wordt het natuurlijk weer een ander verhaal. Maar daar hebben diverse databases dan weer wel ondersteuning voor, iig Elastic Search kent een 'more like this'-functie.
M'n initiële gedachte was om een EAV-achtige structuur toe te passen, maar al snel bleek dat een dergelijke oplossing tal van nadelen heeft. Zo wordt het onmogelijk om te garanderen dat de database consistente data bevat.
Maar is dat een onacceptabel probleem? De enige die volgens mij echt lastig is om te garanderen, is het garanderen dat een product alleen de voor dat type product bedoelde attribuut heeft. De beschikbare type attributen kan je domweg met een tabel vastleggen en via FK's forceren. De eventuele keuzeopties bij een attribuut kan je ook op die manier vastleggen (hoewel het afdwingen dat de keuzeoptie daadwerkelijk bij het type attribuut hoort wel weer lastiger is).
Ik lees overal dat een aparte tabel per productsoort de voorkeur heeft. Ik zie de voordelen van een puur relationele structuur, maar is dit enigszins te onderhouden... Betekent dit dat er in Laravel (waarin de applicatie geschreven wordt) voor iedere productsoort een migration en model moet worden aangemaakt? Is dit een wenselijke situatie?
Dat klinkt als een erg bewerkelijke manier van werken en met honderden productsoorten ook als een onaagename beheerstaak... Je moet dan sowieso database aanpassen bij elke nieuwe productsoort en/of elk nieuwe type attribuut. Ga er maar vanuit dat je attributen ook wilt kunnen toevoegen, aanpassen en verwijderen. En misschien wil je ook wel je producten zelf een keer aanpassen, dan moet je zelfs al die honderden tabellen modificeren.

Dit klinkt me in ieder geval niet beter dan de EAV-oplossing waarbij je je database 1x hoeft op te zetten en daarna vrijwel ongelimiteerd attributen en productsoorten kunt aanpassen of toevoegen.

[ Voor 4% gewijzigd door ACM op 28-08-2016 11:48 ]


Acties:
  • 0 Henk 'm!

  • mcdronkz
  • Registratie: Oktober 2003
  • Laatst online: 16-04 12:44
ACM schreef op zondag 28 augustus 2016 @ 11:35:
[...]

Toevallig weet ik wel iets van de Pricewatch ;)
Kijk, dat scheelt. _/-\o_

Bedankt voor je reactie, je snijdt een aantal uitstekende punten aan.
[...]

Dat klinkt als een erg bewerkelijke manier van werken en met honderden productsoorten ook als een onaagename beheerstaak... Je moet dan sowieso database aanpassen bij elke nieuwe productsoort en/of elk nieuwe type attribuut. Ga er maar vanuit dat je attributen ook wilt kunnen toevoegen, aanpassen en verwijderen. En misschien wil je ook wel je producten zelf een keer aanpassen, dan moet je zelfs al die honderden tabellen modificeren.

Dit klinkt me in ieder geval niet beter dan de EAV-oplossing waarbij je je database 1x hoeft op te zetten en daarna vrijwel ongelimiteerd attributen en productsoorten kunt aanpassen of toevoegen.
Dit is inderdaad precies het grootste pluspunt van EAV. Ik heb het even laten bezinken, en het ziet er naar uit dat ik voor een hybride ga, waarbij attributen die voor elk product van toepassing zijn (merk, land van herkomst, verpakkingssoort) middels FK's naar losse tabellen verwijzen, en productsoort-specifieke attributen middels een EAV-model geborgd worden. Het is niet zaligmakend, maar wel beheersbaar.

[ Voor 14% gewijzigd door mcdronkz op 29-08-2016 17:46 ]


  • TheNephilim
  • Registratie: September 2005
  • Laatst online: 02-10 09:22

TheNephilim

Wtfuzzle

ACM schreef op zondag 28 augustus 2016 @ 11:35:
[...]

Toevallig weet ik wel iets van de Pricewatch ;)
Interessante read! ^^

EAV (en EAV/CR na wat zoeken) zijn van die termen waarvan je maar net moet weten dat ze bestaan. Dat weten kan je maar zo een hele middag Googelen schelen :+
Pagina: 1