2

为此,我有三明治和厨师。

Sandwich 有一个键,它的主键 - 名称。

Chef 有其主键 - Cid,其他信息键,如姓名、年龄等。

我需要的关系是

SignatureSandwich,每位厨师都有一个三明治,这是他们的主要创作。一对一

LikesSandwich,每个厨师都可以喜欢吃任意数量的三明治(可能不包括他们自己的招牌三明治),并且任何数量的厨师都可以喜欢任何三明治。多对多

这是否只是通过两个关系来实现,每个关系都有外键 Cid 和 Sandwich.Name,还是有更好的方法呢?

4

3 回答 3

4

我看到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
于 2013-10-08T14:03:06.330 回答
2

所以像这样的东西?这是 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;
于 2013-10-08T14:22:34.570 回答
1

SignatureSandwich 是微不足道的,只需在 Chef 上放一个 ForeignKey 即可进行三明治。

对于 LikesSandwich,您应该使用中间表,因为每个厨师可以喜欢很多三明治,而三明治可以被很多厨师喜欢。

您可以在中介表中知道厨师最喜欢的三明治过滤,您也可以通过在该中介中过滤来知道谁最喜欢三明治。

于 2013-10-08T14:01:32.670 回答