Advies indeling database

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Mark Hogeveen

Mark Hogeveen

31/10/2020 20:24:06
Quote Anchor link
Een voorraadbeheersysteem bevat producten. De producten kunnen heel verschillend zijn, en dus hun eigen attributen hebben.
Ik wil het EAV (Entity, Attribute, Value) model gaan gebruiken om de producten op te slaan.
EAV is een algemeen principe. Het betekent dat je een tabel hebt waar de producten in staan, met in deze tabel de kolommen voor waardes (attributen) die voor elk product zullen gelden. Zoals productnaam, beschrijving, prijs, BTW percentage, etc.
In een andere tabel worden attributen opgeslagen (globaal voor hele systeem).
Attributen kunnen zijn: gewicht, kleur, lengte, enzovoort. Dit zijn de attributen die nooit voor elk product zullen gelden, en dus specifiek zijn.
Dan is er nog een tabel die de attributen die in het systeem bestaan, koppelt aan elk product. De rijen in deze tabel bevat het product ID, het attribuut ID, en de waarde voor het attribuut.

Ik heb een schema gemaakt van mijn eerste opzet van de database indeling:

Afbeelding

De oranje tabel kan voor elk product vaak meerdere rijen bevatten om het product met een attribuut en de waarde te koppelen.
De tabel 'product_attributes' bevat dus alle attributen die in het systeem voorkomen, als een soort register. Hier komen dus nooit dezelfde rijen in voor. In de praktijk zal deze tabel bijvoorbeeld zo'n 50 - 100 rijen bevatten.

Tweede manier
Nu was ik aan het denken: zou ik die oranje koppelingstabel niet kunnen weglaten, en die net genoemde ' product_attributes' tabel gewoon gebruiken om hierin direct per attribuut de waarde op te slaan? De tabel is dan geen 'register' meer, en kan dus heel veel rijen bevatten waarin dezelfde attribuutnaam en categorie ID staat.
Als ik dan toch nog een flat lijst als 'register' zou willen hebben (voor backend) om alle unieke attributen (attribuutnamen) op te halen die in het systeem voorkomen, dan gebruik in een query zoals:
SELECT DISTINCT name FROM product_attributes

De eerste manier (zoals in de afbeelding) is het meest gebruikelijk. De tweede manier heeft mogelijk het voordeel dat queries minder complex kunnen worden geschreven en dat eventuele JOIN queries minder tabellen hoeven aan te roepen (dus JOINs met waarin bijvoorbeeld 2 tabellen in voorkomen i.p.v. 3).
Maar tegelijkertijd lijkt die tweede manier me wel wat lelijk.

Zou de performance van de database veel worden verbeterd met de tweede manier? Of maak ik er zo alleen maar een rommeltje van?
Gewijzigd op 31/10/2020 20:26:11 door Mark Hogeveen
 
PHP hulp

PHP hulp

15/07/2024 20:16:07
 
Thomas van den Heuvel

Thomas van den Heuvel

31/10/2020 21:15:25
Quote Anchor link
Poep, was hier een antwoord aan het typen maar ben deze kwijt. Een korte samenvatting dan maar.

Wat in het bovenstaande nog ontbreekt is mogelijk het volgende:
- een entiteit voor "concrete" producten, oftewel een specifieke combinatie van product_attribute_values die tezamen een fysiek/tastbaar/concreet product vormen, weet niet of dat in het bovenstaande ontwerp wordt gevangen en/of dat van toepassing is op jouw situatie?
- een tabel voor de attributen (de attributen, dus niet de waarden) die deze ruimte opspannen om zo de concrete producten te voorzien van specifieke waarden (die je in eerste instantie gebruikt voor het vullen van de values voor de specifieke attributen en vervolgens voor het bouwen van de producten zelf)

Als je dan toch bezig bent met een generieke database zou ik het ook zo generiek mogelijk opzetten.

Om het bovenstaande misschien wat beter te illustreren zie een reactie van mij op een ander forum (en de reactie hier direct na, en nog wat kanttekeningen op de tweede pagina). Bekijk ook de afbeelding die hierbij zit die de verbanden illustreert.

Ik denk trouwens dat het voor performance weinig uitmaakt dat je twee of drie tabellen aan elkaar fietst, zolang dit maar via primary/foreign keys of indexen gebeurt. Je kunt altijd met EXPLAIN nagaan waarom een query traag is.

Overigens, je kunt de tabellen dan nog zo strak/generiek opzetten als je wilt, maar als je deze tabellen op de verkeerde manier vult dan kun je hier alsnog een potje van maken. Het is dus niet alleen de structuur die moet kloppen, maar de tabellen moeten ook op een zinnige manier gevuld/ingedeeld worden. Denk bijvoorbeeld aan "product overkoepelende attributen en attribuutwaarden" zoals bijvoorbeeld een schoenmaat. Je moet over verschillende producten soms dezelfde (gedeelde) attributen gebruiken om op die manier in de frontend (en wellicht ook in de backend) snel te kunnen zoeken/filteren, denk aan facetted searches enzo, ook dat staat (misschien wat kort door de bocht) toegelicht op dat andere forum, maar dit illustreert dus waarom een goede en slimme indeling super belangrijk is zodat je hier vervolgens makkelijker mee kunt zoeken want het wordt anders heel erg lastig om producten te vergelijken doordat je bijvoorbeeld het attribuut schoenmaat meerdere keren introduceert. Je bent dan namelijk letterlijk met meerdere maten aan het meten :).

Of je gooit deze producten gewoon in Magento ofzo :p.
Gewijzigd op 31/10/2020 21:27:03 door Thomas van den Heuvel
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.