我正在抓耳挠腮,寻找实现这一目标的合理方法。标题真的很难理解,所以如果你进入这篇文章是希望得到别的东西,我很抱歉。这既是一个数据库问题,也是一个逻辑问题。
我在一个“集合”中有 100 个条目。让我们称每一个为对象。每个对象都引用数据库中的一个条目,并有一些名称(比如 obj1、obj2 ...)。其中一些对象是其他对象的“复合体”。因此,例如,如果 obj1 和 obj2 是输入,则 obj11 是输出 (obj1, obj2 -> obj11)。甚至可能是同一对象的多个输入:obj1 x 4、obj2、obj11 -> obj21。
我正在寻找一种在更改输入的同时连续计算结果对象的方法,因此这些关系必须以某种巧妙的方式存储在数据库中,这样才能以相当优雅的方式完成这样的计算时尚。
自然而然地,我想到了一个多对一的表,但找不到一种合乎逻辑的方法来在不解析整个表的情况下找到给定输入的结果。
有没有人对此有一些想法?
最佳答案
您似乎在构建一种食谱系统。一些对象是由不同数量的其他对象创建的。在数据结构方面,你可以有类似的东西
struct Thing {
std::vector<Ingredient> parts;
// ... other attributes here
};
struct Ingredient {
Thing component;
int count;
};
这可以使用
存储 CREATE TABLE `Things` (
`id` int(11) NOT NULL AUTO_INCREMENT,
# ... other attributes here
PRIMARY KEY `id`
);
CREATE TABLE `Ingredients` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`result_id` int(11) NOT NULL,
`component_id` int(11) NOT NULL,
`count` int(11) NOT NULL,
PRIMARY KEY `id`
);
ALTER TABLE `Ingredients` FOREIGN KEY (`result_id`) REFERENCES `Thing` (`id`);
ALTER TABLE `Ingredients` FOREIGN KEY (`component_id`) REFERENCES `Thing` (`id`);
存储 Thing
的配方,只需将其所有成分及其数量作为配料插入即可。要检索食谱,只需 SELECT
所有成分result_id
.看看哪里有Thing
在配方中使用,只需查询它作为组件的用途。
想象一下 A
由 B
构建和 C
;那B
可以从 D
构建和 E
.然后你可能想要执行多阶段查询,从A
中找出= B
+ C
那A
= ( D
+ E
) + C
.这需要对每个组件进行额外选择,以查看它本身是否具有成分。但是,除非您的食谱形成一棵树,否则这会适得其反:如果A
怎么办?需要 B
和 B
可以从 A
构建?。更糟糕的是:如果有几种方法可以获得 A
怎么办? , 比如说来自 B
+ C
或来自 X
+ Y
?如果您需要区分这些替代食谱,您将需要一个额外的表格:
struct Thing {
std::vector<Recipe> recipes;
// ... other attributes here
};
struct Recipe {
std::vector<Ingredient> ingredients;
// ... other attributes here
};
struct Ingredient {
Thing component;
int count;
};
并且,在 SQL 中,
CREATE TABLE `Recipes` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`result_id` int(11) NOT NULL,
PRIMARY KEY `id`
);
CREATE TABLE `Ingredients` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`recipe_id` int(11) NOT NULL,
`component_id` int(11) NOT NULL,
`count` int(11) NOT NULL,
PRIMARY KEY `id`
);
ALTER TABLE `Recipes` FOREIGN KEY (`result_id`) REFERENCES `Thing` (`id`);
ALTER TABLE `Ingredients` FOREIGN KEY (`recipe_id`) REFERENCES `Recipe` (`id`);
ALTER TABLE `Ingredients` FOREIGN KEY (`component_id`) REFERENCES `Thing` (`id`);
如果您需要恢复类似这样的多阶段配方,那么您正在尝试在关系数据库上执行图查询,并且可能会发现使用专为那些对象设计的对象图数据库要容易得多查询类型。
编辑:假设没有循环,每个 Thing
最多 1 个配方,我如何根据配料表找到要 cooking 的食物?有几种方法是可能的。
- 如果菜谱的数量不是很大,并且菜谱不经常更改,只需将它们全部加载到内存中并使用集合交集来检测可能的菜谱。这将比使用数据库更快。
- 如果你坚持使用数据库,这行得通(你可以 test it online :
SELECT possible.id
FROM (
SELECT i.result_id AS id, COUNT(*) AS total
FROM `Ingredients` AS i GROUP BY i.result_id
) AS possible, (
SELECT result_id, COUNT(result_id) AS total
FROM `Ingredients` AS i WHERE
(i.component_id = 1 AND i.count<=1) OR
(i.component_id = 2 AND i.count<=3) OR
(i.component_id = 42 AND i.count<=1)
GROUP BY i.result_id
) AS valid
WHERE possible.id = valid.result_id AND possible.total = valid.total;
关于sql - 在一对多系统中存储和计算关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56902304/