2014-07-09 138 views
1

我對SQL很陌生,我試圖定義一個2表HospitalHospital_Address,但是當我試圖在Hospital_Address中添加外鍵時,它會拋出一個錯誤: "1215: Cannot add foreign keyMySQL錯誤代碼1215:無法添加外鍵約束

create table Hospital (
      HId Int not null, 
      HName varchar(40) not null, 
      HDept int, Hbed Int, 
     HAreaCd int not null, 
     Primary Key (HId) 
        ); 

create table Hospital_Address (
       HAreaCd Int not null, 
        HArea varchar(40) not null, 
        HCity varchar(40), 
        HAdd1 varchar(40), 
        HAdd2 varchar(40), 
        Primary Key (HArea), 
       foreign key (HAreaCd) references Hospital (HAreaCd)); 

請幫我在這方面。在此先感謝。

回答

5

MySQL的要求有對父HospitalHAreaCd列的索引,以便您在引用該列一個FOREIGN KEY約束。

規範模式是FOREIGN KEY引用父表的PRIMARY KEY,儘管MySQL擴展了這一點以允許FOREIGN KEY引用一個UNIQUE KEY的列,InnoDB擴展了它(超出了SQL標準),並允許一個FOREIGN KEY引用任何一組列,只要有一個以這些列作爲引導列的索引(按照外鍵約束中指定的相同順序)。(也就是說,在InnoDB中,引用列

:如果您在 Hospital表上創建列的索引,例如不必是唯一的,但這種類型的關係的行爲可能不是你想要什麼)

CREATE INDEX Hospital_IX1 ON Hospital (HAreaCd); 

然後,您可以創建引用該列的外鍵約束。


然而,因爲這是MySQL的和InnoDB的一個非標準擴展,「最佳實踐」(如其他答案在這裏表示)是一個FOREIGN KEY引用外部表的PRIMARY KEY。理想情況下,這將是一個專欄。

鑑於Hospital表的現有定義,對於一個外鍵引用它一個更好的選擇是將Hid列添加到Hospital_Address

... ADD HId Int COMMENT 'FK ref Hospital.HId' 

... ADD CONSTRAINT FK_Hospital_Address_Hospital 
     FOREIGN KEY (HId) REFERENCES Hospital (HId) 

建立行,值之間的關係新的HId列將需要填充。

+0

謝謝Spencer,在定義Hospital_IX1之後,我能夠定義Hospital_Address表。但作爲一個noob,我很困惑爲什麼我們要定義一個新索引Hospital_IX1 ......並且當我們創建它時,Hospital_Address表怎麼知道這個索引是Hospital_IX1。那麼Hospital_Address的主鍵索引會發生什麼? – user3822147

+0

InnoDB **要求在INDEX引用的列上定義一個INDEX。 (在封面之下,InnoDB需要該索引以便強制約束;如果沒有該索引,InnoDB將不得不做一些醜陋的併發 - 殺死整個表的鎖定;但是InnoDB甚至不會去那裏,它只需要一個合適的索引MySQL不關心索引名稱是什麼;它只是檢查一個合適的索引是否存在,在這種情況下,是任何具有'HAreaCd'作爲主要列的索引。關於表,索引,約束條件等都記錄在數據庫中 – spencer7593

+0

向表中添加第二個索引不會影響表上的現有索引; PRIMARY KEY仍然是PRIMARY KEY,任何UNIQUE KEY仍然是唯一鍵;任何現有的索引仍然是索引,每當我們運行引用表的查詢時,MySQL都會訪問有關可用索引和唯一性,數據分佈和基數的信息,所以優化器可以選擇適當的訪問計劃 – spencer7593

0

HAreaCd在醫院的表應該是一個主鍵。只有這樣,你可以參考它在Hospital_Address表

+0

好吧,意思是隻有一個表的主鍵可以是第二個表上的外鍵? – user3822147

+0

準確地說,如果密鑰存在於第一個表中並且是主鍵,則第二個表可以具有外鍵。 – RingMaster

+0

實際上,只要有一個合適的索引定義,InnoDB就允許一個表中的任何一組列被FOREIGN KEY引用。規範模式是指外鍵引用表的PRIMARY KEY或UNIQUE KEY,但InnoDB擴展超出SQL標準,並允許引用非唯一的一組列。 (這是非標準行爲,如果理解不好,這樣的FOREIGN KEY的行爲可能是意想不到的,違反直覺。) – spencer7593

1

通常不能將外鍵添加到其他表的非主鍵元素。

如果你真的需要的話,請參考這個問題求助:Foreign Key to non-primary key

+0

事實上,InnoDB允許外鍵約束引用任何一組列,只要在該組列上定義了適當的索引即可。這是SQL標準之外的擴展;規範模式是參考PRIMARY KEY;但也可以引用一個UNIQUE KEY。 (當一個FOREIGN KEY引用一組非唯一的列時,如果不理解,行爲可能是意想不到的。) – spencer7593

相關問題