可以/如何建立一个数据库,其中两个项目之间有多个关系

时间:2013-10-08 13:54:45

标签: database database-design

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

三明治有一个键,它的主键是 - 姓名。

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

我需要的关系是

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

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

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

3 个答案:

答案 0 :(得分:4)

我看到SignatureSandwich是Chef的一个属性,即tblChef中的一列。 SignatureSandwich应与tblSandwich.Name具有外键关系。

我将使用新表tblSandwichPreference建模LikesSandwich关系,该表有两列: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

答案 1 :(得分:2)

这样的事情?这是mysql,如果你还没有使用它,请下载mysql工作台并修改它。它为您提供了有关SQL如何工作的大量见解。我用手工编写这些东西,但可视化它确实很有帮助。

enter image description here

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;

答案 2 :(得分:1)

SignatureSandwich是微不足道的,只需将一把ForeignKey放在Chef上三明治。

对于LikesSandwich,您应该使用中间餐桌,因为每位厨师都喜欢很多三明治,许多厨师都喜欢吃三明治。

你可以知道在中间餐桌上过滤的厨师最喜欢的三明治,你也可以通过过滤中介来了解谁是三明治。