![](/img/trans.png)
[英]Row locking in MySql InnoDb with foreign key constraints and indexes applied?
[英]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.