I have the following structure of my database, implementing a simple EAV model (see pic):
My product
has a type
, which through the junction table restricts prop_names
, available for this product. And here everything is clear.
BUT:
Then I've added a prop_values
table to keep the properties values for each product. It has reference to products
through prod_sku
and to prop_names
through prop_id
. And here the problem comes: One can add to any product any properties - even those, which are not allowed for this product type. Also, there can be duplications - two or more same properties for a single product.
Is there any way to restrict this on the database level?
After the @BillKarvin's answer, I've tried the below CREATE code, but failed with the 'Foreign key constraint is incorrectly formed' error when creating the last table (property_values
).
I have found my error - I forgot to add a KEY to the products
table. Below is the corrected (working) version of my code:
CREATE TABLE product_types (
id INT PRIMARY KEY,
product_type varchar(50) NOT NULL,
block_css_id varchar(50) NOT NULL,
block_description varchar(50) NOT NULL
);
CREATE TABLE products (
sku varchar(50) PRIMARY KEY,
name varchar(50) NOT NULL,
price decimal(20,2) unsigned NOT NULL,
id_product_type INT NOT NULL,
FOREIGN KEY (id_product_type) REFERENCES product_types (id),
KEY (sku, id_product_type)
);
CREATE TABLE property_names (
id INT PRIMARY KEY,
property_name varchar(50) NOT NULL,
property_css_id varchar(50) NOT NULL,
property_input_name varchar(50) NOT NULL
);
CREATE TABLE junction_ptype_propname (
id_productt_type INT NOT NULL,
id_property_name INT NOT NULL,
PRIMARY KEY (id_productt_type, id_property_name),
FOREIGN KEY (id_productt_type) REFERENCES product_types (id),
FOREIGN KEY (id_property_name) REFERENCES property_names (id)
);
CREATE TABLE property_values (
id INT NOT NULL PRIMARY KEY,
product_sku varchar(50) NOT NULL,
property_id INT NOT NULL,
property_value decimal(20,2) NOT NULL DEFAULT 0.00,
id_prod_type INT NOT NULL,
UNIQUE KEY (product_sku, property_id),
FOREIGN KEY (product_sku, id_prod_type) REFERENCES products (sku, id_product_type),
FOREIGN KEY (property_id, id_prod_type) REFERENCES junction_ptype_propname (id_property_name, id_productt_type)
);