Webshop Database Model

  • Hallo iedereen,


    Ik ben de eerste stappen aan het zetten om een custom webshop te maken. Echter loop ik bij de database op een probleempje aan.


    In de webshop zullen kledingstukken, schoenen, etc aangeboden worden.
    Maar hoe verwerk ik dit nou het beste in mijn database?


    Ik zat te denken aan een aparte tabel met product_specificaties. Deze zou dan een hoofdcategorie_id hebben dat staat voor kleur, maat, ... en een waarde hebben, dit zou dan geel, zwart, S, M, ... zijn.


    Maar hoe koppel ik dit dan weer het beste aan mijn product? Aangezien niet elk product elke kleur heeft.



    Alvast bedankt voor de hulp!

  • Ik zou je producten een tabel geven en die dan voor alle opties een andere tabel en dan die bijbehorende id's in je product tabel zetten
    bijv:


    Producten
    id, titel, categorie_id, specificaties_ids


    Specificaties
    id, naam


    Als je dan in de producten specificaties_ids de id's invoert gescheiden door "," oid kan je daar gewoon opzoeken en kan je ze met PHP ook exploden naar een array ;)

  • Lees zijn laatste zin nog is:
    'Als je dan in de producten specificaties_ids de id's invoert gescheiden door "," oid kan je daar gewoon opzoeken en kan je ze met PHP ook exploden naar een array'

    Dan nog kun je geen onderscheid maken tussen een kleur of een maat? Of moet er dan in de tabel Specificaties een categorie_id toegevoegd worden waar: 0 dan voor kleuren staat, 1 voor maten, etc.

  • Als je dan in de producten specificaties_ids de id's invoert gescheiden door "," oid kan je daar gewoon opzoeken en kan je ze met PHP ook exploden naar een array

    Ai.


    Toegegeven, daarmee los je het probleem van alle data in je database gooien op, maar hoe haal je dit er vervolgens weer uit. Er zijn wel situaties denkbaar waar het serialiseren van data handig is, maar hier lijkt mij dat heel onverstandig omdat je het jezelf haast onmogelijk maakt om informatie fatsoenlijk te zoeken. Als je een beroep moet doen op dit soort constructies dan is dat vaak een indicatie dat je data(base) nog niet helemaal uitgenormaliseerd is / incompleet is.


    Dit schreeuwt haast om (op zijn minst) de introductie van een of enkele koppeltabellen.


    Iets wat relatief weinig moeite kost en veel inzicht op kan leveren is het volgende: klieder eerst eens wat op papier. Noteer hierbij de "spelers" (de entiteiten) in het systeem. Schrijf daarbij op hoe hun relatie is ten opzichte van de andere spelers.


    Bijvoorbeeld:
    In mijn webwinkel verkoop ik producten. Een product heeft een aantal standaard en een aantal product-specifieke eigenschappen. Deze eigenschappen hebben specifieke waarden. Eenzelfde product heeft mogelijk meerdere uitvoeringen (sets van specifieke waarde-configuraties).


    Met deze paar zinnen heb je al een redelijk nauwkeurig beeld geschetst van wat je zou kunnen bouwen en leg je mogelijk ook potentiële problemen bloot zoals variaties in de configuratie van "eenzelfde" product. Want, wanneer is een product hetzelfde? Bij een webshop lijkt het mij ook belangrijk dat bezoekers snel kunnen vinden wat ze zoeken. Je zult dus heel goed moeten nadenken hoe je dit vormgeeft.


    Wat hierboven beschreven staat is in feite een soort van generieke opzet voor het bouwen van database-tabellen. Wat je hier in feite aan het doen bent is het bouwen van een database in een database. Nu is dit niet altijd de beste methode maar het is een methode. Omdat dit onder de motorkap in wezen een redelijk geavanceerd adminstratief systeem is loont het de moeite om je database ook echt relationeel op te zetten. Dit houdt in dat je ook (veelvuldig) gebruik maakt van (foreign) keys waarbij je onderlinge relaties afdwingt zodat de data in je database een consistent geheel vormt (en blijft) en relatief "makkelijk" onderhoudbaar is. Het is dus haast een must dat je dus de InnoDB engine gebruikt (aangenomen dat je van MySQL gebruik maakt).


    In zijn simpelste vorm zou ik misschien de volgende tabellen gebruiken:


    products
    als kapstok voor producten


    product_properties
    als kapstok voor product-eigenschappen


    product_property_values
    hierin staan alle mogelijke waarden van een specifieke product-eigenschap


    Met bovenstaande definties heb je (heel globaal) de spelers gedefineerd, maar nu moet je deze nog combineren tot concrete producten, dit zijn dus de invullingen van verschillende product-configraties, maar hier sta je dus voor een probleem. Stel je hebt een of ander T-shirt die in meerdere maten en meerdere kleuren beschikbaar is. Is dit één product die verschillende uitvoeringen heeft (en hoe organiseer je dat dan?) of behandel je dit als verschillende producten (maar hoe geef je dan aan dat er meerdere uitvoeringen zijn van dit zelfde T-shirt?). Omdat ik niet op voorhand weet hoe de situatie in jouw geval is en het in het algemeen wel verstandig is om je opties open te houden is het wellicht een idee om een extra tabel te introduceren waarin je de verschillende productconfiguraties van eenzelfde product kunt bundelen, dus bijvoorbeeld een tabel:


    product_variants
    kapstok voor verschillende eigenschapbundels van eenzelfde product. Er valt iets voor te zeggen om deze automatisch te genereren. Hoe je dit op interface niveau wilt inrichten... is een tweede verhaal, maar hier creëer je in ieder geval op administratief niveau de mogelijkheid. In principe bevat deze tabel de lijst met "concrete" producten.


    Vervolgens moet je de eindjes nog aan elkaar knopen, zo kan het handig zijn dat je een (hulp)tabel hebt die aangeeft welke eigenschappen een product allemaal heeft, dit kan handig zijn om snel(ler) alle eigenschappen op te vragen zodat je hiermee op voorhand de ruimte op kunt spannen van eigenschappen waaruit een product bestaat wat weer handig kan om filters te bouwen om snel te zoeken binnen een productcategorie (hier komen we zo op terug). Als je bijvoorbeeld weet dat een zeker T-shirt type de volgende eigenschappen heeft: halstype, maat, kleur, opdruk, longsleeve (ja ofte nee) dan kun je hier op filteren om snel in te zoomen op het product waarin jij mogelijk geinteresseerd bent. Je zou ook kunnen overwegen om dit soort informatie op een of andere manier aan een categorie op te hangen waar dit kledingtype onderdeel van uit maakt. Je moet er dan vervolgens wel voor zorgen dat al deze producten op zijn minst deze eigenschappen bevatten zodat je hier op kunt filteren. De manier waarop je je informatie organiseert is dus heel erg belangrijk, anders kun je er op een gegeven moment niet goed in zoeken, wat tot gevolg heeft dat je producten minder goed vindbaar zijn en dat kan weer leiden tot afhakende kopers en daarmee tot omzetverlies. Daarom is het serialiseren van data wellicht niet zo'n strak plan :).


    Maar goed, in eerste instantie een "simpele variant", wat je nog moet doen om het rondje compleet te maken is de eigenschap-waarden koppelen aan een product variant:


    product_variant_property_values
    Hierbij is het wellicht ook verstandig om in deze tabel op te nemen welke eigenschap dit betreft. In principe is dit afleidbare (redundante) informatie maar mogelijk zorgt dit ervoor dat het bouwen van queries en de uitvoer hiervan stukken gemakkelijker en sneller gaat. Zo ook dus de eerder genoemde tabel waarbij je de ruimte opspant van de eigenschappen van een specifiek(e) product(groep). Op zich is dit dus ook afleidbare situatie, maar op deze manier heb je ergens expliciet vastgelegd uit welke eigenschappen een product zou moeten bestaan:


    product_variant_properties
    Dit betreft dus een "abstracte hulptabel", hierin zitten geen concrete producten.


    Hiermee heb je een mogelijke generieke basis. Daarnaast zou je hier nog extra lagen op kunnen bouwen door ook een soort van hierarchisch georganiseerde categorie-boom te bouwen waar je producten aan koppelt waarbij een product tot een of meer categorieën kan behoren.


    ---


    Met dit alles vind je mogelijk wel het wiel opnieuw uit. Wellicht is het interessant hoe andere systemen (denk aan Magento) dit theoretisch aanpakken. Zij doen namelijk min of meer hetzelfde: daar heb je ook -zoals zij dat dan noemen- "simpele" en "configureerbare" producten (dit onderscheid wordt hierboven niet echt gemaakt, in ons geval zou een "simpel" product een product zijn met één productconfiguratie en een "configurable" is een product met meerdere productconfiguraties, nu ik er over nadenk is er iets voor te zeggen om deze verschillende soorten producten toch uniform te behandelen zoals we in deze opzet hier doen) en de data-organisatie zoals wij dit doen daar hanteert Magento een algemene variant voor: zij maken gebruik van een EAV-opzet (Entity Attribute Value), zij het op een, maar mijn mening, wat ondoorzichtigere manier.


    Maar voel je vrij om hier zelf ook mee te experimenteren, houd er wel rekening mee dat de informatie die je in je database opslaat ook weer op een of andere manier (en bij voorkeur MAKKELIJK) opvraagbaar moet zijn.


    EDIT: ik zal proberen nog een plaatje toe te voegen met alle tabellen en hun minimale verbanden (zullen zelf nog aangevuld moeten worden, maar dan zijn de relaties in ieder geval duidelijk). Ook zal pas blijken bij het "bouwen" van producten en het uitvoeren van (zoek)queries in je shop of het voorgespiegelde ontwerp echt handig is in het gebruik, of zoals ze zeggen "The proof of the pudding is in the eating".

  • Zoiets dus:

    Hierbij zou je dus product_variant_properties kunnen gebruiken om product_variant_property_values te kunnen vullen.


    Wat je achtereenvolgens zult moeten doen bij het aanmaken van producten:
    - maak een product aan
    - maak product properties aan
    - maak product property values aan
    - EDIT geef in product_variant_properties aan uit welke eigenschappen een product bestaat
    - vervolgens kun je concrete producten gaan bouwen door instanties van een product aan te maken in product_variants en deze (elk) te configureren (of deels te genereren) door gebruik te maken van product_variant_properties en de concrete waarden weg te schrijven in product_variant_property_values


    Succes :)

  • Nog twee pointers:


    #1
    Indien je eenzelfde categorie producten hebt (bijvoorbeeld "schoenen") dan zullen er waarschijnlijk product-overschrijdende eigenschappen zijn, bijvoorbeeld "schoenmaat". Het is vrij belangrijk dat je voor die eigenschap (maat van een schoen) één eigenschap hebt, anders ben je mogelijk met verschillende maten aan het meten/zoeken als je per product zo'n eigenschap creëert. Het op een slimme manier vullen van deze generieke tabellen is dus minstens zo belangrijk als de structuur van de tabellen zelf. Deze flexibele opzet biedt je genoeg ruimte, maar je moet hier vervolgens wel handig mee omspringen.


    #2
    Bedenk vast welke pagina's je in je shop wilt laten terugkomen, denk aan:
    - een categoriepagina
    - een product(detail)pagina
    - een pagina specifiek voor een zoekformulier; je zou ook kunnen overwegen om een filterpaneel/kolom/box te maken op een categoriepagina zelf
    - checkoutpagina


    en onderdelen als:
    - filters
    - wishlist
    - loginpaneel zodat een klant niet altijd zijn/haar gegevens hoeft in te vullen
    - shoppingcart
    - crosssells / upsells
    etc.
    (nogmaals, kijk eens naar Magento voor inspiratie)


    En bij dit alles (punt 2) als belangrijkste: houd hierbij je database in het achterhoofd, bedenk of test of de tabellen en de door jou hier ingestoken data geschikt zijn om aan alle "informatievragen" van de pagina's en onderdelen te voldoen. Maak bijvoorbeeld alvast een kleine set test-data waarmee je een kleine shop kunt simuleren en eventueel nog e.e.a. in het model kunt bijschaven voordat je de hele site al gebouwd hebt, hoe vroeger je dit soort wijzigingen/bijstuuracties doorvoert, hoe beter lijkt mij.

Participate now!

Heb je nog geen account? Registreer je nu en word deel van onze community!