主键MySQL错误

时间:2013-05-19 19:09:46

标签: mysql syntax foreign-keys composite-key

我正在尝试创建一个数据库,我的一个表使用复合主键。这工作正常,直到我尝试使用第二个复合键将外键设置为单独的表。给出的错误是“ERROR 1005(HY000):无法创建表”.kesharaproducts \ production.frm'(错误号:150)“

这是代码。

create table stocks(
rawMatBatchID VARCHAR(4) NOT NULL,
finishedGoodsBatchID VARCHAR(4) NOT NULL,
rawMaterialID VARCHAR(4) NOT NULL,
finishedMaterialID VARCHAR(4) NOT NULL,
supplierID VARCHAR(5) NOT NULL,
rawMaterialType VARCHAR(10) NOT NULL,
finishedMaterialType VARCHAR(10) NOT NULL,
rawMatWeight VARCHAR(5) NOT NULL,
finishedGoodsWeightKg INT(5) NOT NULL,
finishedGoodsWeightG INT(5) NOT NULL,
finishedGoodsUnits INT(5) NOT NULL,
finishedGoodsDate VARCHAR(15) NOT NULL,
rawMatDate VARCHAR(15) NOT NULL,
PRIMARY KEY (finishedGoodsBatchID, rawMatBatchID),
CONSTRAINT FOREIGN KEY (finishedMaterialID) REFERENCES finishedMaterials(finishedMaterialID),
CONSTRAINT FOREIGN KEY (supplierID) REFERENCES supplierDetails(supplierID),
CONSTRAINT FOREIGN KEY (rawMaterialID) REFERENCES rawMaterials(rawMaterialID))ENGINE=INNODB;

上表使用复合主键。

create table transport(
transportID VARCHAR(4) NOT NULL,
vehicleID VARCHAR(4) NOT NULL,
finishedGoodsBatchID VARCHAR(4) NOT NULL,
finishedGoodsUnits INT(5) NOT NULL,
finishedGoodsWeightKg INT(5),
finishedGoodsWeightG INT(5),
transportDate VARCHAR(15),
CONSTRAINT PRIMARY KEY (transportID),
CONSTRAINT FOREIGN KEY (vehicleID) REFERENCES vehicles(vehicleID),
CONSTRAINT FOREIGN KEY (finishedGoodsBatchID) REFERENCES stocks(finishedGoodsBatchID)
)ENGINE=INNODB;

上面的表格使用了第一个复合键并且工作正常。

create table production(
productionBatchID VARCHAR(4) NOT NULL,
finishedMaterialID VARCHAR(4) NOT NULL,
rawMaterialID VARCHAR(4) NOT NULL,
productionDate VARCHAR(15),
rawMatBatchID VARCHAR(4),
initialWeight INT(5),
beforeWeight INT(5),
afterWeight INT(5),
finalWeight INT(5),
packingWeight INT(5),
noOfUnits INT(5),
wastage INT(5),
CONSTRAINT PRIMARY KEY (productionBatchID),
CONSTRAINT FOREIGN KEY (finishedMaterialID) REFERENCES finishedMaterials(finishedMaterialID),
CONSTRAINT FOREIGN KEY (rawMaterialID) REFERENCES rawMaterials(rawMaterialID),
CONSTRAINT FOREIGN KEY (rawMatBatchID) REFERENCES stocks(rawMatBatchID))ENGINE=INNODB;

但是在上面的表中,它使用第二个复合主要作为外键,它给出了错误。如何解决这个问题?这是最后三个表。创建所有其他引用的表。我没有在这里发布所有表格太长时间。当我从最后一个表中删除“CONSTRAINT FOREIGN KEY(rawMatBatchID)REFERENCES stock(rawMatBatchID)”并添加表时,它会被添加。但不是推荐第二个复合键......

3 个答案:

答案 0 :(得分:1)

外键应该与它引用的主键具有相同的列对。

您的transport表工作的原因是InnoDB支持SQL的有趣的非标准扩展,以便外键可以引用复合键中的一列,但仅当它引用左子集时列

您的production表仅引用所引用主键中的 second 列,并且无法以此方式工作。

我不确定你要用这个设计做什么。尽管InnoDB能够针对列的子集进行引用,但这是非标准SQL,不推荐使用。

最好在stocks主键中将两个列添加到引用它的两个表中,并创建一个复合外键来引用它复合主键。

答案 1 :(得分:1)

stocks 没有2个主键。它只有一个。它是一个复合键,由两部分组成:(finishedGoodsBatchID, rawMatBatchID)

如果要使用引用表的FOREIGN KEY约束,则应引用该表的主键(或唯一键)。整个。因此,在这种情况下,stocks的整个复合主键而不是它的一部分。

这也使transport的外键错误。 MySQL允许它,但是如果你这样离开就会遇到问题。外键应该能够以某种方式识别父表中的行,但(finishedGoodsBatchID)不能单独识别行(识别行)。

因此,transport定义应为:

CREATE TABLE transport(
    transportID VARCHAR(4) NOT NULL,
    vehicleID VARCHAR(4) NOT NULL,
    finishedGoodsBatchID VARCHAR(4) NOT NULL,
    rawMatBatchID VARCHAR(4) NOT NULL,                            -- added
    finishedGoodsUnits INT(5) NOT NULL,
    finishedGoodsWeightKg INT(5),
    finishedGoodsWeightG INT(5),
    transportDate VARCHAR(15),
    CONSTRAINT 
      PRIMARY KEY (transportID),
    CONSTRAINT 
      FOREIGN KEY (vehicleID) 
      REFERENCES vehicles(vehicleID),
    CONSTRAINT                                                    -- changed
      FOREIGN KEY (finishedGoodsBatchID, rawMatBatchID) 
      REFERENCES stocks (finishedGoodsBatchID, rawMatBatchID)
) ENGINE=INNODB;

同样的变化也应该在production表的定义中进行。

答案 2 :(得分:-1)

您正在引用尚未存在的表。禁用外键,创建表,然后重新启用外键。

SET foreign_key_checks = 0;

创建表格......

SET foreign_key_checks = 1;