2

我正在创建一个食谱应用程序来帮助我妻子的蛋糕爱好。这个想法是创建一个食谱数据库来保存她所有的蛋糕食谱。

每个食谱都有多种成分。每种成分都有一个测量值(gm、ml、茶匙等),然后是一个数量。

我了解如何创建“配方”和“成分”表以及如何将 2 与连接表“配方_成分”链接起来,但是我正在努力解决如何实现测量和数量字段。

任何有更多数据库经验的人都可以提出一个数据库方案或有任何技巧来处理这个问题吗?

4

2 回答 2

8

你有一些选择,和大多数事情一样,你可以走简单的路线(尼克库恩斯在我打字时发布了一个很好的例子)或逐渐参与更多的路线。以下是一些关于您如何看待这项工作的问题,您可以问自己:

  1. 您想要测量的一致性吗?(您是否要始终为茶匙显示“tsp”,或者可以像尼克的示例中那样自由形式)
  2. 您需要多久添加一次单位?随着时间的推移,您是否需要添加 dram 或 hogshead 或任何单位,或者您可能只是坚持基础?

一个好的中间立场是这样的

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 表在这里完成了大部分工作,将所有内容捆绑在一起。

于 2017-08-12T23:32:03.313 回答
1

像这样的东西应该工作:

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`)
)

这包含一个配方表(每个配方一个条目),用于保存配方名称、描述和一组指令;成分表,其中包含可能成分的列表,包括成分名称;以及一个交叉引用表,用于将配方与成分联系起来,包括配方中成分的数量和单位。

于 2017-08-12T22:53:40.253 回答