当前位置: 首页 > 知识库问答 >
问题:

如何构造具有多个联接表的数据库

应俭
2023-03-14

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

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

{
    "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对象。每个食谱可以有不同数量的步骤和不同的配料分配给每一个步骤。

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

-- Table `dev_Recipe`.`recipe`

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

CREATE  TABLE IF NOT EXISTS `dev_Recipe`.`recipe` (

  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,

  `name` VARCHAR(255) NULL ,

  `description` TEXT NULL ,

  `author_id` INT UNSIGNED NOT NULL ,

  PRIMARY KEY (`id`) ,

  INDEX `author_id_idx` (`author_id` ASC) ,

  CONSTRAINT `author_id`

    FOREIGN KEY (`author_id` )

    REFERENCES `dev_Recipe`.`users` (`id` )

    ON DELETE NO ACTION

    ON UPDATE NO ACTION)

ENGINE = InnoDB;



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

-- Table `dev_Recipe`.`step`

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

CREATE  TABLE IF NOT EXISTS `dev_Recipe`.`step` (

  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,

  `recipe_id` INT UNSIGNED NOT NULL ,

  `step_number` INT UNSIGNED NOT NULL ,

  `description` TEXT NULL ,

  `timer` INT UNSIGNED NULL ,

  `image` VARCHAR(100) NULL ,

  PRIMARY KEY (`id`) ,

  INDEX `recipe_id_idx` (`recipe_id` ASC) ,

  CONSTRAINT `step_recipe_id`

    FOREIGN KEY (`recipe_id` )

    REFERENCES `dev_Recipe`.`recipe` (`id` )

    ON DELETE NO ACTION

    ON UPDATE NO ACTION)

ENGINE = InnoDB;


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

-- Table `dev_Recipe`.`ingredient`

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

CREATE  TABLE IF NOT EXISTS `dev_Recipe`.`ingredient` (

  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,

  `name` VARCHAR(45) NOT NULL ,

  `color` INT NOT NULL ,

  `img` VARCHAR(45) NULL ,

  PRIMARY KEY (`id`) )

ENGINE = InnoDB;


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

-- Table `dev_Recipe`.`step_ingredients`

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

CREATE  TABLE IF NOT EXISTS `dev_Recipe`.`step_ingredients` (

  `recipe_id` INT UNSIGNED NOT NULL ,

  `ingredient_id` INT UNSIGNED NOT NULL ,

  `step_id` INT UNSIGNED NOT NULL ,

  `amount` INT NULL ,

  `unit` VARCHAR(25) NULL ,

  INDEX `recipe_id_idx` (`recipe_id` ASC) ,

  INDEX `ingredient_id_idx` (`ingredient_id` ASC) ,

  INDEX `step_id_idx` (`step_id` ASC) ,

  PRIMARY KEY (`recipe_id`, `step_id`) ,

  CONSTRAINT `step_ing_recipe_id`

    FOREIGN KEY (`recipe_id` )

    REFERENCES `dev_Recipe`.`recipe` (`id` )

    ON DELETE NO ACTION

    ON UPDATE NO ACTION,

  CONSTRAINT `ingredient_step_ing_id`

    FOREIGN KEY (`ingredient_id` )

    REFERENCES `dev_Recipe`.`ingredient` (`id` )

    ON DELETE NO ACTION

    ON UPDATE NO ACTION,

  CONSTRAINT `step_ing_id`

    FOREIGN KEY (`step_id` )

    REFERENCES `dev_Recipe`.`step` (`id` )

    ON DELETE NO ACTION

    ON UPDATE NO ACTION)

ENGINE = InnoDB;

我做了另一个设计,其中食谱步骤以及步骤成分相结合。我认为第一种布局更容易查询,因为我只需查看step_firedents_idrecipe_id就可以通过step_firedents进行搜索,但我不确定。有什么想法吗?

共有1个答案

胡和煦
2023-03-14

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

  • 1到1
  • 1到多
  • 多对多

话虽如此,但您的模式一目了然地看起来很规范、很合乎逻辑。我要提醒的唯一一点是,对于带有self引用的类别,SQL中的递归可能会很棘手。

一个步骤可以在没有制作方法的情况下存在

用户与食谱是一对一的(正如Dan所提到的)

编辑:对于从菜谱到成分的双连接而不是单连接的问题,这里有一个与原始设计有关的标准化问题:是什么使step_ingredent和steprecipe_id保持相同的?现在还不能保证一贯性。如果您考虑数据设计,您实际上是说您认为您会连接这两个表很多,那么为什么不用一个不必要的FK将它们连接起来(不要这样做,否则事情会很快变得乱七八糟:))

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
 类似资料:
  • 问题内容: 所以我有四个桌子。每个表都有一个与前一个表ID相同的ID。因此,我的点击表中有一个ID和一个广告来源的ID。在广告表中,它有一个广告ID和一个来自其广告系列的ID。所以这是一个例子。 因此,要找出表4中的值从何而来,我需要遍历每个表并检查它们具有哪个ID。基本上,我想知道表1中的哪些值与表4中的值相关联。 表4中的内容是网站的访问者,表1中的内容是互联网广告。我想知道哪些访客来自哪些广

  • 问题内容: 根据我的研究,这是一个非常普遍的问题,通常有一个相当简单的解决方案。我的任务是更改几个查询,以 使所有结果都 进入 每组前3名 。最初,一切进展顺利,我使用了该站点的一些建议和答案来实现这一目标(最受欢迎的产品)。但是,由于多次加入,我在最后一个“最畅销产品”方面遇到了困难。 基本上,我需要 按#个产品的最高销售顺序来排序所有产品,其中每个供应商的最大产品数量为3。 我要联接多个表来创

  • 我在学习Kotlin的过程中遇到了一个我想不通的问题。我想在Kotlin中扩展Java类,并且能够在不同的情况下使用它的三个构造函数中的任何一个(基于我想抛出异常时所拥有的信息)。在java中,我的类将如下所示: 有人能建议我在Kotlin如何正确地做到这一点吗?

  • 问题内容: 我有三个表:,,和。 该表包含类别的名称和其类别的ID 。 在包含两列:为这篇文章的ID和该职位的类别的ID。 该表包含有关后多列-如,等 我在网址中有一个名为parent_id的变量,它对应于一个类别。我想列出所有属于parent_id值类别的帖子(而不是类别)。 例如,假设parent_id值为5。每个帖子可能属于ID为20的类别,但该类别属于父类别(其ID为5)。我想列出所有属于

  • 我试图连接4个表,其中一个表没有所有匹配的ID,但我仍然需要显示连接的结果,甚至对于没有相应ID的行。 下面是我所说的一个例子: 示例查询: 所以基本上我要做的是,如果tbl4没有tbl1_id,我仍然希望看到来自table1的结果,但为cnt显示0值...当我运行这个查询时,我得到了一堆重复的条目,数据看起来不正确。

  • 问题内容: 有没有一种方法可以在一个查询中包含多个语句(hibernate)? 这对我有用: 我在中得到了预期的结果。 但是我想要的是与它的构造器有一个新的实例。 例如这样: 或在 我也有兴趣使用DTO对象和DTO对象,但我无法读懂吗?那正确吗? 使用两个示例时,我的Spring Boot应用程序确实从错误开始。 最后我要一张地图 问题答案: 从技术上讲,根据JPQL select子句的定义,它将