如何用多个连接表构造数据库
这是我第一次尝试将更复杂的对象存储到数据库中。 我需要一些关于数据库设计的帮助。
我想要从数据库中存储和重新生成配方对象
{
"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代码
-- -----------------------------------------------------
-- 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;由于我之前从未做过连接表,我不知道这是否是解决我的问题的正确方法。 这是一个合理的设计和如何优化它?
我做了另一个设计, recipes加入step和step与ingredients 。 我认为第一个布局更容易查询,因为我可以通过仅查看step_ingredients通过ingredients_id recipe_id进行搜索,但我不确定。 有什么想法吗?

关系数据库设计的主要内容是有三种类型的FK关系:
话虽如此,你的模式看起来很正常和合乎逻辑。 我唯一要注意的是,对于具有自引用的类别,SQL中的递归可能会很棘手。
一些注意事项:
步骤成分需要已经有一个recipe_id(可能为空)的步骤,
没有一步就可以存在一个步骤成分
没有配方就可以存在一个步骤
用户对食谱是一对一的(如丹提到的)
编辑:关于双连接而不是单一连接从食谱到成分的关注,这里是一个正常化的问题,我很难与原始设计:什么使step_ingredient和step recipe_id保持一致? 现在,不能保证一致性。 如果你考虑数据设计,你真的说你认为你会加入这两个表很多,所以为什么不把它们连接到一个不必要的FK(不要这样做,否则事情会变得很快:))
您的第二个设计实际上也允许相同数量的连接,因为您已将recipe_id作为PK包含在步骤表中,然后在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
乍一看,它看起来非常好。 但是,我不确定为什么类别和成分类别表需要父母ID。
此外,您需要用户和食谱之间的多对多关系。 你现在有什么看起来像一对一。
链接地址: http://www.djcxy.com/p/86275.html上一篇: How to structure a database with multiple join tables
下一篇: ERROR 1215: Cannot add foreign key constraint when using ON DELETE SET NULL
