MySQL 5.7 中 MyISAM 和 InnoDB 存储引擎之间的当前区别是什么?
What are the current differences between MyISAM and InnoDB storage engines specifically in MySQL 5.7?
我在 Whosebug 本身上看到了很多关于这个主题 MyISAM vs InnoDB 的问题和答案。
但是,所有的问题和答案都太旧了,与MySQL的当前stable版本无关 5.7.x
到那时,MyISAM 和 InnoDB 肯定已经进行了如此多的开发。
所以,我需要版本 5.7.x
目前可用的那些差异
所以,请不要将我的问题标记为重复,请有人解释这些存储引擎目前的差异以及它们自过去以来的差异。
另外请说明table.
在什么情况下应该选择哪种存储引擎
属于同一架构的不同 table 是否可以具有不同的存储引擎,即少数 table 将具有 InnoDB 并且很少有 MyISAM.
如果是,那么 JOIN 查询将如何在 table 秒之间执行 MyISAM 和 InnoDB?
MySQL 是否真的要从未来的版本中删除 MyISAM 存储引擎?
您关于 MyISAM 正在接受新开发的假设是不正确的。 MyISAM 没有得到任何重要的新开发。 MySQL 显然正朝着逐步淘汰 MyISAM 的方向前进,不鼓励使用 MyISAM。
Oracle Corp. 尚未宣布他们将删除 MyISAM 的任何具体日期或版本。我的猜测是 MyISAM 永远不会被完全删除,因为有太多的站点无法升级,如果不进行昂贵的测试以确保他们的特定应用程序在转换为 InnoDB 时不会遇到任何回归问题。
但您可能会注意到,在 MySQL 5.7 手册中,关于 MyISAM 的部分已降级为 Alternative Storage Engines,这应该表明它的优先级较低。
在MySQL 5.7中,MyISAM仍然用于table的一些系统,如mysql.user
、mysql.db
等。但是新系统tables在5.6和5.7引入的是InnoDB。所有系统 table 都是 MySQL 8.0.
中的 InnoDB
MyISAM 仍然不支持 ACID. There are no transactions, no consistency features, and no durable writes. See my answer to MyISAM versus InnoDB 的任何属性。
MyISAM 仍然不支持外键,这是值得的。但我很少看到真正的生产站点使用外键,即使使用 InnoDB。
MyISAM 仅支持 table 级锁定(如手册中所述,某些 INSERT 附加到 table 的末尾除外)。
MySQL 5.7 在 MyISAM 和 InnoDB 中都支持 fulltext indexes and spatial indexes。这些特性不是继续使用 MyISAM 的理由。
像 mysqldump
这样的逻辑备份工具和像 Percona XtraBackup 这样的物理备份工具都不能在不获取全局锁的情况下备份 MyISAM tables。
您询问是否可以在同一架构中使用不同的存储引擎创建各种 table。是的,你可以,这与 MySQL.
的许多版本一样
您询问是否可以加入不同存储引擎的 table(顺便说一句,table 不需要在相同的模式中才能加入)。是的,你可以加入这样的 tables,MySQL 会处理所有细节。这与 MySQL 的许多版本相同。
但是执行此操作时可能会出现一些奇怪的情况,例如如果您在事务中更新 MyISAM table 和 InnoDB table,然后回滚怎么办? InnoDB table 中的更改被回滚,但 MyISAM table 中的更改未被回滚,因此如果您不小心,可能会破坏数据完整性。这也与 MySQL.
的许多版本相同。
MyISAM 优于 InnoDB 的案例是一个简短的列表,而且越来越短。
一些 table-scan 查询和批量插入在 MyISAM 中更快。 InnoDB 更擅长索引搜索。
MyISAM 可能使用比 未压缩 InnoDB table 中存储的等效数据更少的存储 space。您可以使用 myisampack 进一步压缩 MyISAM tables,但这会使 MyISAM table 变为只读。
现在还有其他选项可以在事务存储引擎中紧凑地存储数据,例如 InnoDB table compression, or MyRocks。
SELECT COUNT(*) FROM MyTable
查询(没有 WHERE 子句)在 MyISAM 中非常快,因为准确的行数保存在 MyISAM 元数据中。 InnoDB(或其他 MVCC 实现)不会保留此计数,因为查看 table 的每个事务都可能 "see" 不同的行计数。只有像 MyISAM 这样具有 table 级锁定且没有事务隔离的存储引擎才能优化这种情况。
为另一个键列中的每个不同值独立地自动递增该数字。同样,这需要 table 级锁定,因此 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 table 从一个服务器移动到另一个服务器仍然很容易,因为 .MYD 和 .MYI 文件是独立的。您可以对 InnoDB tables 做一些类似的事情,但是您必须使用 transportable tablespaces 的复杂功能。但是这种易于移动的 table 品质的 MyISAM 在 MySQL 8.0 中不再适用,因为它们具有新的数据字典功能。
在某些负载下,MyISAM 可能是 internal_tmp_disk_storage_engine
更好的选择,它在 MySQL 5.7 中默认为 InnoDB。如果您 运行 大量查询在磁盘 上创建临时 tables (内存中的临时 tables 不会受益),它可以对 InnoDB 引擎造成压力。但是你必须有一个高查询率才能解决这个问题,如果你的查询在磁盘上创建这么多临时 tables,你应该尝试以不同的方式优化查询。
MyISAM 允许您设置多个键缓存,并为特定的 table 定义缓存。但是 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
我在求职测验中遇到了这个问题并且答对了:(指的是新版本):
MyISAM 和 InnoDB 是两种不同的存储引擎,它们以不同的方式处理 CRUD 操作。
锁定:当在 MyISAM 存储引擎中处理一行时,所有 table 将被其他 session 锁定,直到更改被提交,这与 InnoDB 不同,后者仅锁定特定的选定行 (/s)。在提交 session 之前释放锁。锁定 table 或一行会导致其他 session 暂停,这些 session 试图与相同的 table 或行进行交互,以防止 table 中的错误数据操作。
事务:与MyISAM 不同,InnoDB 支持事务。事务是 2 个或更多命令的集合,如 SELECT、INSERT、UPDATE 和 DELETE,对单个操作直到完成。
原子操作:当在 InnoDB 中设置一个事务并且
操作未完成 - 它终止所有更改并且
恢复数据库原样(全部或全部),例如,如果在
在交易中间,代码中存在语法错误 /
数据类型不匹配或任何可能中断捆绑的东西
完成其操作的命令 - 所有更改都不会应用,
感谢交易原子性。另一方面,当使用
MyISAM 存储引擎,如果一组命令 "breaks" (对于任何
原因),操作立即停止,所有
tables/rows/data 受到影响的将继续受到影响,这
可能会导致数据库中的数据损坏(...和头痛)。
乙。 运行 MyISAM 上的一个操作是当场设置的,
而 InnoDB 允许您使用 "ROLLBACK"s 丢弃任何
更改,这在 运行 笔交易时最有用。
交易日志:创建交易时没有
之间的事务日志,您可以在 table/s 上应用任何更改
在数据库中,如果 table 有聚集索引(例如),
数据将必须搜索它必须插入的确切位置,并且
只有这样才能应用更改。在有交易的情况下
在数据库和事务之间登录,将发送更改
首先到事务日志,并将在 table 中设置其顺序
在将更改发送到数据库之前 - 这将减少时间
消费。数据库保存所有交易的日志
made,可以帮助选择恢复之前的任何交易
并恢复所有更改。当设置为 "simple" 恢复模式时——事务将从事务日志中删除并且无法恢复数据(通常用于 DEV 环境)。当设置为
"full" 恢复模式,所有交易都已保存并列出,准备就绪
待恢复 - 这通常用于生产环境
这可能会导致性能问题等问题 - 所以支持他们
从服务器上启动并删除可能是一个解决方案。当设置为
"bulk-logged" 恢复模式仅保存事务日志
具体 "important" 更改和命令(导入、导出、
insert-select、select-into、reorganaizing/rebuilding 索引)和
可能会防止性能问题。
外键:与 InnoDB 不同,MyISAM 不使用外键。当 table 列的外键设置为指向另一个 table 列时,当任何 update/delete 出现在指向的 table 上时,它将知道更改必须应用于指向它的另一个table。这在两个 table 之间创建了某种 link 并保持数据同步。使用 FK 设置 tables 可能需要更多的努力,这可能被认为是一个缺点(?)。
FULLTEXT 索引:InnoDB 在其以前的版本中不支持 FULLTEXT 索引——MyISAM 支持它。切换到 MyISAM 不会是最好的解决方案,因此只需将 MySQL 更新为支持 FULLTEXT 索引的版本。
FULLTEXT 索引可以获取标题、评论等文本并进行搜索(在这种情况下,这应该是比 "LIKE" 命令更好的选择)。
空间数据类型:仅 InnoDB 支持。
总而言之,InnoDB 在数据处理、有效性和恢复方面通常更可靠。对于较新的版本,InnoDB 将支持主要搜索的 FULLTEXT 索引——当使用没有选项更新 MySQL 的旧版本时,使用 MyISAM 会很棒。
我在 Whosebug 本身上看到了很多关于这个主题 MyISAM vs InnoDB 的问题和答案。
但是,所有的问题和答案都太旧了,与MySQL的当前stable版本无关 5.7.x
到那时,MyISAM 和 InnoDB 肯定已经进行了如此多的开发。
所以,我需要版本 5.7.x
目前可用的那些差异所以,请不要将我的问题标记为重复,请有人解释这些存储引擎目前的差异以及它们自过去以来的差异。
另外请说明table.
在什么情况下应该选择哪种存储引擎属于同一架构的不同 table 是否可以具有不同的存储引擎,即少数 table 将具有 InnoDB 并且很少有 MyISAM.
如果是,那么 JOIN 查询将如何在 table 秒之间执行 MyISAM 和 InnoDB?
MySQL 是否真的要从未来的版本中删除 MyISAM 存储引擎?
您关于 MyISAM 正在接受新开发的假设是不正确的。 MyISAM 没有得到任何重要的新开发。 MySQL 显然正朝着逐步淘汰 MyISAM 的方向前进,不鼓励使用 MyISAM。
Oracle Corp. 尚未宣布他们将删除 MyISAM 的任何具体日期或版本。我的猜测是 MyISAM 永远不会被完全删除,因为有太多的站点无法升级,如果不进行昂贵的测试以确保他们的特定应用程序在转换为 InnoDB 时不会遇到任何回归问题。
但您可能会注意到,在 MySQL 5.7 手册中,关于 MyISAM 的部分已降级为 Alternative Storage Engines,这应该表明它的优先级较低。
在MySQL 5.7中,MyISAM仍然用于table的一些系统,如mysql.user
、mysql.db
等。但是新系统tables在5.6和5.7引入的是InnoDB。所有系统 table 都是 MySQL 8.0.
MyISAM 仍然不支持 ACID. There are no transactions, no consistency features, and no durable writes. See my answer to MyISAM versus InnoDB 的任何属性。
MyISAM 仍然不支持外键,这是值得的。但我很少看到真正的生产站点使用外键,即使使用 InnoDB。
MyISAM 仅支持 table 级锁定(如手册中所述,某些 INSERT 附加到 table 的末尾除外)。
MySQL 5.7 在 MyISAM 和 InnoDB 中都支持 fulltext indexes and spatial indexes。这些特性不是继续使用 MyISAM 的理由。
像 mysqldump
这样的逻辑备份工具和像 Percona XtraBackup 这样的物理备份工具都不能在不获取全局锁的情况下备份 MyISAM tables。
您询问是否可以在同一架构中使用不同的存储引擎创建各种 table。是的,你可以,这与 MySQL.
的许多版本一样您询问是否可以加入不同存储引擎的 table(顺便说一句,table 不需要在相同的模式中才能加入)。是的,你可以加入这样的 tables,MySQL 会处理所有细节。这与 MySQL 的许多版本相同。
但是执行此操作时可能会出现一些奇怪的情况,例如如果您在事务中更新 MyISAM table 和 InnoDB table,然后回滚怎么办? InnoDB table 中的更改被回滚,但 MyISAM table 中的更改未被回滚,因此如果您不小心,可能会破坏数据完整性。这也与 MySQL.
的许多版本相同。MyISAM 优于 InnoDB 的案例是一个简短的列表,而且越来越短。
一些 table-scan 查询和批量插入在 MyISAM 中更快。 InnoDB 更擅长索引搜索。
MyISAM 可能使用比 未压缩 InnoDB table 中存储的等效数据更少的存储 space。您可以使用 myisampack 进一步压缩 MyISAM tables,但这会使 MyISAM table 变为只读。
现在还有其他选项可以在事务存储引擎中紧凑地存储数据,例如 InnoDB table compression, or MyRocks。
SELECT COUNT(*) FROM MyTable
查询(没有 WHERE 子句)在 MyISAM 中非常快,因为准确的行数保存在 MyISAM 元数据中。 InnoDB(或其他 MVCC 实现)不会保留此计数,因为查看 table 的每个事务都可能 "see" 不同的行计数。只有像 MyISAM 这样具有 table 级锁定且没有事务隔离的存储引擎才能优化这种情况。为另一个键列中的每个不同值独立地自动递增该数字。同样,这需要 table 级锁定,因此 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 table 从一个服务器移动到另一个服务器仍然很容易,因为 .MYD 和 .MYI 文件是独立的。您可以对 InnoDB tables 做一些类似的事情,但是您必须使用 transportable tablespaces 的复杂功能。但是这种易于移动的 table 品质的 MyISAM 在 MySQL 8.0 中不再适用,因为它们具有新的数据字典功能。
在某些负载下,MyISAM 可能是
internal_tmp_disk_storage_engine
更好的选择,它在 MySQL 5.7 中默认为 InnoDB。如果您 运行 大量查询在磁盘 上创建临时 tables (内存中的临时 tables 不会受益),它可以对 InnoDB 引擎造成压力。但是你必须有一个高查询率才能解决这个问题,如果你的查询在磁盘上创建这么多临时 tables,你应该尝试以不同的方式优化查询。MyISAM 允许您设置多个键缓存,并为特定的 table 定义缓存。但是 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
我在求职测验中遇到了这个问题并且答对了:(指的是新版本):
MyISAM 和 InnoDB 是两种不同的存储引擎,它们以不同的方式处理 CRUD 操作。
锁定:当在 MyISAM 存储引擎中处理一行时,所有 table 将被其他 session 锁定,直到更改被提交,这与 InnoDB 不同,后者仅锁定特定的选定行 (/s)。在提交 session 之前释放锁。锁定 table 或一行会导致其他 session 暂停,这些 session 试图与相同的 table 或行进行交互,以防止 table 中的错误数据操作。
事务:与MyISAM 不同,InnoDB 支持事务。事务是 2 个或更多命令的集合,如 SELECT、INSERT、UPDATE 和 DELETE,对单个操作直到完成。
原子操作:当在 InnoDB 中设置一个事务并且 操作未完成 - 它终止所有更改并且 恢复数据库原样(全部或全部),例如,如果在 在交易中间,代码中存在语法错误 / 数据类型不匹配或任何可能中断捆绑的东西 完成其操作的命令 - 所有更改都不会应用, 感谢交易原子性。另一方面,当使用 MyISAM 存储引擎,如果一组命令 "breaks" (对于任何 原因),操作立即停止,所有 tables/rows/data 受到影响的将继续受到影响,这 可能会导致数据库中的数据损坏(...和头痛)。
乙。 运行 MyISAM 上的一个操作是当场设置的, 而 InnoDB 允许您使用 "ROLLBACK"s 丢弃任何 更改,这在 运行 笔交易时最有用。
交易日志:创建交易时没有 之间的事务日志,您可以在 table/s 上应用任何更改 在数据库中,如果 table 有聚集索引(例如), 数据将必须搜索它必须插入的确切位置,并且 只有这样才能应用更改。在有交易的情况下 在数据库和事务之间登录,将发送更改 首先到事务日志,并将在 table 中设置其顺序 在将更改发送到数据库之前 - 这将减少时间 消费。数据库保存所有交易的日志 made,可以帮助选择恢复之前的任何交易 并恢复所有更改。当设置为 "simple" 恢复模式时——事务将从事务日志中删除并且无法恢复数据(通常用于 DEV 环境)。当设置为 "full" 恢复模式,所有交易都已保存并列出,准备就绪 待恢复 - 这通常用于生产环境 这可能会导致性能问题等问题 - 所以支持他们 从服务器上启动并删除可能是一个解决方案。当设置为 "bulk-logged" 恢复模式仅保存事务日志 具体 "important" 更改和命令(导入、导出、 insert-select、select-into、reorganaizing/rebuilding 索引)和 可能会防止性能问题。
外键:与 InnoDB 不同,MyISAM 不使用外键。当 table 列的外键设置为指向另一个 table 列时,当任何 update/delete 出现在指向的 table 上时,它将知道更改必须应用于指向它的另一个table。这在两个 table 之间创建了某种 link 并保持数据同步。使用 FK 设置 tables 可能需要更多的努力,这可能被认为是一个缺点(?)。
FULLTEXT 索引:InnoDB 在其以前的版本中不支持 FULLTEXT 索引——MyISAM 支持它。切换到 MyISAM 不会是最好的解决方案,因此只需将 MySQL 更新为支持 FULLTEXT 索引的版本。 FULLTEXT 索引可以获取标题、评论等文本并进行搜索(在这种情况下,这应该是比 "LIKE" 命令更好的选择)。
空间数据类型:仅 InnoDB 支持。
总而言之,InnoDB 在数据处理、有效性和恢复方面通常更可靠。对于较新的版本,InnoDB 将支持主要搜索的 FULLTEXT 索引——当使用没有选项更新 MySQL 的旧版本时,使用 MyISAM 会很棒。