La Modélisation Des Variantes D'Un Produit
J'ai essayé de modèle de variantes de produits et pensé que je pourrais avoir besoin d'utiliser la VAE. J'aurais pu le faire sans EAV, mais je suis inquiet que je pourrais avoir manqué quelque chose. Voici mon dessin:
Voici ce que j'essaie de représenter:
- Un
product
peut avoir 0 ou plusieursproduct variants
(par exemple un t-shirt produit peut avoir la taille et la couleur des variantes). - Un
product variant
peut avoir 1 ou plusieursproduct variant options
(par exemple, la taille de la variante peut être petit, moyen, grand). - Un
SKU
est composé de 1 ou plusieursproduct variant options
(leproduct_variant_option_combination
table contient toutes les combinaisons possibles de " product_variant_options. Donc, si il y avait 3 tailles et 3 couleurs, il y aurait 3 * 3 = 9 combinaisons -- et chaque combinaison serait donné sa propre référence et prix). - Un
product
peut avoir 1 ou plusieursSKUs
.
Si le produit n'a pas toutes les variantes, alors il suffit de les ignorer product_variants
, product_variant_options
, et product_variant_option_combinations
.
Est cette conception sonore? Vais-je avoir des problèmes de cette interrogation? Sera-ce à l'échelle? Est-il normalisé?
Mise à JOUR de 1
@Edper:
Si un produit peut avoir 0 ou plusieurs (mode optionnel) des variantes d'un produit (par exemple, la taille, la couleur, etc). Est-ce que l'une des variantes d'un produit peut aussi avoir 0 ou plusieurs produits ayant qu'une variante?
Je ne le pense pas. Il est possible qu'un produit comme un "t-shirt" ont une "taille" de la variante et un autre produit comme le "pantalon" peut aussi avoir une "taille" de la variante, mais je pense que c'est juste le hasard. Il n'y a pas besoin de faire de "taille" n'apparaissent que comme un enregistrement parce que la "taille" peut avoir les contexte différent.
Les produits que j'ai fais face à varier considérablement et ils sont tenus d'avoir des nommés de la même façon variantes.
Mise à JOUR 2:
Voici un exemple de la façon dont je vois mes données:
J'ai encadré la variante Size
et à ses valeurs. Je tiens à préciser que ce ne sont pas considérés comme des doublons. Le Size
variante pour les 3 produits est juste le hasard. Il n'est pas nécessaire de normaliser ce, je pense. Chaque produit peut avoir 0 ou plusieurs variantes -- et ils sont inconnus pour moi. J'attends des "doublons" (même s'ils ne sont pas vraiment des doublons comme ils le sont toujours dans le contexte d'un produit en particulier, et donc de Widget 1 "Taille" variante n'est pas le même que le Widget de 2 la "Taille" de la variante).
Mise à JOUR 3:
Je vois maintenant que, dans ma conception, il est possible pour un product
d'avoir de multiples identiques product_variants
. Je pense que cela peut être résolu en effectuant des product_variants
.product_id
et product_variants
.name
une clé composite. Cela signifie que Widget 1 ne peut avoir de "Taille" variante fois.
product_variant_options
.product_variant_id
product_variant_options
.name
devrait également être une clé composite.
Mise à JOUR 4:
Par la mise à jour de mon product_variant_option_combinations
inclure product_variant_id
(FK à product_variants
.id
) et l'application d'une contrainte UNIQUE avec product_variant_option_combinations
.sku_id
et product_variant_option_combinations
.product_variant_id
, Je pense que j'ai été en mesure d'éviter le problème d'avoir un SKU qui est à la fois "Petits" et "Gros". Est-ce exact?
-- phpMyAdmin SQL Dump
-- version 4.1.14
-- http://www.phpmyadmin.net
--
-- Host: 127.0.0.1
-- Generation Time: Jul 30, 2014 at 03:35 AM
-- Server version: 5.6.17
-- PHP Version: 5.5.12
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
--
-- Database: `mydb`
--
-- --------------------------------------------------------
--
-- Table structure for table `products`
--
CREATE TABLE IF NOT EXISTS `products` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;
--
-- Dumping data for table `products`
--
INSERT INTO `products` (`id`, `name`) VALUES
(1, 'Widget 1');
-- --------------------------------------------------------
--
-- Table structure for table `product_variants`
--
CREATE TABLE IF NOT EXISTS `product_variants` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`product_id` int(11) NOT NULL,
`name` varchar(45) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UNIQUE_product_id_name` (`product_id`,`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
--
-- Dumping data for table `product_variants`
--
INSERT INTO `product_variants` (`id`, `product_id`, `name`) VALUES
(2, 1, 'Color'),
(1, 1, 'Size');
-- --------------------------------------------------------
--
-- Table structure for table `product_variant_options`
--
CREATE TABLE IF NOT EXISTS `product_variant_options` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`product_variant_id` int(11) NOT NULL,
`name` varchar(45) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UNIQUE_product_variant_id_name` (`product_variant_id`,`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
--
-- Dumping data for table `product_variant_options`
--
INSERT INTO `product_variant_options` (`id`, `product_variant_id`, `name`) VALUES
(2, 1, 'Large'),
(1, 1, 'Small'),
(4, 2, 'Black'),
(3, 2, 'White');
-- --------------------------------------------------------
--
-- Table structure for table `skus`
--
CREATE TABLE IF NOT EXISTS `skus` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`product_id` int(11) NOT NULL,
`sku` varchar(45) NOT NULL,
`price` decimal(10,2) NOT NULL,
PRIMARY KEY (`id`),
KEY `skus_product_id_products_id_idx` (`product_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
--
-- Dumping data for table `skus`
--
INSERT INTO `skus` (`id`, `product_id`, `sku`, `price`) VALUES
(1, 1, 'W1SSCW', '10.00'),
(2, 1, 'W1SSCB', '10.00'),
(3, 1, 'W1SLCW', '12.00'),
(4, 1, 'W1SLCB', '15.00');
-- --------------------------------------------------------
--
-- Table structure for table `skus_product_variant_options`
--
CREATE TABLE IF NOT EXISTS `skus_product_variant_options` (
`sku_id` int(11) NOT NULL,
`product_variant_id` int(11) NOT NULL,
`product_variant_options_id` int(11) NOT NULL,
PRIMARY KEY (`sku_id`,`product_variant_options_id`,`product_variant_id`),
UNIQUE KEY `UNIQUE_sku_id_product_variant_id` (`sku_id`,`product_variant_id`),
KEY `spvo_product_variant_options_id_pro_idx` (`product_variant_options_id`),
KEY `spvo_product_variant_id_product_var_idx` (`product_variant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Dumping data for table `skus_product_variant_options`
--
INSERT INTO `skus_product_variant_options` (`sku_id`, `product_variant_id`, `product_variant_options_id`) VALUES
(1, 1, 1),
(2, 1, 1),
(3, 1, 2),
(4, 1, 2),
(1, 2, 3),
(3, 2, 3),
(2, 2, 4),
(4, 2, 4);
--
-- Constraints for dumped tables
--
--
-- Constraints for table `product_variants`
--
ALTER TABLE `product_variants`
ADD CONSTRAINT `product_variants_product_id_products_id` FOREIGN KEY (`product_id`) REFERENCES `products` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;
--
-- Constraints for table `product_variant_options`
--
ALTER TABLE `product_variant_options`
ADD CONSTRAINT `product_variant_options_product_variant_id_product_variants_id` FOREIGN KEY (`product_variant_id`) REFERENCES `product_variants` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;
--
-- Constraints for table `skus`
--
ALTER TABLE `skus`
ADD CONSTRAINT `skus_product_id_products_id` FOREIGN KEY (`product_id`) REFERENCES `products` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;
--
-- Constraints for table `skus_product_variant_options`
--
ALTER TABLE `skus_product_variant_options`
ADD CONSTRAINT `skus_product_variant_options_sku_id_skus_id` FOREIGN KEY (`sku_id`) REFERENCES `skus` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `spvo_product_variant_options_id_product_variant_options_id` FOREIGN KEY (`product_variant_options_id`) REFERENCES `product_variant_options` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `spvo_product_variant_id_product_variants_id` FOREIGN KEY (`product_variant_id`) REFERENCES `product_variants` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
- Si un
product
peut avoir 0 ou plusieurs (mode optionnel)product variants
(par exemple, la taille, la couleur, etc). Est-ce que, d'uneproduct variants
peut aussi avoir 0 ou plusieursproducts
avoir cette variante? Même avecproduct variant
àproduct variant options
parce queproduct variant options
(par exemple, petit, moyen, grand) peut-être lié à 0 ou plusieursproduct variant
. Donc, ce qui signifie que vous avez une plusieurs-à-plusieurs rapport qui signifie que vous besoin d'une table de bridge direproducts_product_variant
? Ou pensez-vous que vous stockez directement les valeurs à-direname
champ deproducts variant
à partir de la liste déroulante? - Voir La Mise À Jour 1. Merci.
- Si il n'y a pas que partagent de nombreuses variantes de produits différents, alors votre conception est bonne. Mais encore une fois quand un utilisateur de choisir une variante, serait-il venir de la pré-rempli
ComboBox
, par exemple, ou il s'agit d'une table de référence qui est, disons lié à unComboBox
? Si c'est le dernier alors pourquoi le tableau de référence des pas indiqué dans votre conception? Mais encore une fois, votre conception est déjà assez bien. - Les utilisateurs ne seront pas "choisir" une variante. Au lieu de cela, ils seront "en précisant" une variante (et il est possible de spécifier ce qu'ils veulent).
Vous devez vous connecter pour publier un commentaire.
Vous pourriez avoir une conception comme:
Avec le Principal, Unique et Clés Étrangères:
Vous avez:
Vous avez besoin de créer un n-dimensions, tableau, avec le nombre de dimensions égalant le nombre d'options pour le produit. Chaque élément du tableau correspond à une variante de produit. Il y aura toujours au moins une variante de produit pour chaque produit; comme il y a toujours le pseudo option du produit "tel quel"
Vous avez la possibilité de validation afin de garantir un SKU n'est pas affecté, sauf si des valeurs ont été spécifiées pour toutes les options associées à un produit.
Basé sur la feuille de calcul de la façon dont vous voyez vos données, vous pouvez saisir des données dans vos tables comme suit:
Il semble y avoir rien du tout dans votre conception de l'arrêt de l'ajout de l'entrée de l'enregistrement (product_variant_option_id: 2; sku_id 1), de sorte que SKU W1SSCW a maintenant deux options des Petits et des Grands. Il n'y a rien pour empêcher l'entrée de l'enregistrement (product_variant_option_id: 7; sku_id: 1) de sorte que SKU W1SSCW a aussi l'option Amateur.
Basé sur la feuille de calcul de la façon dont vous voyez vos données, vous pouvez saisir des données dans mes tables comme suit:
Dans ma conception, vous ne pouvait pas entrer les autres VARIANT_VALUES record (produit_id: 1; variant_id: 1; option_id: 1; value_id: 2) - de sorte que SKU W1SSCW a maintenant deux options de Petits et de Gros en raison de la clé primaire sur VARIANT_VALUES et les VARIANT_VALUES record (produit_id: 1; variant_id: 1; option_id: 1; value_id: 1). Dans ma conception, vous ne pouvait pas entrer dans la VARIANT_VALUES record (produit_id: 1; variant_id: 1; option_id: 4; value_id: 1) - de sorte que SKU W1SSCW a également la possibilité d'Amateur en raison de la clé étrangère référençant PRODUCT_OPTIONS et l'absence d'un enregistrement dans cette table de (produit_id: 1; option_id: 4), indiquant que la Classe est une option valable pour le produit Widget 1.
MODIFIER: Conception sans PRODUCT_OPTIONS table
Vous pourriez avoir une conception comme:
Avec le Principal, Unique et Clés Étrangères:
Basé sur la feuille de calcul de la façon dont vous voyez vos données, vous pouvez saisir des données dans ces tableaux comme suit:
PRODUCT_VARIANT
.variant_id
le tableau PK? Qu'en estOPTION_VALUES
.value_id
? Est ce que le PK? Je suis encore à essayer de l'étude de votre conception pour voir si ce que vous dites au sujet de l'UGS sens pour moi.skus
table a uneproduct_id
FK. Etproduct_variant_option_combinations
est une liste détaillée de tous lesproduct_variant_options
pour unskus
.#variant_id
référence? 2.) "alors que dans le vôtre tout PRODUCT_VARIANT_OPTION peut être sélectionné pour tout produit" <-- je ne vois pas comment c'est possible car monproducts
table n'est pas directement connecté àproduct_variant_options
. 3.) "alors que dans votre, vous pourriez avoir une variante qui est à la fois Petits et Grands." <-- ce n'est pas ce que je veux? Si il y a une "Taille" de la variante, alors je veux éventuellement avoir une "Petite Taille" et "Grande Taille"? Je suis toujours un peu confus. Désolé.OPTIONS
.option_name
pour être une clé unique. Il est parfaitement OK pour la "Taille" apparaît plusieurs fois (parce que la "Taille" du Widget 1 n'est pas la même "Taille" pour Widget 2). Si je supprime le royaume-UNI contrainte, aura-t-il des problèmes?PRODUCT_VARIANTS
? Aussi, comment dois-je traiter le dans le cas que vous avez mentionné? Pas tous les produits ont des variantes (comme une question de fait, probablement la majorité n'aura pas de variantes). Je suis un peu perdu avecvariant_id
comme il ne semble pas se rapporter à une table???PRODUCT_OPTIONS
table-elle nécessaire? Il semble à faire est de relier lesPRODUCTS
etOPTIONS
table. Ne pouvait pas même être atteint simplement en définissant uneOPTIONS
.product_id
FK àPRODUCTS
.product_id
?product_variant_option_combination
n'empêche pas une variante de Taille = Petit et Taille = Grand? Je n'ai pas pu en quelque sorte modifier ma table pour éviter cela?product_variant_option_combination
et crois que j'ai résolu le problème dans lequel une référence peut être à la fois Petits et Grands. Pensées?FK: product_id, option_id REFERENCES PRODUCT_OPTIONS (product_id, option_id)
? Est-il une solution qui ne nécessite pasvariant_id
?OPTIONS
.option_id
pas censé être un auto-incrémentation de la valeur? Mon problème avecvariant_id
(qui a été renommé avecsku_id
est que ce n'est pas un FK à quelque chose, c'est pourquoi je demande si il existe une solution qui n'a pas besoin d'une telle "nombre magique" - mais peut-être qu'il est en effet nécessaire). Maintenant, dans la dernière conception, je vois encore un autre étrange colonne commevariant_id
(ce qui est le plus de cetteOPTIONS
.option_id
la colonne). Pensées?