Схема базы данных для рецепта / ингредиента / измерения / количества

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

Каждый рецепт будет иметь несколько ингредиентов. Каждый ингредиент будет иметь измерение (г, мл, чайные ложки и т. Д.), А затем количество.

Я понимаю, как создавать таблицы «рецепты» и «ингредиенты» и как связать 2 с соединительной таблицей «recipe_ingredients», однако я борюсь с тем, как затем реализовать поля измерения и количества.

Может ли кто-нибудь с немного большим опытом работы с базами данных предложить схему базы данных или есть какие-либо советы для этого?

1

Решение

У вас есть несколько вариантов для этого, и, как и для большинства других вещей, вы можете пойти по простому маршруту (Ник Кунс опубликовал хороший пример, когда я это пишу) или по более сложным маршрутам. Вот несколько вопросов, чтобы спросить себя о том, как вы видите это работает:

  1. Вы хотите единообразия в ваших измерениях? (Вы хотите всегда показывать «чайную ложку» для чайной ложки, или она может быть произвольной, как в примере Ника)
  2. Как часто вам нужно будет добавлять юниты? Нужно ли вам добавлять драм, свинью или что-то еще в виде единиц со временем, или вы просто придерживаетесь основ?

Хорошая золотая середина будет что-то вроде

CREATE TABLE `recipe` (
`recipe_id`    INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`name`         VARCHAR(128) DEFAULT NULL,
`description`  TEXT,
`instructions` TEXT,
PRIMARY KEY (`recipe_id`)
)

CREATE TABLE `ingredient` (
`ingredient_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`recipe_id`     INT(10) UNSIGNED NOT NULL,
`ingredient`    VARCHAR(64) DEFAULT NULL,
`amount`        DECIMAL(4, 2) DEFAULT NULL,
`unit`          ENUM ('tsp', 'tbsp', 'oz', 'g', 'lb', 'cup', 'gallon', 'pinch') DEFAULT NULL,
PRIMARY KEY (`ingredient_id`)
)

Это удовлетворяет # 1, применяя набор единиц, что приятно. Недостатком является то, что вы должны изменить свою таблицу, чтобы обновить единицы. Также может быть сложнее поддерживать передний план в актуальном состоянии с помощью действительных вариантов.

Затем вы можете добавить таблицу для единиц измерения и ссылаться на нее по внешнему ключу из таблицы ингредиентов следующим образом:

CREATE TABLE `unit` (
`unit_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`label`   VARCHAR(64) DEFAULT NULL,
`sort`    INT(10) UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (`unit_id`),
UNIQUE KEY `unit_label_uk` (`label`)
)

CREATE TABLE `ingredient` (
`ingredient_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`unit_id`       INT(10) UNSIGNED NOT NULL,
`recipe_id`     INT(10) UNSIGNED NOT NULL,
`ingredient`    VARCHAR(64) DEFAULT NULL,
`amount`        DECIMAL(4, 2) DEFAULT NULL,
`sort`          INT(10) UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (`ingredient_id`)
)

Это удовлетворяет # 1 и # 2, позволяя вам легко управлять вашими юнитами и получать доступ к списку для использования в вашем внешнем интерфейсе, так что вам не придется изменять свой внешний интерфейс при смене юнитов.

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

РЕДАКТИРОВАТЬ:
На ваш комментарий я бы настроил это так:

CREATE TABLE `recipe` (
`recipe_id`    INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`name`         VARCHAR(128) NOT NULL,
`description`  TEXT,
`instructions` TEXT,
PRIMARY KEY (`recipe_id`)
)

CREATE TABLE `ingredient` (
`ingredient_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`label`         VARCHAR(64) NOT NULL,
`sort`          INT(10) UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (`ingredient_id`)
UNIQUE KEY `ingredient_label_uk` (`label`)
)

CREATE TABLE `unit` (
`unit_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`label`   VARCHAR(64) DEFAULT NULL,
`sort`    INT(10) UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (`unit_id`),
UNIQUE KEY `unit_label_uk` (`label`)
)

CREATE TABLE `recipe_ingredient` (
`recipe_ingredient_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`recipe_id`            INT(10) UNSIGNED NOT NULL,
`ingredient_id`        INT(10) UNSIGNED NOT NULL,
`unit_id`              INT(10) UNSIGNED NOT NULL,
`amount`               DECIMAL(4, 2) DEFAULT NULL,
`sort`                 INT(10) UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (`recipe_ingredient_id`)
)

Ваша таблица recipe_ingredient выполняет большую часть работы здесь, связывая все вместе.

4

Другие решения

Примерно так должно работать:

CREATE TABLE `recipe` (
`recipe_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(128) DEFAULT NULL,
`description` text,
`instructions` text,
PRIMARY KEY (`recipe_id`)
)

CREATE TABLE `ingredient` (
`ingredient_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`ingredient` varchar(64) DEFAULT NULL,
PRIMARY KEY (`ingredient_id`)
)

CREATE TABLE `xref_recipe_ingredient` (
`recipe_id` int(10) unsigned NOT NULL,
`ingredient_id` int(10) unsigned NOT NULL,
`amount` decimal(4,2) DEFAULT NULL,
`unit` varchar(8) DEFAULT NULL,
INDEX (`recipe_id`)
)

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

0

По вопросам рекламы [email protected]