[英]mysql 8 (innodb) foreign key constraints on newly created indexes
Suppose I have a table items
假设我有一个表
items
with columns id (PRIMARY), name(VARCHAR), section_id (BIGINT), updated_at (DATETIME)
,列
id (PRIMARY), name(VARCHAR), section_id (BIGINT), updated_at (DATETIME)
,
and a table sections
with id (PRIMARY)
.和一个带有
id (PRIMARY)
的表sections
。
Naturally, items.section_id
is a foreign key that refers to sections.id
.自然地,
items.section_id
是引用sections.id
的外键。
Suppose there is an index on items
of the columns (section_id, name)
.假设列
(section_id, name)
的items
有一个索引。 I believe that if you tried to drop this index, you would get an error that it is needed in a foreign key constraint
.我相信如果你试图删除这个索引,你会得到一个错误,指出它
needed in a foreign key constraint
。 I can accept this.我可以接受这个。
Now, I want to create a new index, like create index ix_section_id_id_updated_at on items (section_id, id, updated_at)
.现在,我想创建一个新索引,例如
create index ix_section_id_id_updated_at on items (section_id, id, updated_at)
。 MySQL lets me do this, but if I go to drop this table, I get that same error: it fails, because it is needed in a foreign key constraint
. MySQL 让我这样做,但是如果我 go 删除这个表,我会得到同样的错误:它失败了,因为它
needed in a foreign key constraint
。
Why should this be?为什么会这样? It already has one index that can be used for this foreign key check.
它已经有一个可用于此外键检查的索引。 Further, the error does NOT go away with
set FOREIGN_KEY_CHECKS=0;
此外,错误不会 go 远离
set FOREIGN_KEY_CHECKS=0;
. . Is there a way to force MySQL to not associate the new index with the foreign key, so that it is quick to drop?
有没有办法强制MySQL不把新索引和外键关联起来,这样就快drop了? This is necessary because I will be running the migration on a production server with temporary downtime, and need to be able to quickly revert the migration in case of anything going wrong afterwards.
这是必要的,因为我将在临时停机的生产服务器上运行迁移,并且需要能够在之后出现任何问题的情况下快速恢复迁移。
I can reproduce your issue if I don't create an index on section_id and allow mysql to do so on the creation of a foreign key(as described in the manual).如果我不在 section_id 上创建索引并允许 mysql 在创建外键时这样做(如手册中所述),我可以重现您的问题。 Adding a new index drops the auto generated key and if you then drop the new index an error is generated because of the requirement to have a key, and mysql does not auto generate one on a drop.. .
添加新索引会删除自动生成的密钥,如果您随后删除新索引,则会由于需要密钥而生成错误,而 mysql 不会在删除时自动生成一个...。 If you manually generate a key on section_id this problem does not happen..and the newly created compound index drops successfully.
如果你在 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;
and with manually generated key并使用手动生成的密钥
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.