2017-06-05 96 views
0

我已经看了好几篇文章,但没有找到我的问题的解决方案。我的怀疑是错误源于我试图用一个列引用两个不同表中的同一主键列。具体来说,该出价表具有也存在于投标人和item_round_status表中的外键simulation_id。出价表引用了这两个表的外键,但我希望在表中只使用一个simulation_id列。这是错误150问题的来源吗?从两个表中引用相同的外键列的MySQL错误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图也更新: UML diagram of three relevant tables

+0

什么是确切的错误信息文本?另外:[外键使用和错误信息](https://dev.mysql.com/doc/refman/5.7/en/innodb-foreign-key-constraints.html)PS什么“但我只想使用表中的一个simulation_id列“是什么意思? – philipxy

+0

@philipxy我唯一能看到的就是这个语句:“InnoDB允许一个外键引用任何索引列或者一组列,但是在被引用的表中,必须有一个索引,其中被引用的列被列为第一个列顺序相同“。投标人表键列是否为simulation_id,bidder_idx时,是否存在出价表列的顺序为simulation_id,round,item_id,bidder_idx的问题?是否在两个列之间导致问题? – german129

回答

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`) 

的 “参考表” 这里是竞价,在 “引用的列” 列表(IDX,simulation_id)。

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

果然,在投标人发现的最接近的是:

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

其中隐含声明了一个默认的唯一不为空指数,但像所有其他指标没有按从FK的专栏列表开始。

0

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, 

至于我可以告诉我正确了索引设置,但该代码被生成顺序错误。我使用了gui来创建出价表,出价者和item_round_status之间的关系,因为这两个表的模拟都是pk,所以它重复了那个列。当我使用mysql工作台前端工程师生成sql脚本时。我手动调整了投标人的外键,以引用为item_round_status生成的simulationid列,它改变了与该外键相关的索引。我手动将它们更改为正确的索引,但它在生成导致错误的脚本时似乎忽略了我的更改。