暂无图片
暂无图片
3
暂无图片
暂无图片
暂无图片

MySQL的存储引擎之InnoDB

原创 巩飞 2020-02-28
1704

InnoDB存储引擎提供了提交、回滚和奔溃恢复的事务能力,它是高可靠性和高性能的平衡。
下图是MySQL 5.7中InnoDB存储引擎的内存和磁盘结构。
图片.png

使用InnoDB来存表有很多优点:

  • 如果服务器因硬件或软件问题而崩溃,无论数据库发生了什么,重启数据库后不需要做任何特别的事情。InnoDB自动完成崩溃前提交的更改,并撤消正在进行但未提交的更改。
  • InnoDB存储引擎维护自己的缓冲池,经常使用的数据直接从内存中处理。这个缓存适用于多种类型的信息并加快处理速度。在专用数据库服务器上80%的物理内存通常分配给缓冲池。
  • 如果将相关数据拆分为不同的表,则可以设置强制引用的外键。更新或删除主表数据,子表中的相关数据会自动更新或删除。
  • 如果数据在磁盘或内存中损坏,checksum机制会提醒。
  • 当为每个表设计具有适当主键列的数据库时,操作涉及到这些列会自动优化。引用主键非常快WHERE子句、ORDER BY子句、GROUP BY子句和联接操作中的列。
  • 插入、更新和删除通过一种称为更改缓冲的自动机制进行优化。InnoDB不仅允许对同一个表的并发读写访问,还缓存更改后的数据优化磁盘I/O。
  • 当相同的行从表中反复访问,称为自适应散列索引的功能将接管使这些查找更快,就好像它们是从散列表中出来的一样。
  • 可以压缩表和相关索引。
  • 创建和删除索引,对性能和可用性的影响要小得多。
  • 可以通过查询INFORMATION_SCHEMA表来了解存储引擎的内部工作情况。
  • 可以通过查询Performance Schema表来了解存储引擎的性能详细信息。

InnoDB存储表和索引有两种方式。

  • 共享表空间,这种方式创建的表,表结构保存在.frm文件中,数据和索引保存在innodb_data_home_dir和innodb_data_file_path定义的表空间中。
  • 多表空间,这种方式创建的表,表结构仍然保存在.frm文件中,每个表的数据和索引单独保存在.ibd中。如果是分区表,每个分区对应单独的.ibd文件。

要使用多表空间方式,需要设置参数innodb_file_per_table=ON,并且重启服务生效,之后新创建的表将按照新方式保存,已存在的表还继续使用原来的方式。

root@database-one 01:13: [gftest]> show variables like 'innodb_file_per_table'; +-----------------------+-------+ | Variable_name | Value | +-----------------------+-------+ | innodb_file_per_table | ON | +-----------------------+-------+ 1 row in set (0.00 sec) root@database-one 01:13: [gftest]> show variables like 'innodb_data_%'; +-----------------------+------------------------+ | Variable_name | Value | +-----------------------+------------------------+ | innodb_data_file_path | ibdata1:12M:autoextend | | innodb_data_home_dir | | +-----------------------+------------------------+ 2 rows in set (0.01 sec)

可以看到,笔者测试环境使用的就是多表空间方式。创建表进行验证下。

root@database-one 01:13: [gftest]> create table testinnodb(id int not null auto_increment,name varchar(10),primary key(id)) engine=innodb; Query OK, 0 rows affected (0.45 sec) root@database-one 01:15: [gftest]> exit Bye [root@database-one gftest]# cd /home/mysql/gftest/ [root@database-one gftest]# ls db.opt emp_copy.ibd emp.ibd myset.ibd t1.ibd t2.ibd t6.frm testdate.frm testenum1.frm testenum.frm test.frm testinnodb.frm testnew.frm t.frm vc.frm emp_copy.frm emp.frm myset.frm t1.frm t2.frm t3.frm t6.ibd testdate.ibd testenum1.ibd testenum.ibd test.ibd testinnodb.ibd testnew.ibd t.ibd vc.ibd [root@database-one gftest]# ls -l testinnodb.* -rw-r----- 1 mysql mysql 8586 2月 28 01:15 testinnodb.frm -rw-r----- 1 mysql mysql 98304 2月 28 01:15 testinnodb.ibd [root@database-one gftest]#

InnoDB表的自动增长列可以人工插入,但是插入值如果是null或者0,则将实际插入自动增长的值。

root@database-one 01:20: [gftest]> insert into testinnodb values(1,'wangjun'),(2,'liuyun'),(0,'xiaoli'),(null,'guojing'); Query OK, 4 rows affected (0.04 sec) Records: 4 Duplicates: 0 Warnings: 0 root@database-one 01:22: [gftest]> select * from testinnodb; +----+---------+ | id | name | +----+---------+ | 1 | wangjun | | 2 | liuyun | | 3 | xiaoli | | 4 | guojing | +----+---------+ 4 rows in set (0.00 sec)

对于已经存在的表,要想知道其存储引擎,可以用show create table或show table status查看。

root@database-one 01:24: [gftest]> show create table testinnodb \G *************************** 1. row *************************** Table: testinnodb Create Table: CREATE TABLE `testinnodb` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(10) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 1 row in set (0.03 sec) root@database-one 01:25: [gftest]> show table status like 'testinnodb' \G *************************** 1. row *************************** Name: testinnodb Engine: InnoDB Version: 10 Row_format: Dynamic Rows: 4 Avg_row_length: 4096 Data_length: 16384 Max_data_length: 0 Index_length: 0 Data_free: 0 Auto_increment: 7 Create_time: 2020-02-28 01:15:44 Update_time: 2020-02-28 01:22:17 Check_time: NULL Collation: utf8_general_ci Checksum: NULL Create_options: Comment: 1 row in set (0.03 sec)
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论