草庐IT

mysql - 在 MySQL 中删除用于外键的索引的后果

coder 2023-10-24 原文

似乎可以删除为 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 表中 命令表。

我的问题是,在 InnoDB 表上以这种方式删除用于外键约束的索引是否会产生其他后果?

(这件事的背景是我有一个数据仓库,有人在其中向包含数亿行的事实表添加了外键,该事实表引用了只有少数几行的其他表 - 使得这些列上的索引对查询无用性能,同时占用 大量 磁盘空间并严重影响插入性能。完整性不太重要,由数据仓库中的 ETL 过程强制执行 - 但保持外键约束对文档和 3. 方可视化工具)

最佳答案

这似乎是错误 #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: When dropping all indexes on a column with multiple indexes, InnoDB failed to block a DROP INDEX operation when a foreign key constraint requires an index. (Bug #16896810)

这并没有明确说明修复适用于 foreign_key_checks=OFF 时,但是当 foreign_key_checks=ON 时不允许使用 DROP ,所以大概 OFF 是他们正在修复的情况。

尽管允许 DROP INDEX,但重新启动服务器 correctly gives a missing foreign key index error .因此,无论如何,利用该错误不会使您处于非常有用的状态。当然你可以自动删除它;但由于它是一个错误,您不能依赖该行为,并且您不应该期望/猜测您的系统如何在它下运行,无论其他问题是否已记录/观察到或未记录/观察到。无论如何,出于完整性的目的,您应该通过 DBMS 以某种方式强制执行与该外键声明关联的约束——不要强制执行或依赖应用程序。

(一如既往,Minimal, Complete, and Verifiable Example 会很有帮助。)

关于mysql - 在 MySQL 中删除用于外键的索引的后果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47083121/

有关mysql - 在 MySQL 中删除用于外键的索引的后果的更多相关文章

  1. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  2. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  3. ruby - 我可以使用 Ruby 从 CSV 中删除列吗? - 2

    查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html

  4. ruby - 我可以使用 aws-sdk-ruby 在 AWS S3 上使用事务性文件删除/上传吗? - 2

    我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的

  5. ruby - 如果指定键的值在数组中相同,如何合并哈希 - 2

    我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat

  6. ruby - 检查字符串是否包含散列中的任何键并返回它包含的键的值 - 2

    我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案

  7. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  8. ruby - inverse_of 是否适用于 has_many? - 2

    当我使用has_one时,它​​工作得很好,但在has_many上却不行。在这里您可以看到object_id不同,因为它运行了另一个SQL来再次获取它。ruby-1.9.2-p290:001>e=Employee.create(name:'rafael',active:false)ruby-1.9.2-p290:002>b=Badge.create(number:1,employee:e)ruby-1.9.2-p290:003>a=Address.create(street:"123MarketSt",city:"SanDiego",employee:e)ruby-1.9.2-p290

  9. ruby - 如何安全地删除文件? - 2

    在Ruby中是否有Gem或安全删除文件的方法?我想避免系统上可能不存在的外部程序。“安全删除”指的是覆盖文件内容。 最佳答案 如果您使用的是*nix,一个很好的方法是使用exec/open3/open4调用shred:`shred-fxuz#{filename}`http://www.gnu.org/s/coreutils/manual/html_node/shred-invocation.html检查这个类似的帖子:Writingafileshredderinpythonorruby?

  10. ruby-on-rails - 标准化文件名的字符串,删除重音和特殊字符 - 2

    我正在尝试找到一种方法来规范化字符串以将其作为文件名传递。到目前为止我有这个:my_string.mb_chars.normalize(:kd).gsub(/[^\x00-\x7F]/n,'').downcase.gsub(/[^a-z]/,'_')但第一个问题:-字符。我猜这个方法还有更多问题。我不控制名称,名称字符串可以有重音符、空格和特殊字符。我想删除所有这些,用相应的字母('é'=>'e')替换重音符号,并将其余的替换为'_'字符。名字是这样的:“Prélèvements-常规”“健康证”...我希望它们像一个没有空格/特殊字符的文件名:“prelevements_routin

随机推荐