Дизайн базы данных рецептов - PullRequest
2 голосов
/ 11 апреля 2019

Я пытаюсь создать базу данных для хранения моих рецептов. Однако я не уверен, как это реализовать. Я смотрел на другие вопросы, подобные этому, но они не имеют такой же фокус, как и я.

Я предполагаю, что любое блюдо на самом деле является просто ингредиентом, который затем можно использовать в других блюдах или, в данном случае, в других ингредиентах. Любой ингредиент может иметь несколько рецептов. На данный момент каждый рецепт показывает, сколько нужно каждого ингредиента, но я также хочу знать, как эти ингредиенты сочетаются без подробного текстового описания.

Например, в тексте я бы описал один (очень плохой) рецепт яичницы-болтуньи так:

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: я наткнулся на рецепт функционального программирования Тирамису , который, хотя и очень сильно сфокусированный на методах, довольно хорошо отображает то, что я пытаюсь реализовать для своей базы данных.

Ответы [ 2 ]

2 голосов
/ 11 апреля 2019

Я думаю, что сбивает с толку то, что с рецептом нужно подумать о двух разных вещах: «Предметы» и «Шаги».

Одна структура базы данных, которая приходит на ум, это Структура звездной схемы , которая аккуратно разделяет эти идеи (на Dimension и Fact таблицы соответственно).

Краткое описание каждого:

  • Размер

    • «Состояние чего-то», т. Е. Запись просто для описания того, что это за вещь. Таблица адресов клиента будет примером таблицы измерений.
  • Факт

    • «Вещи, изменяющиеся со временем», то есть каждая запись относится к таблице измерений, но имеет изменяющиеся значения. Примером могут быть отправленные покупки с веб-сайта по адресу клиента. Адрес остается прежним, но посылки постоянно добавляются в таблицу.

Нельзя сказать, что таблицы измерений тоже не меняются; очевидно, что новые пользователи регистрируются на сайтах постоянно. В приведенном выше примере адреса, если клиент должен изменить свой адрес, новое значение primary key будет добавлено для нового адреса.

Теперь перейдем к примерам ваших рецептов:

Представь, что ты что-то готовишь. Я бы положил все, что вы держите в руках, в таблицу «измерений». Например: DIM_INGREDIENT (с такими столбцами, как INDREDIENT_ID, INGREDIENT_NAME) и DIM_AMOUNT (AMOUNT_ID, AMOUNT, UNITS) для описания сумм. И DIM_ACTION (ACTION_ID, TYPE, LENGTH, UNITS) для описания действия. Есть еще кое-что, что вы можете придумать; Вот несколько, чтобы начать.

Любые шаги, которые я предприму, могут быть в таблице FACT_RECIPE_STEPS, которая будет отображаться во все таблицы измерений. Любой шаг, который не имеет логического шага, будет иметь значение null (т.е. перемешивание в течение 5 минут будет иметь значение NULL для INGREDIENT_ID).

FACT_RECIPE_STEPS может выглядеть так:

RECIPE_ID, RECIPE_STEP, ACTION_STEP_ID, INGREDIENT_ID, AMOUNT_ID, ACTION_ID

Что сбивает с толку, так это «шаг» взбивания всего вместе. Я поместил это в другую таблицу 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

EDIT:

Я был немного неуверен в том, как сделать часть рецепта "Взбитые", и подумал, что, когда вы добавляете взбитую смесь в конечный результат, это все равно, что добавить в рецепт один ингредиент. Тем не менее, вам нужно приготовить смесь раньше, и она состоит из трех этапов. По сути, это как собственный маленький рецепт, и FACT_ACTION_STEP учитывает этот другой «рецепт», чтобы иметь возможность добавить результат на одну строку в таблицу FACT_RECIPE_STEPS.

Теперь, когда я думаю об этом немного больше, может быть, лучше просто назначить «Whisked» в качестве собственного рецепта в FACT_RECIPE_STEPS и DIM_INGREDIENT (что-то вроде «Взбитые специи для яиц») + и избавиться от него. таблицы FACT_ACTION_STEP в целом. Таким образом, вы можете легко сделать более сложные рецепты, такие как «Яйца и блинный завтрак», где часть «Яйца» является результатом этого рецепта.

2 голосов
/ 11 апреля 2019

Вы можете добавить некоторые другие поля в таблицы, но я считаю, что эта схема работает для вас.

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

EDIT

Допустим, вы хотите сохранить рецепт (X), который представляет собой комбинацию рецептов x и y плюс ингредиент z.

Для приготовления рецепта Х (большой Х),

в recipe, ingredients и technique таблицах, которые вы храните

  • х рецепт и w, t, r ингредиенты с техникой p
  • рецепт и b, n, m ингредиентов с техникой v
  • также z ингредиент с техникой f (для этого я забыл добавить поле ror_id как FK в таблице ингредиентов)

Вы можете определить 2 различных рецепта (x и y) как ингредиенты рецепта (X), используя таблицу recipe_ror. Эта таблица относится к разным рецептам как к одной (отношение многих ко многим между таблицами recipe и recipe_of_recipes)

Если вы также хотите сохранить технику для рецептов X, x или y (как, например, cook в вашем примере), вы также можете добавить поле t_id в качестве FK к recipe и recipe_of_recipes таблице.

...