配方数据库设计

时间:2019-04-11 19:13:43

标签: database database-design architecture many-to-many schema

我正在尝试创建一个数据库来存储我的食谱。但是,我不确定如何实现它。我看着其他类似的问题,但它们与我的关注重点不同。

我假设任何菜肴实际上只是一种成分,然后可以在其他菜肴中使用,或者在这种情况下可以在其他成分中使用。任何成分都可以有多种配方。目前,每种配方都表明每种成分需要多少,但我也想知道这些成分是如何组合的,而没有冗长的文字描述。

例如,在文字中,我将描述一种(非常糟糕的)炒鸡蛋食谱:

Scrambled eggs:
    Cooked for 5 minutes(
        1g Butter,
        Whisked(
            1g Salt,
            1g Pepper,
            2 Eggs
    )

然后Scrambled eggs可以在其他食谱中用作配料。

但是这将如何在数据库中转换?由于这是一个个人项目,因此我不需要该数据库基于SQL,但是到目前为止我还不知道任何其他类型的数据库。

我考虑过定义一个Ingredient,因为它与一个可选的Technique相关联,但这意味着Whisked(1g salt, 1g pepper, 2 eggs)必须是一个Ingredient。我想这可能会起作用,并且我也可以将成分的名称设置为可选,但这似乎很尴尬。

我还考虑过将Recipe定义为具有多个TransformedIngredients,其中包含将Technique应用于多个Ingredients,但有时Recipe包含原始的,如果未转换,Ingredients,有时需要将TransformedIngredients应用于TransformedIngredient。据我了解,这些数据库将无法正常工作。

PS:我偶然发现了functional programming Tiramisu recipe,尽管它非常侧重于技术,但却能很好地显示我要为数据库实现的内容。

2 个答案:

答案 0 :(得分:2)

您可以向表中添加一些其他字段,但我相信此架构对您有用。

recipe
------------
r_id PK
recipe_name
cooking_time

recipe_of_recipes
-----------------
ror_id   PK
ror_name

recipe_ror (table for many to many relation-> defining a recipe as an ingredient)
-------------
r_ror_id PK
r_id     FK
ror_id   FK

ingredients
-------------
i_id     PK
t_id     FK
r_id     FK
ror_id   FK (added later)
ingredient_name
quantity

technique
-------------
t_id   PK
technique_name

编辑

假设您要存储由X和y配方加z成分组成的配方(X)。

要准备X配方(大X),

在您存储的recipeingredientstechnique表中

  • x配方和p,w,t,r成分
  • y配方和v,b,n,m成分
  • z成分也具有f的技术(为此,我忘记将字段ror_id作为FK添加到成分表中)

您可以使用recipe_ror表将2个不同的配方(x和y)定义为配方(X)的成分。该表与一个不同的配方相关(表reciperecipe_of_recipes之间的很多关系)

如果您还想存储X,x或y食谱的技术(例如您的示例中的cook),还可以将t_id字段作为FK添加到reciperecipe_of_recipes桌子。

答案 1 :(得分:2)

我认为令人困惑的是,对于食谱,有两个不同的方面需要考虑,即“项目”和“步骤”。

为此想到的一个数据库结构是Star Schema structure,它很好地将这些想法分开(分别分成DimensionFact表)。

每个的简要说明:

  • 尺寸

    • “事物的状态”,即仅存在记录以描述事物的本质。客户的地址表就是尺寸表的一个例子。
  • 事实

    • “随时间变化的事物”,即每个记录都与维度表相关,但是具有变化的值。一个示例是从网站将购买的商品运送到客户的地址。地址保持不变,但货运量不断增加到表中。

这并不是说Dimension表也没有改变;显然,新用户一直在注册网站。在上面的地址示例中,如果客户要更改其地址,则将为新地址添加一个新的primary key值。

现在继续您的食谱示例:

想象一下您正在做饭。我会将您手中的任何东西放在“尺寸”表中。例如:DIM_INGREDIENT(具有诸如INDREDIENT_IDINGREDIENT_NAME之类的列和DIM_AMOUNT({{1},AMOUNT_IDAMOUNT )来描述金额。还有UNITSDIM_ACTIONACTION_IDTYPELENGTH)来描述动作。您可以想出更多的东西。这些只是一些入门。

我要采取的任何步骤都可以放在UNITS表中,该表将映射到所有维度表。没有逻辑步骤的任何步骤都将具有FACT_RECIPE_STEPS值(即,搅拌5分钟将null设为空)。

INGREDIENT_ID可能看起来像这样:

FACT_RECIPE_STEPSRECIPE_IDRECIPE_STEPACTION_STEP_IDINGREDIENT_IDAMOUNT_ID

令人困惑的是将材料搅拌在一起的“子步骤”。我将其放在另一个称为ACTION_ID的{​​{1}}表中,因为“威士忌”是配方列表中的一项操作,但是要执行该操作,您实际上需要做三件事。

我认为以下是一些数据表的外观:

FACT

编辑:

我对如何做食谱的“威士忌”部分不太确定,并认为,当将打好的混合物添加到最终结果中时,就像在食谱中添加一种成分一样。但是,您需要事先准备混合物,并且该过程分为三个步骤。基本上就像是自己的小食谱,FCT_ACTION_STEP考虑了其他“食谱”,以便能够将结果添加到DIM_INGREDIENT INGREDIENT_ID: 1 INGREDIENT_NAME: 'Scrambled eggs' INGREDIENT_ID: 2 INGREDIENT_NAME: 'Salt' INGREDIENT_ID: 3 INGREDIENT_NAME: 'Pepper' INGREDIENT_ID: 4 INGREDIENT_NAME: 'Eggs' INGREDIENT_ID: 5 INGREDIENT_NAME: 'Butter' DIM_ACTION ACTION_ID: 1 TYPE: 'Cook' LENGTH: 5 UNITS: 'minutes' ACTION_ID: 2 TYPE: 'Whisk' LENGTH: null UNITS: null FCT_ACTION_STEP STEP_ID: 1 ACTION_ID: 2 DIM_AMOUNT AMOUNT_ID: 1 AMOUNT: 1 UNITS: 'grams' AMOUNT_ID: 2 AMOUNT: 2 UNITS: null FACT_RECIPE_STEPS RECIPE_ID, RECIPE_STEP, ACTION_STEP_ID, INGREDIENT_ID, AMOUNT_ID, ACTION_ID 表的一行中。

现在我想一想,最好在FACT_ACTION_STEPFACT_RECIPE_STEPS中将“ whisked”作为自己的配方(被称为“鸡蛋的whisked香料”) +并完全摆脱FACT_RECIPE_STEPS表。这样,您可以轻松制作更复杂的食谱,例如“鸡蛋和煎饼早餐”,其中鸡蛋部分是该食谱的结果。