web-dev-qa-db-ja.com

エラーコード:1215。MySQLワークベンチでデータベースを作成中に外部キー制約を追加できません

Mysqlワークベンチでこのdbのモデルを作成しましたが、スクリプトを実行してテーブルを作成すると、「エラーコード:1215。外部キー制約を追加できません」というメッセージが表示されます。

スクリプトの最後で支払いテーブルに到達すると、エラーがポップアップ表示されます。私は過去1日間それを見ていて、オンラインで見つけたソリューションに基づいてあちこちで微調整を行っていますが、何も機能しません。

どんな助けでも大歓迎です。

-- MySQL Script generated by MySQL Workbench
-- Thu Dec  7 14:01:08 2017
-- Model: New Model    Version: 1.0
-- MySQL Workbench Forward Engineering

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';

-- -----------------------------------------------------
-- Schema game_rental
-- -----------------------------------------------------
DROP SCHEMA IF EXISTS `game_rental` ;

-- -----------------------------------------------------
-- Schema game_rental
-- -----------------------------------------------------
CREATE SCHEMA IF NOT EXISTS `game_rental` ;
USE `game_rental` ;

-- -----------------------------------------------------
-- Table `game_rental`.`platform`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `game_rental`.`platform` ;

CREATE TABLE IF NOT EXISTS `game_rental`.`platform` (
  `platform_id` TINYINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(25) NOT NULL,
  PRIMARY KEY (`platform_id`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;


-- -----------------------------------------------------
-- Table `game_rental`.`member`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `game_rental`.`member` ;

CREATE TABLE IF NOT EXISTS `game_rental`.`member` (
  `member_id` SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `first_name` VARCHAR(45) NOT NULL,
  `last_name` VARCHAR(45) NOT NULL,
  `email` VARCHAR(50) NOT NULL,
  PRIMARY KEY (`member_id`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;


-- -----------------------------------------------------
-- Table `game_rental`.`game`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `game_rental`.`game` ;

CREATE TABLE IF NOT EXISTS `game_rental`.`game` (
  `game_id` SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `title` VARCHAR(255) NOT NULL,
  `publisher` VARCHAR(45) NOT NULL,
  `rental_duration` TINYINT UNSIGNED NOT NULL DEFAULT 3,
  `rental_rate` DECIMAL(4,2) NOT NULL DEFAULT 5.00,
  `replacement_cost` DECIMAL(5,2) NOT NULL DEFAULT 50.00,
  PRIMARY KEY (`game_id`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;


-- -----------------------------------------------------
-- Table `game_rental`.`game_platform`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `game_rental`.`game_platform` ;

CREATE TABLE IF NOT EXISTS `game_rental`.`game_platform` (
  `game_id` SMALLINT UNSIGNED NOT NULL,
  `platform_id` TINYINT UNSIGNED NOT NULL,
  PRIMARY KEY (`game_id`, `platform_id`),
  CONSTRAINT `fk_game_id_plt`
    FOREIGN KEY (`game_id`)
    REFERENCES `game_rental`.`game` (`game_id`)
    ON DELETE RESTRICT
    ON UPDATE CASCADE,
  CONSTRAINT `fk_platform_id`
    FOREIGN KEY (`platform_id`)
    REFERENCES `game_rental`.`platform` (`platform_id`)
    ON DELETE RESTRICT
    ON UPDATE CASCADE)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;

CREATE INDEX `fk_platform_id` ON `game_rental`.`game_platform` (`platform_id` ASC);


-- -----------------------------------------------------
-- Table `game_rental`.`inventory`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `game_rental`.`inventory` ;

CREATE TABLE IF NOT EXISTS `game_rental`.`inventory` (
  `inventory_id` MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `game_id` SMALLINT UNSIGNED NOT NULL,
  PRIMARY KEY (`inventory_id`),
  CONSTRAINT `fk_game_id_inv`
    FOREIGN KEY (`game_id`)
    REFERENCES `game_rental`.`game` (`game_id`)
    ON DELETE RESTRICT
    ON UPDATE CASCADE)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;

CREATE INDEX `idx_fk_game_id` ON `game_rental`.`inventory` (`game_id` ASC);


-- -----------------------------------------------------
-- Table `game_rental`.`rental`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `game_rental`.`rental` ;

CREATE TABLE IF NOT EXISTS `game_rental`.`rental` (
  `rental_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `rental_date` DATETIME NOT NULL,
  `inventory_id` MEDIUMINT UNSIGNED NOT NULL,
  `member_id` SMALLINT UNSIGNED NOT NULL,
  `return_date` DATETIME NULL DEFAULT NULL,
  `staff_id` TINYINT UNSIGNED NOT NULL,
  PRIMARY KEY (`rental_id`),
  CONSTRAINT `fk_inventory_id`
    FOREIGN KEY (`inventory_id`)
    REFERENCES `game_rental`.`inventory` (`inventory_id`)
    ON DELETE RESTRICT
    ON UPDATE CASCADE,
  CONSTRAINT `fk_member_id`
    FOREIGN KEY (`member_id`)
    REFERENCES `game_rental`.`member` (`member_id`)
    ON DELETE RESTRICT
    ON UPDATE CASCADE)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;

CREATE INDEX `idx_fk_inventory_id` ON `game_rental`.`rental` (`inventory_id` ASC);

CREATE INDEX `idx_fk_member_id_rent` ON `game_rental`.`rental` (`member_id` ASC);


-- -----------------------------------------------------
-- Table `game_rental`.`payment`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `game_rental`.`payment` ;

CREATE TABLE IF NOT EXISTS `game_rental`.`payment` (
  `payment_id` SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `member_id` SMALLINT UNSIGNED NOT NULL,
  `rental_id` INT UNSIGNED NOT NULL,
  `amount` DECIMAL(5,2) NOT NULL,
  `payment_date` DATETIME NOT NULL,
  PRIMARY KEY (`payment_id`),
  CONSTRAINT `fk_rental_id`
    FOREIGN KEY (`rental_id`)
    REFERENCES `game_rental`.`rental` (`rental_id`)
    ON DELETE SET NULL
    ON UPDATE CASCADE,
  CONSTRAINT `fk_member_id`
    FOREIGN KEY (`member_id`)
    REFERENCES `game_rental`.`member` (`member_id`)
    ON DELETE RESTRICT
    ON UPDATE CASCADE)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;

CREATE INDEX `idx_fk_member_id_pay` ON `game_rental`.`payment` (`member_id` ASC);

CREATE INDEX `fk_rental_id` ON `game_rental`.`payment` (`rental_id` ASC);


SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
2
Brian McNamara

問題は、支払い時の最初の外部キーにあります。

CONSTRAINT `fk_rental_id`
    FOREIGN KEY (`rental_id`)
    REFERENCES `game_rental`.`rental` (`rental_id`)
    ON DELETE SET NULL
    ON UPDATE CASCADE,

基本的に、あなたが言っていることは、game_rental.rentalからのDELETEがある場合、支払いテーブルで参照されているすべてのrental_idがnullに設定されるということです。

ドキュメントから( https://dev.mysql.com/doc/refman/5.7/en/create-table-foreign-keys.html ):

SET NULL:親テーブルから行を削除または更新し、子テーブルの1つまたは複数の外部キー列をNULLに設定します。 ON DELETE SET NULL句とON UPDATE SET NULL句の両方がサポートされています。

SET NULLアクションを指定する場合は、子テーブルの列をNOT NULLとして宣言していないことを確認してください。

最後の行ですべてが明確になっているはずです。rental_idは支払い時にNOT NULLに設定されているため、問題があります。 paymentテーブルからrental_idのNOT NULL制限を削除するか、 "ON DELETE SET NULL"を削除する必要があります。

最後に;その後、別のエラーが発生します。

Can't write; duplicate key in table 'payment'

名前から

CONSTRAINT `fk_member_id`

最初にgame_rental.rentalで使用されます。そのCONSTRAINTの支払いテーブルの名前を変更する必要があります。

2
Mauricio Cacho