7

这是我第一次尝试将更复杂的对象存储到数据库中。我需要一些关于数据库设计的帮助。

我要存储并从数据库中重新生成的配方对象

{
    "id": 2345,
    "name": "cake",
    "description": "yummy cake",
    "categorys": [
        17,
        26
    ],
    "persons": 4,
    "author": 26,
    "language": "de",
    "unit": "en",
    "variantOf": 34,
    "specialTools": [
        34,
        44,
        10
    ],
    "img": "32598734.jpg",
    "estTime": 2777,
    "steps": {
        "1": {
            "title": "mix",
            "description": "mix all together",
            "img": "45854.jpg",
            "timer": null,
            "ingredients": [
                {
                    "name": "Butter",
                    "color": "#227799",
                    "amount": 150,
                    "unit": "g"
                },
                {
                    "name": "egg",
                    "color": "#aaff22",
                    "amount": 3,
                    "unit": "pc"
                },
                {
                    "name": "sugar",
                    "color": "#22ffff",
                    "amount": 50,
                    "unit": "g"
                }
            ]
        },
        "2": {
            "title": "bake",
            "description": "put it in the oven",
            "img": null,
            "timer": 2400,
            "ingredients": [
                {
                    "name": "butter",
                    "color": "#227799",
                    "amount": null,
                    "unit": null
                },
                {
                    "name": "sugar",
                    "color": "#22ffff",
                    "amount": null,
                    "unit": null
                },
                {
                    "name": "egg",
                    "color": "#aaff22",
                    "amount": null,
                    "unit": null
                }
            ]
        }
    }
}

最复杂的部分是steps对象。每个配方可以有不同数量的步骤,每个步骤分配不同的成分。

这是我做 的一个数据库设计数据库方案

recipe_id, step_id是外键。我想要不同表格中的所有内容,因为食谱应该可以按成分、类别...

用于生成最重要表的SQL 代码

-------------------------------------------------- -----

-- 表`dev_Recipe`.`recipe`

-------------------------------------------------- -----

如果不存在 `dev_Recipe`.`recipe`,则创建表(

  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,

  `name` VARCHAR(255) NULL ,

  `描述` TEXT NULL ,

  `author_id` INT UNSIGNED NOT NULL ,

  主键 (`id`) ,

  索引 `author_id_idx` (`author_id` ASC) ,

  约束`author_id`

    外键(`author_id`)

    参考 `dev_Recipe`.`users` (`id`)

    删除无操作

    更新无动作)

引擎 = InnoDB;



-------------------------------------------------- -----

-- 表`dev_Recipe`.`step`

-------------------------------------------------- -----

如果不存在 `dev_Recipe`.`step`,则创建表(

  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,

  `recipe_id` INT UNSIGNED NOT NULL ,

  `step_number` INT UNSIGNED NOT NULL ,

  `描述` TEXT NULL ,

  `timer` INT UNSIGNED NULL ,

  `image` VARCHAR(100) NULL ,

  主键 (`id`) ,

  索引 `recipe_id_idx` (`recipe_id` ASC) ,

  约束`step_recipe_id`

    外键(`recipe_id`)

    参考 `dev_Recipe`.`recipe` (`id`)

    删除无操作

    更新无动作)

引擎 = InnoDB;


-------------------------------------------------- -----

-- 表`dev_Recipe`.`ingredient`

-------------------------------------------------- -----

如果不存在 `dev_Recipe`.`ingredient`,则创建表(

  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,

  `name` VARCHAR(45) NOT NULL ,

  `颜色` INT NOT NULL ,

  `img` VARCHAR(45) NULL ,

  主键 (`id`) )

引擎 = InnoDB;


-------------------------------------------------- -----

-- 表`dev_Recipe`.`step_ingredients`

-------------------------------------------------- -----

如果不存在 `dev_Recipe`.`step_ingredients`,则创建表(

  `recipe_id` INT UNSIGNED NOT NULL ,

  `ingredient_id` INT UNSIGNED NOT NULL ,

  `step_id` INT UNSIGNED NOT NULL ,

  `数量` INT NULL ,

  `unit` VARCHAR(25) NULL ,

  索引 `recipe_id_idx` (`recipe_id` ASC) ,

  索引`ingredient_id_idx` (`ingredient_id` ASC) ,

  索引 `step_id_idx` (`step_id` ASC) ,

  主键(`recipe_id`,`step_id`),

  约束`step_ing_recipe_id`

    外键(`recipe_id`)

    参考 `dev_Recipe`.`recipe` (`id`)

    删除无操作

    更新无动作,

  约束`ingredient_step_ing_id`

    外键(`ingredient_id`)

    参考 `dev_Recipe`.`ingredient` (`id`)

    删除无操作

    更新无动作,

  约束`step_ing_id`

    外键(`step_id`)

    参考 `dev_Recipe`.`step` (`id`)

    删除无操作

    更新无动作)

引擎 = InnoDB;

由于我以前从未做过连接表,我不知道这是否是解决我的问题的正确方法。这是一个合理的设计以及如何优化它?

我做了另一个设计,在哪里recipes加入stepstepingredients我认为第一个布局更容易查询,因为我只能通过ingredients_id recipe_id查看来搜索step_ingredients,但我不确定。有什么想法吗?

数据库设计2

4

2 回答 2

7

关系数据库设计的主要内容是有 3 种类型的 FK 关系:

  • 1比1
  • 1对多
  • 多对多

话虽如此,您的架构一目了然,看起来规范化且合乎逻辑。我要注意的唯一一点是,对于具有自引用的类别,在 SQL 中递归可能会很棘手。

几点注意事项:

步骤成分需要已经具有 recipe_id 的步骤(可能为 null)

没有步骤可以存在步骤成分吗

没有配方也可以存在步骤

用户到配方是一对一的(正如丹所说)

编辑:对于从配方到成分的双连接而不是单连接的关注,这是我对原始设计的一个规范化问题:是什么让 step_ingredient 和 step recipe_id 保持相同?目前,无法保证一致性。如果您考虑数据设计,您实际上是在说您认为您会经常加入这两个表,所以为什么不将它们与不必要的 FK 连接起来(不要这样做,否则事情会很快变得混乱:))

您的第二个设计实际上也允许相同数量的连接,因为您已将 recipe_id 作为 PK 包含在 step 表中,然后它将成为 step_ingredient 中的 PK/FK,它将保证 recipe_id 的一致性。前任:

SELECT ingredient_id
FROM Recipe r
JOIN Step_ingredient si on si.step_recipe_id = r.recipe_id
JOIN Ingredient i on si.ingredient_id = i.ingredient_id

以及我最喜欢的数据库规范化入门链接:http ://en.wikipedia.org/wiki/Database_normalization

于 2013-04-12T12:58:54.953 回答
2

乍一看,它看起来非常好。但是,我不确定为什么类别和成分类别表需要父 ID。

此外,您还需要用户和食谱之间的多对多关系。您目前拥有一对一的样子。

于 2013-04-12T12:56:42.567 回答