草庐IT

mysql - MySQL 5.7中MyISAM和InnoDB存储引擎之间的当前差异是什么?

coder 2023-10-14 原文

我在stackoverflow上看到了很多关于myisam vs innodb的问题和答案。
但是,所有的问题和答案都太老了,与mysql 5.7.x的当前稳定版本无关
到目前为止,myisam和innodb都必须做很多开发工作。
所以,我需要5.7.x版目前提供的这些差异
所以,请不要重复标记我的问题,有人请解释这些存储引擎目前的差异,以及他们过去的差异。
另外,请解释在什么情况下应该为表选择哪种存储引擎。
属于同一架构的不同表是否有不同的存储引擎,即少数表有innodb,少数表有myisam。
如果是,那么如何在带有myisam和innodb的表之间执行连接查询?
mysql真的要从将来的版本中删除myisam存储引擎吗?

最佳答案

你认为Myisam得到了新的发展是不正确的。Myisam没有得到任何重大的新发展。mysql显然正朝着逐步淘汰myisam的方向发展,因此不鼓励使用myisam。
甲骨文公司尚未宣布任何具体日期或版本,他们将删除MyISAM。我的猜测是MyISAM永远不会被完全删除,因为有太多的网站无法升级,而没有进行昂贵的测试,以确保他们的特定应用程序不会经历任何回归问题转换到InnoDB。
但您可能会注意到,在mysql 5.7手册中,myisam的部分已经降级为Alternative Storage Engines,这应该是它获得的优先级较低的一个线索。
在mysql 5.7中,myisam仍然用于一些系统表,如mysql.usermysql.db等,但是5.6和5.7中引入的新系统表是innodb。所有系统表都是mysql 8.0中的innodb。
myisam仍然不支持ACID的任何属性。没有事务,没有一致性功能,也没有持久写入。请看我对MyISAM versus InnoDB的回答。
Myisam仍然不支持外键,这是值得的。但我很少看到真正的生产站点使用外键,即使使用innodb。
myisam只支持表级别的锁定(除了一些附加到表末尾的insert,如手册中所述)。
mysql 5.7在myisam和innodb中都支持fulltext indexesspatial indexes。这些特性并不是像以前那样继续使用myisam的原因。
逻辑备份工具(如mysqldump和物理备份工具(如percona xtrabackup)都无法在不获取全局锁的情况下备份myisam表。
您询问是否可以在同一架构中创建具有不同存储引擎的各种表。是的,你可以,这和很多版本的mysql一样。
您询问是否可以联接不同存储引擎的表(顺便说一下,要联接表,表不需要在同一架构中)。是的,你可以加入这样的表,mysql负责所有的细节。这和很多版本的mysql一样。
但是当你这样做的时候会出现一些奇怪的情况,比如你在事务中更新myisam表和innodb表,然后回滚呢?innodb表中的更改将回滚,但myisam表中的更改不会回滚,因此如果不小心,您的数据完整性可能会被破坏。这也和很多版本的mysql一样。
与innodb相比,myisam有优势的例子很短,而且越来越短。
在myisam中,一些表扫描查询和大容量插入更快。innodb更擅长索引搜索。
myisam可能比未压缩的innodb表中存储的等效数据占用更少的存储空间。您可以使用myisampack进一步压缩myisam表,但这会使myisam表成为只读的。
如今,在事务性存储引擎中还有其他的数据压缩存储选项,例如InnoDB table compressionMyRocks
SELECT COUNT(*) FROM MyTable查询(不带where子句)在myisam中非常快,因为行的准确计数被保存在myisam元数据中。innodb(或其他mvcc实现)不会保持这个计数,因为查看表的每个事务可能“看到”一个不同的行计数。只有具有表级锁定且没有事务隔离(如myisam)的存储引擎才能优化此情况。
为另一个键列中的每个不同值独立编号的自动递增。同样,这需要表级锁定,因此innodb不支持它。

CREATE TABLE MyTable (
  group_id INT NOT NULL,
  seq_id INT NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (group_id, seq_id)
) ENGINE=MyISAM;

将myisam表从一台服务器移动到另一台服务器仍然很容易,因为.myd和.myi文件是自包含的。您可以对innodb表做一些类似的事情,但是必须使用transportable tablespaces的复杂特性。但是,myisam这种易于移动的表质量在mysql 8.0中不再有效,因为它们的新数据字典特性。
在一定负载下,myisam可能是internal_tmp_disk_storage_engine的更好选择,mysql 5.7中默认为innodb。如果您运行大量在磁盘上创建临时表的查询(内存中的临时表没有好处),这会给innodb引擎带来压力。但要做到这一点,您必须有一个很高的查询率,如果您的查询在磁盘上创建了这么多临时表,您应该尝试以不同的方式优化查询。
myisam允许您设置多个键缓存,并为特定表定义缓存。但myisam密钥缓存仅用于索引结构,而不用于数据。
参考文献:
https://www.percona.com/blog/2016/10/11/mysql-8-0-end-myisam/
https://www.percona.com/blog/2017/12/04/internal-temporary-tables-mysql-5-7/
http://jfg-mysql.blogspot.com/2017/08/why-we-still-need-myisam.html

关于mysql - MySQL 5.7中MyISAM和InnoDB存储引擎之间的当前差异是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47680213/

有关mysql - MySQL 5.7中MyISAM和InnoDB存储引擎之间的当前差异是什么?的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby-on-rails - Ruby on Rails 迁移,将表更改为 MyISAM - 2

    如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设

  3. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  4. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  5. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  6. ruby - 为什么 4.1%2 使用 Ruby 返回 0.0999999999999996?但是 4.2%2==0.2 - 2

    为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返

  7. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  8. ruby - ruby 中的 TOPLEVEL_BINDING 是什么? - 2

    它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput

  9. ruby - Infinity 和 NaN 的类型是什么? - 2

    我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串

  10. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

随机推荐