繁体   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