为此,我有三明治和厨师。
Sandwich 有一个键,它的主键 - 名称。
Chef 有其主键 - Cid,其他信息键,如姓名、年龄等。
我需要的关系是
SignatureSandwich,每位厨师都有一个三明治,这是他们的主要创作。一对一
LikesSandwich,每个厨师都可以喜欢吃任意数量的三明治(可能不包括他们自己的招牌三明治),并且任何数量的厨师都可以喜欢任何三明治。多对多
这是否只是通过两个关系来实现,每个关系都有外键 Cid 和 Sandwich.Name,还是有更好的方法呢?
为此,我有三明治和厨师。
Sandwich 有一个键,它的主键 - 名称。
Chef 有其主键 - Cid,其他信息键,如姓名、年龄等。
我需要的关系是
SignatureSandwich,每位厨师都有一个三明治,这是他们的主要创作。一对一
LikesSandwich,每个厨师都可以喜欢吃任意数量的三明治(可能不包括他们自己的招牌三明治),并且任何数量的厨师都可以喜欢任何三明治。多对多
这是否只是通过两个关系来实现,每个关系都有外键 Cid 和 Sandwich.Name,还是有更好的方法呢?
我看到SignatureSandwich它是 Chef 的一个属性,即 tblChef 中的一个列。SignatureSandwich应该与 tblSandwich.Name 有外键关系。
我将LikesSandwich使用一个新表 tblSandwichPreference 建模关系,该表有两列:Cid 和 SandwichName。
在 tblSandwichPreference 中,Cid 应该有一个指向 tblChef.Cid 的外键,而 SandwichName 应该有一个指向 tblSandwich.Name 的外键。
一些有用的查询:
-- Query all chefs who like a particular sandwich
SELECT * FROM tblSandwichPreference
JOIN tblChef ON tblChef.Cid = tblSandwichPreference.Cid
WHERE tblSandwichPreference.SandwichName = @SandwichName
-- Query all sandwiches preferred by a particular chef
SELECT * FROM tblSandwichPreference
JOIN tblSandwich ON tblSandwich.Name = tblSandwichPreference.SandwichName
WHERE tblSandwichPreference.Cid = @ChefID
所以像这样的东西?这是 mysql,如果您还没有使用它,请下载 mysql 工作台并对其进行修改。它让您深入了解 SQL 的工作原理。我过去常常手动编写这些东西,但可视化它真的很有帮助。

SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';
DROP SCHEMA IF EXISTS `mydb` ;
CREATE SCHEMA IF NOT EXISTS `mydb` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ;
USE `mydb` ;
-- -----------------------------------------------------
-- Table `mydb`.`Sandwiches`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `mydb`.`Sandwiches` ;
CREATE TABLE IF NOT EXISTS `mydb`.`Sandwiches` (
`SandwichName` VARCHAR(45) NOT NULL,
PRIMARY KEY (`SandwichName`),
UNIQUE INDEX `SandwichName_UNIQUE` (`SandwichName` ASC))
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`Chefs`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `mydb`.`Chefs` ;
CREATE TABLE IF NOT EXISTS `mydb`.`Chefs` (
`ChefID` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`Name` VARCHAR(45) NOT NULL,
`Age` INT UNSIGNED NOT NULL,
`SignatureSandwich` VARCHAR(45) NOT NULL,
PRIMARY KEY (`ChefID`, `SignatureSandwich`),
INDEX `fk_Chefs_Sandwiches_idx` (`SignatureSandwich` ASC),
CONSTRAINT `fk_SignatureSandwich`
FOREIGN KEY (`SignatureSandwich`)
REFERENCES `mydb`.`Sandwiches` (`SandwichName`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`SandwichLikes`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `mydb`.`SandwichLikes` ;
CREATE TABLE IF NOT EXISTS `mydb`.`SandwichLikes` (
`SandwichThatIsLiked` VARCHAR(45) NOT NULL,
`ChefThatLikes` INT UNSIGNED NOT NULL,
PRIMARY KEY (`SandwichThatIsLiked`, `ChefThatLikes`),
INDEX `fk_Sandwiches_has_Chefs_Chefs1_idx` (`ChefThatLikes` ASC),
INDEX `fk_Sandwiches_has_Chefs_Sandwiches1_idx` (`SandwichThatIsLiked` ASC),
CONSTRAINT `fk_SandwichThatIsLiked`
FOREIGN KEY (`SandwichThatIsLiked`)
REFERENCES `mydb`.`Sandwiches` (`SandwichName`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_ChefThatLikes`
FOREIGN KEY (`ChefThatLikes`)
REFERENCES `mydb`.`Chefs` (`ChefID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
SignatureSandwich 是微不足道的,只需在 Chef 上放一个 ForeignKey 即可进行三明治。
对于 LikesSandwich,您应该使用中间表,因为每个厨师可以喜欢很多三明治,而三明治可以被很多厨师喜欢。
您可以在中介表中知道厨师最喜欢的三明治过滤,您也可以通过在该中介中过滤来知道谁最喜欢三明治。