簡體   English   中英

MySQL是否隱式地為UNIQUE和FOREIGN KEY約束生成索引,還是我應該顯式地創建索引?

[英]Does MySQL generate indices for UNIQUE and FOREIGN KEY constraints implicitly or should I actually create them explicitly?

讓我們考慮一個包含2個簡單表的數據庫: tablea具有INT id ,VARCHAR something字段和引用tableb (包含相同字段但添加了UNIQUE約束)。

如果我們使用MySQL Workbench設計和正向設計該模式,它將生成以下代碼:

CREATE TABLE IF NOT EXISTS `tableb` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `something` VARCHAR(45) NULL,
  PRIMARY KEY (`id`),
  UNIQUE INDEX `something_UNIQUE` (`something` ASC))
ENGINE = InnoDB;

CREATE TABLE IF NOT EXISTS `tablea` (
  `id` INT NOT NULL,
  `something` VARCHAR(45) NULL,
  `tableb_id` INT NOT NULL,
  PRIMARY KEY (`id`, `tableb_id`),
  INDEX `fk_tablea_tableb_idx` (`tableb_id` ASC),
  CONSTRAINT `fk_tablea_tableb`
    FOREIGN KEY (`tableb_id`)
    REFERENCES `tableb` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

但我們似乎可以通過更簡單,更簡單的代碼達到相同的效果(表,列和約束的相同架構):

CREATE TABLE IF NOT EXISTS `tableb` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `something` VARCHAR(45) NULL,
  PRIMARY KEY (`id`),
  UNIQUE (`something`)
) ENGINE = InnoDB;

CREATE TABLE IF NOT EXISTS `tablea` (
  `id` INT NOT NULL,
  `something` VARCHAR(45) NULL,
  `tableb_id` INT NOT NULL,
  PRIMARY KEY (`id`, `tableb_id`),
  FOREIGN KEY (`tableb_id`) REFERENCES `tableb`(`id`)
) ENGINE = InnoDB;

第一個版本是否比第二個版本更好(例如更快)? 在第二種情況下,MySQL是否也不會創建第一個版本中提到的索引?

正如我在評論中提到的以及手冊所說,在最后一個塊中,您無需在子表(引用)中顯式創建與FK相關的鍵。 如果需要,MySQL會根據最左邊的位置(或按照手冊所述的最前面的位置)自動為您創建它們。 單列索引自然是最左側的。 對於復合材料(即多列鍵),最左側自然是有意義的。

如果您運行上面的命令並發出一個

show create table tablea;

如果您恰好在孩子中定義了最左鍵,並且該鍵可用於FK關系,則引擎不會自行為您創建一個。

在標題為“ 使用外鍵約束 ”的手冊頁中

在引用表中,必須有一個索引,其中外鍵列以相同的順序列為第一列。 如果這樣的索引不存在,則會在引用表上自動創建。 如果您創建另一個可用於強制外鍵約束的索引,則以后可能會靜默刪除該索引。 如果給定,則使用index_name(如前所述)。

同樣,正如我在您的問題的注釋部分中提到的那樣,被引用的表(父表)必須具有必要的最左邊的鍵,以便在所有這些操作之前快速查找。 該密鑰不必是PRIMARY密鑰或唯一密鑰。 但是它必須在復合材料的最左側可用。 如果在子級的ALTER TABLECREATE TABLE之前的父級中沒有一個可用,則該操作將失敗並顯示

MySQL錯誤1215:無法添加外鍵約束

關於在子表中代表(或不代表)何時創建鍵的幾個快速示例:

  1. 如果您在col1上顯式創建一個密鑰,並且該密鑰在FK中使用,則不會為您創建幫助密鑰。

  2. 如果在(a,b,c,d)上顯式創建復合鍵,並且在(a,b)上具有FK,則不會為您創建幫助鍵。

  3. 如果在(a,b,c,d)上顯式創建復合鍵,並且在(a,c)上具有FK,則將為您創建一個輔助鍵。 因為b妨礙了顯式操作,所以需要一個新的鍵。

  4. 如果在(a,b,c,d)上顯式創建組合鍵,並且在(a,b,c)上具有FK,則不會為您創建幫助鍵。 以相同的順序,顯式表的最左端足以滿足FK的要求。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM