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:

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?