2013-05-19 109 views
0

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

下面是代码。

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股票(rawMatBatchID)”并添加它添加的表时。但不能与第二个复合键的引用...

+0

错误1005(HY000):无法创建表'.kesharaproducts \ production.frm'(errno:150) –

回答

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表的definitioon来完成了。

-1

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

SET foreign_key_checks = 0; 

创建表...

SET foreign_key_checks = 1; 
+0

不,这些是最后三张表。所有其他引用的表格都已创建。我没有在这里发布所有表格,时间太长了。当我从最后一个表中删除“CONSTRAINT FOREIGN KEY(rawMatBatchID)REFERENCES股票(rawMatBatchID)”并添加它添加的表时。但是不推荐到第二个组合键。 –

1

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

transport表工作的原因是InnoDB支持一个有趣的非标准扩展到SQL,这样一个外键可以复合键引用一列,但只有当它引用的列的左子集。

production您的production表只引用第二个列在引用的主键,它不能这样工作。

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

这将是更好地在stocks主键添加引用它既表,并进行了复合外键引用一个复合主键。

+0

谢谢!这实际上是有道理的! :) –