簡體   English   中英

mysql 8 (innodb) 新建索引的外鍵約束

[英]mysql 8 (innodb) foreign key constraints on newly created indexes

假設我有一個表items
id (PRIMARY), name(VARCHAR), section_id (BIGINT), updated_at (DATETIME)

和一個帶有id (PRIMARY)的表sections

自然地, items.section_id是引用sections.id的外鍵。

假設列(section_id, name)items有一個索引。 我相信如果你試圖刪除這個索引,你會得到一個錯誤,指出它needed in a foreign key constraint 我可以接受這個。

現在,我想創建一個新索引,例如create index ix_section_id_id_updated_at on items (section_id, id, updated_at) MySQL 讓我這樣做,但是如果我 go 刪除這個表,我會得到同樣的錯誤:它失敗了,因為它needed in a foreign key constraint

為什么會這樣? 它已經有一個可用於此外鍵檢查的索引。 此外,錯誤不會 go 遠離set FOREIGN_KEY_CHECKS=0; . 有沒有辦法強制MySQL不把新索引和外鍵關聯起來,這樣就快drop了? 這是必要的,因為我將在臨時停機的生產服務器上運行遷移,並且需要能夠在之后出現任何問題的情況下快速恢復遷移。

如果我不在 section_id 上創建索引並允許 mysql 在創建外鍵時這樣做(如手冊中所述),我可以重現您的問題。 添加新索引會刪除自動生成的密鑰,如果您隨后刪除新索引,則會由於需要密鑰而生成錯誤,而 mysql 不會在刪除時自動生成一個...。 如果你在 section_id 上手動生成一個鍵,這個問題就不會發生......並且新創建的復合索引成功刪除。

drop table if exists items;
drop table if exists sections;

create table items(id int PRIMARY key, name varchar(3), section_id BIGINT, updated_at DATETIME);

create table sections(id bigint primary key);

alter table items
    add foreign key fk1(section_id) references sections(id);
    
show create table items;

CREATE TABLE `items` (  `id` int(11) NOT NULL,  
`name` varchar(3) DEFAULT NULL,  
`section_id` bigint(20) DEFAULT NULL, 
 `updated_at` datetime DEFAULT NULL,  
PRIMARY KEY (`id`),  
KEY `fk1` (`section_id`),  
CONSTRAINT `fk1` FOREIGN KEY (`section_id`) REFERENCES `sections` (`id`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;

alter table items
    add key key1(section_id, name);

show create table items;

CREATE TABLE `items` (
  `id` int(11) NOT NULL,
  `name` varchar(3) DEFAULT NULL,
  `section_id` bigint(20) DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `key1` (`section_id`,`name`),
  CONSTRAINT `fk1` FOREIGN KEY (`section_id`) REFERENCES `sections` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

並使用手動生成的密鑰

drop table if exists items;
drop table if exists sections;

create table items(id int PRIMARY key, name varchar(3), section_id BIGINT, updated_at DATETIME);

create table sections(id bigint primary key);


alter table items
    add key sid(section_id);
alter table items
    add foreign key fk1(section_id) references sections(id);
    
show create table items;

CREATE TABLE `items` (
  `id` int(11) NOT NULL,
  `name` varchar(3) DEFAULT NULL,
  `section_id` bigint(20) DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `sid` (`section_id`),
  CONSTRAINT `fk1` FOREIGN KEY (`section_id`) REFERENCES `sections` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

alter table items
    add key key1(section_id, name);

show create table items;

CREATE TABLE `items` (
  `id` int(11) NOT NULL,
  `name` varchar(3) DEFAULT NULL,
  `section_id` bigint(20) DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `sid` (`section_id`),
  KEY `key1` (`section_id`,`name`),
  CONSTRAINT `fk1` FOREIGN KEY (`section_id`) REFERENCES `sections` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

暫無
暫無

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

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