2013-05-19 118 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

謝謝!這實際上是有道理的! :) –