标准化产品配方数据
normalizing product recipe data
我正在尝试实施产品配方(这就是我们的供应商所称的),但我似乎无法思考如何正确规范化它。
我添加了一些样本数据来说明它的样子。
以 R*** 开头的值是对配方标识符的引用。
数值是对产品标识符的引用。
配方是产品的分组(仅此而已)。
食谱的唯一属性是名称。这应该是产品分组的逻辑名称。
如您所见,产品也可以依次连接到食谱。
并且产品可以直接连接到其他产品。
对此的唯一限制是配方 (R***) 永远不能直接连接到另一个配方。所以要明确一点,产品可以直接连接,但食谱不能。
事实上,一个子条目可以有多个不同的父条目,这让我觉得有点模糊。
好的...想出以下解决方案,似乎效果不错。
如果有人感兴趣,这里是 sql 创建的:
CREATE TABLE recipe_node (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
recipe_id INT,
product_id INT,
created_at DATETIME NOT NULL,
updated_at DATETIME,
deleted TINYINT NOT NULL DEFAULT 0,
deleted_at DATETIME,
PRIMARY KEY (id),
UNIQUE INDEX UNQ_PRODUCT_ID (product_id),
UNIQUE INDEX UNQ_RECIPE_ID (recipe_id),
CONSTRAINT FK_RECIPE_NODE_RECIPE_ID_RECEPT_RECEPTID FOREIGN KEY (recipe_id) REFERENCES recept(receptid) ON UPDATE RESTRICT ON DELETE CASCADE,
CONSTRAINT FK_RECIPE_NODE_PRODUCT_ID_PRODUCT_PRODUCTID FOREIGN KEY (product_id) REFERENCES product(productid) ON UPDATE RESTRICT ON DELETE CASCADE
) ENGINE=INNODB CHARSET=utf8 COLLATE=utf8_general_ci;
CREATE TABLE recipe_graph (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
parent_id int(10) unsigned NOT NULL,
child_id int(10) unsigned NOT NULL,
quantity int(10) unsigned NOT NULL DEFAULT '1',
sequence_number int(10) unsigned NOT NULL DEFAULT '1',
created_at datetime NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY UNQ_PARENT_ID_CHILD_ID (parent_id,child_id),
KEY IDX_CHILD_ID_PARENT_ID (child_id,parent_id),
CONSTRAINT FK_RECIPE_GRAPH_CHILD_ID_RECIPE_NODE_ID FOREIGN KEY (child_id) REFERENCES recipe_node (id) ON DELETE CASCADE,
CONSTRAINT FK_RECIPE_GRAPH_PARENT_ID_RECIPE_NODE_ID FOREIGN KEY (parent_id) REFERENCES recipe_node (id) ON DELETE CASCADE
) ENGINE=INNODB CHARSET=utf8 COLLATE=utf8_general_ci;
我正在尝试实施产品配方(这就是我们的供应商所称的),但我似乎无法思考如何正确规范化它。
我添加了一些样本数据来说明它的样子。
以 R*** 开头的值是对配方标识符的引用。 数值是对产品标识符的引用。
配方是产品的分组(仅此而已)。 食谱的唯一属性是名称。这应该是产品分组的逻辑名称。
如您所见,产品也可以依次连接到食谱。 并且产品可以直接连接到其他产品。
对此的唯一限制是配方 (R***) 永远不能直接连接到另一个配方。所以要明确一点,产品可以直接连接,但食谱不能。
事实上,一个子条目可以有多个不同的父条目,这让我觉得有点模糊。
好的...想出以下解决方案,似乎效果不错。
如果有人感兴趣,这里是 sql 创建的:
CREATE TABLE recipe_node (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
recipe_id INT,
product_id INT,
created_at DATETIME NOT NULL,
updated_at DATETIME,
deleted TINYINT NOT NULL DEFAULT 0,
deleted_at DATETIME,
PRIMARY KEY (id),
UNIQUE INDEX UNQ_PRODUCT_ID (product_id),
UNIQUE INDEX UNQ_RECIPE_ID (recipe_id),
CONSTRAINT FK_RECIPE_NODE_RECIPE_ID_RECEPT_RECEPTID FOREIGN KEY (recipe_id) REFERENCES recept(receptid) ON UPDATE RESTRICT ON DELETE CASCADE,
CONSTRAINT FK_RECIPE_NODE_PRODUCT_ID_PRODUCT_PRODUCTID FOREIGN KEY (product_id) REFERENCES product(productid) ON UPDATE RESTRICT ON DELETE CASCADE
) ENGINE=INNODB CHARSET=utf8 COLLATE=utf8_general_ci;
CREATE TABLE recipe_graph (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
parent_id int(10) unsigned NOT NULL,
child_id int(10) unsigned NOT NULL,
quantity int(10) unsigned NOT NULL DEFAULT '1',
sequence_number int(10) unsigned NOT NULL DEFAULT '1',
created_at datetime NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY UNQ_PARENT_ID_CHILD_ID (parent_id,child_id),
KEY IDX_CHILD_ID_PARENT_ID (child_id,parent_id),
CONSTRAINT FK_RECIPE_GRAPH_CHILD_ID_RECIPE_NODE_ID FOREIGN KEY (child_id) REFERENCES recipe_node (id) ON DELETE CASCADE,
CONSTRAINT FK_RECIPE_GRAPH_PARENT_ID_RECIPE_NODE_ID FOREIGN KEY (parent_id) REFERENCES recipe_node (id) ON DELETE CASCADE
) ENGINE=INNODB CHARSET=utf8 COLLATE=utf8_general_ci;