2012-06-24 126 views
5

以下兩個CREATE TABLE語句有什麼區別? (第一個使用KEY,第二個沒有。)FOREIGN KEY創建的差異

CREATE TABLE `title` (
    `title` VARCHAR(255) NOT NULL, 
    `order_number` VARCHAR(35) NOT NULL, 
    KEY `order_number` (`order_number`), 
    CONSTRAINT `order_number_fk` FOREIGN KEY (`order_number`) 
     REFERENCES `order` (`order_number`) ON DELETE CASCADE 
) 

CREATE TABLE `title` (
    `title` VARCHAR(255) NOT NULL, 
    `order_number` VARCHAR(35) NOT NULL, 
    CONSTRAINT `order_number_fk` FOREIGN KEY (`order_number`) 
     REFERENCES `order` (`order_number`) ON DELETE CASCADE 
) 

兩者都創建有效的表。他們有什麼不同,我想用什麼?

回答

7

它們(幾乎*)是相同的。

當您創建外鍵約束時,如果沒有合適的索引,則會在引用表的相關列上自動創建索引。

從手冊頁面上FOREIGN KEY Constraints

InnoDB的需要外鍵和被引用鍵的索引以便外鍵檢查可以快速,不需要表掃描。在引用表中,必須有一個索引,其中外鍵列以相同順序排列爲第一列。 如果索引表不存在,則會在引用表上自動創建此類索引。如果您創建可用於強制實施外鍵約束的另一個索引,則此索引可能稍後會自動丟棄。如前所述,使用index_name。

重點煤礦。


(*)我說幾乎一樣的,因爲有一些細微的差別。

指數

在你給索引一個明確的名稱的第一個版本,但在第二個版本的索引的名稱是一樣的約束的名稱的名稱(如果它被指定)。

比較SHOW INDEX在這兩種情況下的輸出:

版本1:

 
Table Non_unique Key_name   Seq_in_index Column_name ... 
title 1   order_number  1    order_number ... 

版本2:

 
Table Non_unique Key_name   Seq_in_index Column_name ... 
title 1   order_number_fk 1    order_number ... 

正如你所看到的,這裏唯一的區別是名稱該指數。

靜音下降

另一個細微的差別是,在第二種情況下,如文檔提到,自動創建索引可能是默默地在加入新指標下降:

該指數可能如果您創建另一個可用於強制執行外鍵約束的索引,則可以稍後默默放棄。

這意味着,如果你以後創建一個多列索引,例如,(order_number, title)

CREATE INDEX ix_order_number_title ON title (order_number, title); 

然後再次運行SHOW INDEX

版本1:

 
Table Non_unique Key_name    Seq_in_index Column_name ... 
title 1   order_number   1    order_number ... 
title 1   ix_order_number_title 1    order_number ... 
title 1   ix_order_number_title 2    title   ... 

版本2:

 
Table Non_unique Key_name    Seq_in_index Column_name ... 
title 1   ix_order_number_title 1    order_number ... 
title 1   ix_order_number_title 2    title   ... 

現在你可以看到第一個版本有兩個索引,但第二個版本只有一個。在第二個版本中,當添加多列索引時,由外鍵約束自動創建的索引會自動再次丟失。通常這不是一個嚴重的問題,因爲新索引使得原始索引大部分是多餘的。

我想使用哪一個?

通常,您不必擔心在外鍵約束的引用表上顯式創建索引。

但如果你可能需要明確創建索引:

  • 你願意給它一個名稱,從約束的名稱不同,或
  • 你不想要索引當其他索引被添加時,靜靜地消失。
+0

這對MyISAM也是如此嗎? – lee

+1

@lee MyISAM不支持外鍵約束。 – David542

+0

很好的答案,謝謝! – David542