我正在尝试创建一个数据库来存储我的食谱。但是,我不确定如何实现它。我看着其他类似的问题,但它们与我的关注重点不同。
我假设任何菜肴实际上只是一种成分,然后可以在其他菜肴中使用,或者在这种情况下可以在其他成分中使用。任何成分都可以有多种配方。目前,每种配方都表明每种成分需要多少,但我也想知道这些成分是如何组合的,而没有冗长的文字描述。
例如,在文字中,我将描述一种(非常糟糕的)炒鸡蛋食谱:
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,尽管它非常侧重于技术,但却能很好地显示我要为数据库实现的内容。
答案 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),
在您存储的recipe
,ingredients
和technique
表中
您可以使用recipe_ror
表将2个不同的配方(x和y)定义为配方(X)的成分。该表与一个不同的配方相关(表recipe
和recipe_of_recipes
之间的很多关系)
如果您还想存储X,x或y食谱的技术(例如您的示例中的cook),还可以将t_id
字段作为FK添加到recipe
和recipe_of_recipes
桌子。
答案 1 :(得分:2)
我认为令人困惑的是,对于食谱,有两个不同的方面需要考虑,即“项目”和“步骤”。
为此想到的一个数据库结构是Star Schema structure,它很好地将这些想法分开(分别分成Dimension
和Fact
表)。
每个的简要说明:
尺寸
事实
这并不是说Dimension表也没有改变;显然,新用户一直在注册网站。在上面的地址示例中,如果客户要更改其地址,则将为新地址添加一个新的primary key
值。
想象一下您正在做饭。我会将您手中的任何东西放在“尺寸”表中。例如:DIM_INGREDIENT
(具有诸如INDREDIENT_ID
,INGREDIENT_NAME
之类的列和DIM_AMOUNT
({{1},AMOUNT_ID
,AMOUNT
)来描述金额。还有UNITS
(DIM_ACTION
,ACTION_ID
,TYPE
,LENGTH
)来描述动作。您可以想出更多的东西。这些只是一些入门。
我要采取的任何步骤都可以放在UNITS
表中,该表将映射到所有维度表。没有逻辑步骤的任何步骤都将具有FACT_RECIPE_STEPS
值(即,搅拌5分钟将null
设为空)。
INGREDIENT_ID
可能看起来像这样:
FACT_RECIPE_STEPS
,RECIPE_ID
,RECIPE_STEP
,ACTION_STEP_ID
,INGREDIENT_ID
,AMOUNT_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_STEP
和FACT_RECIPE_STEPS
中将“ whisked”作为自己的配方(被称为“鸡蛋的whisked香料”) +并完全摆脱FACT_RECIPE_STEPS
表。这样,您可以轻松制作更复杂的食谱,例如“鸡蛋和煎饼早餐”,其中鸡蛋部分是该食谱的结果。