【问题标题】:mysql error 150 from referencing same foreign key column in two tablesmysql错误150在两个表中引用相同的外键列
【发布时间】:2017-11-05 18:10:31
【问题描述】:

我浏览了很多帖子,但还没有找到解决我问题的方法。我的怀疑是错误源于我试图使用单个列来引用两个不同表中的相同主键列。具体来说,bid 表具有外键 simulation_id,它也存在于 bidder 和 item_round_status 表中。出价表引用了这两个表的外键,但我只想使用表中的一个 Simulation_id 列。这是错误 150 问题的根源吗?

-- -----------------------------------------------------
-- Table `kffg_simulations`.`item_round_status`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `kffg_simulations`.`item_round_status` (
  `simulation_id` INT NOT NULL ,
  `round` INT NOT NULL ,
  `clock_item_id` INT NOT NULL ,
  `posted_price` BIGINT NOT NULL ,
  `clock_price` BIGINT NOT NULL ,
  PRIMARY KEY (`simulation_id`, `round`, `clock_item_id`)  ,
  INDEX `fk_item_round_status_clock_item1_idx` (`clock_item_id` ASC)  ,
  INDEX `fk_item_round_status_simulation1_idx` (`simulation_id` ASC)  ,
  CONSTRAINT `fk_item_round_status_clock_item1`
    FOREIGN KEY (`clock_item_id`)
    REFERENCES `kffg_simulations`.`clock_item` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_item_round_status_simulation1`
    FOREIGN KEY (`simulation_id`)
    REFERENCES `kffg_simulations`.`simulation` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `kffg_simulations`.`bidder`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `kffg_simulations`.`bidder` (
  `simulation_id` INT NOT NULL ,
  `idx` INT NOT NULL ,
  `bidder_strategy_id` INT NOT NULL ,
  `budget` BIGINT NOT NULL ,
  PRIMARY KEY (`simulation_id`, `idx`)  ,
  INDEX `fk_bidder_simulation1_idx` (`simulation_id` ASC)  ,
  INDEX `fk_bidder_bidder_strategy1_idx` (`bidder_strategy_id` ASC)  ,
  CONSTRAINT `fk_bidder_simulation1`
    FOREIGN KEY (`simulation_id`)
    REFERENCES `kffg_simulations`.`simulation` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_bidder_bidder_strategy1`
    FOREIGN KEY (`bidder_strategy_id`)
    REFERENCES `kffg_simulations`.`bidder_strategy` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `kffg_simulations`.`bid_type`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `kffg_simulations`.`bid_type` (
  `id` INT NOT NULL AUTO_INCREMENT ,
  `name` VARCHAR(45) NOT NULL ,
  PRIMARY KEY (`id`)  )
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `kffg_simulations`.`bid_status`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `kffg_simulations`.`bid_status` (
  `id` INT NOT NULL AUTO_INCREMENT ,
  `description` VARCHAR(45) NOT NULL ,
  PRIMARY KEY (`id`)  )
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `kffg_simulations`.`bid`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `kffg_simulations`.`bid` (
  `simulation_id` INT NOT NULL ,
  `item_round_status_round` INT NOT NULL ,
  `clock_item_id` INT NOT NULL ,
  `bidder_idx` INT NOT NULL ,
  `quantity` INT NOT NULL ,
  `price` INT NOT NULL ,
  `bid_type_id` INT NOT NULL ,
  `switch_to_pea_category_id` INT NOT NULL ,
  `backstop` BIGINT NULL ,
  `bid_status_id` INT NOT NULL ,
  `processed_demand` INT NOT NULL ,
  PRIMARY KEY (`simulation_id`, `item_round_status_round`, `clock_item_id`, `bidder_idx`, `quantity`)  ,
  INDEX `fk_bid_item_round_status1_idx` (`simulation_id` ASC, `item_round_status_round` ASC, `clock_item_id` ASC)  ,
  INDEX `fk_bid_bidder1_idx` (`simulation_id` ASC, `bidder_idx` ASC)  ,
  INDEX `fk_bid_bid_type1_idx` (`bid_type_id` ASC)  ,
  INDEX `fk_bid_pea_category1_idx` (`switch_to_pea_category_id` ASC)  ,
  INDEX `fk_bid_bid_status1_idx` (`bid_status_id` ASC)  ,
  CONSTRAINT `fk_bid_item_round_status1`
    FOREIGN KEY (`simulation_id` , `item_round_status_round` , `clock_item_id`)
    REFERENCES `kffg_simulations`.`item_round_status` (`simulation_id` , `round` , `clock_item_id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_bid_bidder1`
    FOREIGN KEY (`bidder_idx` , `simulation_id`)
    REFERENCES `kffg_simulations`.`bidder` (`idx` , `simulation_id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_bid_bid_type1`
    FOREIGN KEY (`bid_type_id`)
    REFERENCES `kffg_simulations`.`bid_type` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_bid_pea_category1`
    FOREIGN KEY (`switch_to_pea_category_id`)
    REFERENCES `kffg_simulations`.`pea_category` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_bid_bid_status1`
    FOREIGN KEY (`bid_status_id`)
    REFERENCES `kffg_simulations`.`bid_status` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

已更新以显示错误消息:

------------------------
LATEST FOREIGN KEY ERROR
------------------------
170604 21:52:27 Error in foreign key constraint of table kffg_simulations/bid:

    FOREIGN KEY (`simulation_id` , `item_round_status_round` , `clock_item_id`)
    REFERENCES `kffg_simulations`.`item_round_status` (`simulation_id` , `round` , `clock_item_id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_bid_bidder1`
    FOREIGN KEY (`bidder_idx` , `simulation_id`)
    REFERENCES `kffg_simulations`.`bidder` (`idx` , `simulation_id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_bid_bid_type1`
    FOREIGN KEY (`bid_type_id`)
    REFERENCES `kffg_simulations`.`bid_type` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_bid_pea_category1`
    FOREIGN KEY (`switch_to_pea_category_id`)
    REFERENCES `kffg_simulations`.`pea_category` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_bid_bid_status1`
    FOREIGN KEY (`bid_status_id`)
    REFERENCES `kffg_simulations`.`bid_status` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB:
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html
for correct foreign key definition.

还更新了 uml 图:

【问题讨论】:

  • 确切的错误消息文本是什么?另外:Foreign Key Usage and Error Information PS“但我只想使用表中的一个 Simulation_id 列”是什么意思?
  • @philipxy 我唯一能看到的是这条语句:“InnoDB 允许外键引用任何索引列或列组。但是,在引用的表中,必须有一个索引,其中引用的列按相同顺序列为第一列。"当bidder表键列是simulation_id、bidder_idx时,是否存在bid表列顺序为simulation_id、round、item_id、bidder_idx的问题?之间的列会导致问题吗?

标签: mysql foreign-keys mysql-error-150


【解决方案1】:

Foreign Key Usage and Error Information 提供有关 FK(外键)的信息。

您可以通过查看 SHOW ENGINE INNODB STATUS 的输出来获得最近 InnoDB 外键错误的详细说明。

InnoDB 允许外键引用任何索引列或列组。但是,在被引用的表中,必须有一个索引,其中被引用的列以相同的顺序作为第一列列出。

出价:

FOREIGN KEY (`bidder_idx` , `simulation_id`)
REFERENCES `kffg_simulations`.`bidder` (`idx` , `simulation_id`)

这里的“引用表”为bidder,“引用列”列表为(idx,simulation_id)。

Cannot find an index in the referenced table where the
referenced columns appear as the first columns,

果然,在bidder中我们找到的最接近的是:

PRIMARY KEY (`simulation_id`, `idx`)  ,

它隐式声明了一个默认的唯一非空索引,但与所有其他索引一样,它并不以 FK 的列列表开头。

【讨论】:

    【解决方案2】:

    Philipxy 感谢您对这个问题的帮助。您在评论中说投标人的外键错误是正确的。由于某种原因,mysql 工作台以错误的顺序生成了代码中的列。 mysqlworkbench提供的代码如下:

      CONSTRAINT `fk_bid_bidder1`
        FOREIGN KEY (`bidder_idx` , `simulation_id`)
        REFERENCES `kffg_simulations`.`bidder` (`idx` , `simulation_id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
    

    以下代码可以正常工作:

      CONSTRAINT `fk_assignment_bidder1`
        FOREIGN KEY (`bidder_simulation_id` , `bidder_idx`)
        REFERENCES `kffg_simulations`.`bidder` (`simulation_id` , `idx`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
    

    据我所知,我已正确设置了索引,但生成的代码顺序错误。

    (我使用 mysql workbench 正向工程师生成 sql 脚本。我使用 gui 来创建投标表、投标者和 item_round_status 之间的关系。由于这两个表的模拟 ID 为 pk 它复制了该列。当我手动调整投标人的外键以引用为 item_round_status 生成的 Simulationid 列,它更改了与该外键相关的索引。我手动将它们更改为正确的索引,但在生成导致错误的脚本时似乎忽略了我的更改。)

    【讨论】:

      猜你喜欢
      • 2010-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-27
      • 1970-01-01
      • 2016-08-18
      相关资源
      最近更新 更多