运行脚本时出现MySQL错误“无法添加外键约束”

时间:2015-12-09 21:34:11

标签: mysql sql

我使用MySQL Workbench创建了一个模式,将其导出为脚本,然后在我的MySQL本地服务器上运行该脚本。一切都有效,除了'会员'表。当它创建此表时,我得到错误1215:无法添加外键约束。

CREATE SCHEMA IF NOT EXISTS `endor` DEFAULT CHARACTER SET utf8 ;
USE `endor` ;


CREATE TABLE IF NOT EXISTS `endor`.`activity` (
  `activityid` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45) NULL,
  PRIMARY KEY (`activityid`))
ENGINE = InnoDB;


CREATE TABLE IF NOT EXISTS `endor`.`resource` (
  `resourceid` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45) NULL,
  `location` VARCHAR(45) NULL,
  `time_checkedout` VARCHAR(45) NULL,
  `activity_activityid` INT NULL,
  PRIMARY KEY (`resourceid`),
  INDEX `fk_resource_activity1_idx` (`activity_activityid` ASC),
  CONSTRAINT `fk_resource_activity1`
    FOREIGN KEY (`activity_activityid`)
    REFERENCES `endor`.`activity` (`activityid`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;



CREATE TABLE IF NOT EXISTS `endor`.`treasury` (
  `treasuryid` INT NOT NULL AUTO_INCREMENT,
  `treasurer_name` VARCHAR(45) NULL,
  PRIMARY KEY (`treasuryid`))
ENGINE = InnoDB;



CREATE TABLE IF NOT EXISTS `endor`.`account` (
  `accountid` INT NOT NULL AUTO_INCREMENT,
  `type` VARCHAR(45) NULL,
  `balance` INT NULL,
  `treasury_treasuryid` INT NULL,
  PRIMARY KEY (`accountid`),
  INDEX `fk_account_treasury1_idx` (`treasury_treasuryid` ASC),
  CONSTRAINT `fk_account_treasury1`
    FOREIGN KEY (`treasury_treasuryid`)
    REFERENCES `endor`.`treasury` (`treasuryid`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


CREATE TABLE IF NOT EXISTS `endor`.`member` (
  `memberid` INT NOT NULL AUTO_INCREMENT,
  `fname` VARCHAR(45) NULL,
  `lname` VARCHAR(45) NULL,
  `email` VARCHAR(45) NULL,
  `type` VARCHAR(45) NULL,
  `resource_resourceid` INT NULL,
  `resource_activity_activityid` INT NULL,
  `treasury_treasuryid` INT NULL,
  `account_accountid` INT NULL,
  PRIMARY KEY (`memberid`),
  INDEX `fk_member_resource1_idx` (`resource_resourceid` ASC,                   `resource_activity_activityid` ASC),
  INDEX `fk_member_treasury1_idx` (`treasury_treasuryid` ASC),
  INDEX `fk_member_account1_idx` (`account_accountid` ASC),
  CONSTRAINT `fk_member_resource1`
    FOREIGN KEY (`resource_resourceid` , `resource_activity_activityid`)
    REFERENCES `endor`.`resource` (`resourceid` , `activity_activityid`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_member_treasury1`
    FOREIGN KEY (`treasury_treasuryid`)
    REFERENCES `endor`.`treasury` (`treasuryid`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_member_account1`
    FOREIGN KEY (`account_accountid`)
    REFERENCES `endor`.`account` (`accountid`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;



CREATE TABLE IF NOT EXISTS `endor`.`accounts_payable` (
  `apid` INT NOT NULL AUTO_INCREMENT,
  `treasury_treasuryid` INT NULL,
  PRIMARY KEY (`apid`),
  INDEX `fk_accounts_payable_treasury1_idx` (`treasury_treasuryid` ASC),
  CONSTRAINT `fk_accounts_payable_treasury1`
    FOREIGN KEY (`treasury_treasuryid`)
    REFERENCES `endor`.`treasury` (`treasuryid`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;



CREATE TABLE IF NOT EXISTS `endor`.`accounts_receivable` (
  `arid` INT NOT NULL AUTO_INCREMENT,
  `treasury_treasuryid` INT NULL,
  PRIMARY KEY (`arid`),
  INDEX `fk_accounts_receivable_treasury1_idx` (`treasury_treasuryid` ASC),
  CONSTRAINT `fk_accounts_receivable_treasury1`
    FOREIGN KEY (`treasury_treasuryid`)
    REFERENCES `endor`.`treasury` (`treasuryid`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

2 个答案:

答案 0 :(得分:0)

看来FK activity_activityid是通过资源而不是活动引用的。

CONSTRAINT `fk_member_resource1`
FOREIGN KEY (`resource_resourceid` , `resource_activity_activityid`)
REFERENCES `endor`.`resource` (`resourceid` , `activity_activityid`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,

尝试将上述内容更改为:

 CONSTRAINT `fk_member_resource1`
FOREIGN KEY (`resource_resourceid`)
REFERENCES `endor`.`resource` (`resourceid`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
 CONSTRAINT `fk_member_activity1`
FOREIGN KEY (`activity_activityid`)
REFERENCES `endor`.`activity` (`activityid`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,

答案 1 :(得分:0)

您正在尝试创建此外键:

CONSTRAINT `fk_member_resource1`
  FOREIGN KEY (`resource_resourceid` , `resource_activity_activityid`)
  REFERENCES `endor`.`resource` (`resourceid` , `activity_activityid`)

endorresource的主键只是(resourceid)。您的外键不应引用非关键字段。

此外,您应该考虑表endormember是否需要列resource_activity_activityid。如果要求它与引用的activity_activity_id行的resource列相同,那么您的架构会因其存在而非规范化。如果您将其保留,那么您可以保留成员和资源不同意相应活动ID的可能性。

有时数据库是故意非规范化的,通常是出于性能原因,但我现在还没有看到任何理由。