À mon avis, vous pouvez résoudre ce problème de deux manières:
La catégorie est un type de produit spécial
Cela signifie que pour tout produit donné dans votre base de données, il contient une clé étrangère pointant vers le même produit de table. Un produit n'est un produit que s'il n'existe aucun produit dont la clé étrangère est égale à l'id dudit produit. En d'autres termes, s'il n'a aucun produit en dessous, c'est un produit.
Cela simplifierait un peu les choses. Les produits aux propriétés auraient une relation un-à-plusieurs et, par conséquent, vos catégories ont également une relation un-à-plusieurs car elles sont également des produits. Ajouter une propriété à une catégorie serait aussi simple que d'ajouter une propriété à un produit dans votre programme. Le chargement de toutes les propriétés impliquerait de combiner les propriétés du produit avec les propriétés de son produit de catégorie associé et ainsi de suite jusqu'à ce que vous atteigniez un produit de catégorie sans parent.
Votre application de commerce électronique devrait faire cette distinction, mais si vous êtes de toute façon susceptible de charger des produits d'une catégorie, ce n'est pas une perte de performances de savoir si vous avez affaire à une catégorie ou à un produit. Il se prête également bien à la recherche arborescente au niveau du produit, car chaque produit (catégorie) s'ouvrirait à une liste de sous-produits sans beaucoup de travail supplémentaire.
L'inconvénient est bien sûr que des informations supplémentaires présentes dans le produit qui n'ont pas de sens pour une catégorie créeraient des champs inutilisés maladroits dans le produit. Bien que cette solution soit plus flexible dans votre application, elle est également un peu moins intuitive.
Relation plusieurs à plusieurs
Les produits ne sont plus dans une relation composite avec la propriété. Vous créez une table ProductProperty avec des clés étrangères de la table de produit et de la table de propriétés qui lient les deux. De même, vous avez une table de catégories avec une relation plusieurs-à-plusieurs avec la table de propriétés et une table CategoryProperty avec des clés étrangères de la table des catégories et de la table des propriétés.
Le produit lui-même aurait une relation plusieurs-à-un avec la catégorie, vous permettant essentiellement de créer une liste de propriétés uniques se rapportant à la fois au produit et à la catégorie via une déclaration de sélection bien formalisée.
Du point de vue de la base de données, c'est définitivement plus propre et plus flexible. Votre application pourrait probablement faire la plupart du temps sans traiter directement avec CategoryProperty ou ProductProperty si la requête est effectuée correctement. Cependant, vous ne devez pas non plus considérer la catégorie ou le produit comme le propriétaire d'un bien. Il doit s'agir de sa propre entité au sein de votre programme. Cela signifie également que la gestion desdites propriétés consisterait à créer la propriété elle-même, puis à l'associer à une catégorie ou à un produit en deux étapes distinctes. Certes, plus de travail que la première solution, mais en aucun cas plus difficile.
En plus de cela, vous devrez également effectuer une vérification supplémentaire lors de la suppression de la catégorie ou du produit si l'une de ses propriétés est utilisée par d'autres (contrairement à la première solution où vous pouviez éliminer en toute sécurité toutes les propriétés associées d'un produit / catégorie donné) .
Conclusion
Dans un contexte professionnel, j'irais dans la catégorie mile supplémentaire et distance du produit et du produit de la propriété en utilisant l'approche plusieurs-à-plusieurs. Il n'y aurait aucune possibilité de chevauchement des données, et dans un sens, il est plus facile de raisonner chacun de ces trois en tant qu'entité propre. Cependant, la première solution n'est en aucun cas mauvaise, car elle vous permet également d'écrire une application plus simple. Sachez simplement que si vous pensiez que vous deviez éventuellement passer d'une solution à l'autre, il serait probablement dans votre intérêt de choisir la seconde.
Bonne chance!