似乎可以删除在MySQL 5.5中为外键创建的索引,其中包含一个小“技巧”,如下所示:
mysql > create table commands (
id int primary key auto_increment, name varchar(255));
mysql > create table data (
dim_command int, cnt int NOT NULL,
CONSTRAINT FOREIGN KEY (dim_command) references commands(id));
现在创建了一个无法删除的索引:
mysql > show create table data;
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| data | CREATE TABLE `data` (
`dim_command` int(11) DEFAULT NULL,
`cnt` int(11) NOT NULL,
KEY `dim_command` (`dim_command`),
CONSTRAINT `data_ibfk_1` FOREIGN KEY (`dim_command`) REFERENCES `commands` (`id`)
) ENGINE=InnoDB
mysql > alter table data drop index dim_command;
ERROR 1553 (HY000): Cannot drop index 'dim_command': needed in a foreign key constraint
但它可以被删除:
mysql > set foreign_key_checks=Off;
Query OK, 0 rows affected (0.00 sec)
mysql > alter table data drop index dim_command;
Query OK, 0 rows affected (0.51 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql > set foreign_key_checks=On;
Query OK, 0 rows affected (0.00 sec)
此时:
data
表仍然具有外键约束规范(通过例如show create table data
显示)data
表中,该表引用了不存在的行
commands
表。我遇到的问题是,如果在InnoDB表上以这种方式删除用于外键约束的索引还有其他后果吗?
(背景是我有一个数据仓库,其中有人将外键添加到包含数亿行的事实表中,这些行仅使用少量行引用其他表 - 使这些列上的索引对查询无用性能,同时占用很多的磁盘空间并严重影响插入性能。完整性不太受关注,并且由数据仓库中的ETL过程强制执行 - 但保留外键约束对于文档和3.方可视化工具)
答案 0 :(得分:1)
这似乎是错误#16896810。显然,5.7.2 (2013-09-21, Milestone 12)之后5.7.9 (2015-10-21, General Availability)修正了此问题。它也在MySQL 5.6.14 (2013-09-20, General Availability)
中修复
- InnoDB:当删除具有多个索引的列上的所有索引时,InnoDB在外键约束需要索引时无法阻止DROP INDEX操作。 (Bug#16896810)
这并没有明确说明该修复程序适用于foreign_key_checks=OFF
,但DROP
时未允许foreign_key_checks=ON
,因此大概是OFF
定影
尽管允许DROP INDEX
,但重新启动服务器correctly gives a missing foreign key index error。所以利用这个bug并不会让你处于一个非常有用的状态。当然你可以自动删除它;但由于它是一个错误,你不能依赖于这种行为,你不应该期望/猜测你的系统如何在其下行动,无论其他问题是记录/观察到的还是未记录/观察到的。无论如何,出于完整性的目的,您应该通过DBMS以这种或那种方式强制执行与该外键声明相关的约束 - 不要强制执行它或依赖于应用程序。
(与往常一样,Minimal, Complete, and Verifiable Example会有所帮助。)
答案 1 :(得分:0)
如果未强制执行FK,其中一个缺点与查询性能无关。
如果您可以将值插入到commands
中其引用的PK列中不存在的FK列中,那么您将不知道您的数据是否有任何好处。它可能包含一堆破损的参考文献,你无法阻止它们发生。
外键约束 -it的目的是保持数据完整性。