mysqlserver 组件 | -- |
---|---|
connection pool | 连接池组件 |
Management Service & Utilities | 管理服务和工具组件 |
SQL interface | sql接口组件 |
Parser | 查询分析器组件 |
Optimizer | 优化器组件 |
Caches & Buffers | 缓冲池组件 |
Pluggable Storage Engines | 存储引擎 |
File System | 文件系统 |
层次 | -- |
---|---|
连接层 | 最上层是一些客户端和链接服务,包含本地sock通信和大多数基于客户端/服务端工具实现的类似于TCP/IP的通信。主要完成一些类似于连接处理、授权认证、及相关的安全方案。在该层上引入了线程池的概念,为通过认证安全接入的客户端提供线程。同样在该层上可以实现基于SSL的安全链接。服务器也会为安全接入的每个客户端验证它所具有的操作权限。 |
服务层 | 第二层架构主要完成大多数核心服务功能,如sql接口,并完成缓存的查询,sql的分析和优化,部分内置函数的执行。所有跨存储引擎的功能也在这一层实现,如过程、函数等。在该层,服务器会解析查询并创建相应的内部解析树,并对其完成相应的优化如确定表的查询的顺序,是否利用索引等,最后生成相应的执行操作。如果是select语句,服务器还会查询内部的缓存,如果缓存空间足够大,这样在解决大量读操作的环境中能够很好的提升系统的性能。 |
引擎层 | 存储引擎层,存储引擎真正的负责了Mysql中数据的存储和提取,服务器通过API和存储引擎进行通信。不同的存储引擎具有不同的功能,这样我们可以根据自己的需要,来选取合适的存储引擎。 |
存储层 | 数据存储层,主要是将数据存储在文件系统之上,并完成与存储引擎的交互。和其他数据库相比,MySQL有点与众不同,它的架构可以在不同场景中应用并发挥良好作用。主要体现在存储引擎上,插件式的存储引擎架构,将查询处理和其他的系统任务以及数据的存储提取分离。这种架构可以根据业务的需求和实际需要选择合适的存储引擎。 |
存储引擎就是存储数据,建立索引,更新查询数据等等技术的实现方式。存储引擎是基于表的,而不是基于库的。所以存储引擎也可以被称为表类型。插件式存储引擎是Mysql数据库最重要的特性之一。Mysql5.7包含的存储引擎有:InnoDB、MyISAM、BDB、MEMORY、MERGE、NDB cluster、ARCHIVE、CSV、BLACKHOLE、FEDERATED等,其中InnoDB和BDB提供事务安全表,其他存储引擎是非事物安全表。mysql5.5之前默认存储引擎是MyISAM,5.5之后是InnoDB。
###查看数据库默认操作引擎;可以更改配置文件default_storage_engine 配置
mysql> show variables like '%default_storage_engine%';
+------------------------+--------+
| Variable_name | Value |
+------------------------+--------+
| default_storage_engine | InnoDB |
+------------------------+--------+
##查看mysql支持的存储引擎
mysql> show engines;
常用存储引擎特性
特点 | innodb | myISAM | MEMORY | MERGE | NDB |
---|---|---|---|---|---|
存储限制 | 64TB | 有 | 有 | 没有 | 有 |
事务安全 | 支持 | ||||
锁机制 | 行锁 (适合高并发) | 表锁 | 表锁 | 表锁 | 行锁 |
B树索引 | 支持 | 支持 | 支持 | 支持 | 支持 |
HASh索引 | 支持 | ||||
全文索引 | 5.6之后支持 | 支持 | |||
集群索引 | 支持 | ||||
数据索引 | 支持 | 支持 | 支持 | ||
索引缓存 | 支持 | 支持 | 支持 | 支持 | 支持 |
数据可压缩 | 支持 | ||||
空间使用 | 高 | 低 | N/A | 低 | 低 |
内存使用 | 高 | 低 | 中等 | 低 | 高 |
批量插入速度 | 低 | 高 | 高 | 高 | 高 |
支持外键 | 支持 |
MyISAM是mysql5.5之前默认存储引擎,不支持事务和外键,每个MyISAM表在磁盘上存储成3个文件,其文件名和表名相同,扩展名分别是:
.frm 存储表定义(8版本是.sdi,表的元数据信息) .MYD(MYDATA,存储数据) .MYI(MYIndex,存储索引)
数据文件和索引文件可以放置在不同的目录,平均分布IO,获取更快的速度。 MyISAM的表支持3种不同的存储格式。
静态表(固定长度)表(默认的存储格式) 动态表 压缩表
案例: 切换引擎Innodb到MyISAM.
mysql> show create table t_dept;
+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t_dept | CREATE TABLE `t_dept` (
`dept_id` int NOT NULL,
`dept_name` varchar(30) NOT NULL,
PRIMARY KEY (`dept_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> alter table t_dept engine=MyISAM;
Query OK, 4 rows affected (0.46 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> select * from t_dept;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
| 10 | 研发部 |
| 20 | 市场部 |
| 30 | 销售部 |
| 40 | 教学部 |
+---------+-----------+
4 rows in set (0.06 sec)
#####################底层文件变化
[root@localhost ~]# ll /var/lib/mysql/myschool/
total 336
-rw-r----- 1 mysql mysql 114688 Apr 19 21:24 salary_tab.ibd
-rw-r----- 1 mysql mysql 114688 Apr 19 01:13 tb_testinfo.ibd
-rw-r----- 1 mysql mysql 114688 Apr 19 04:40 t_dept.ibd
-rw-r----- 1 mysql mysql 114688 Apr 19 04:41 t_emp.ibd
-rw-r----- 1 mysql mysql 6876 Apr 19 02:58 t_user_371.sdi
-rw-r----- 1 mysql mysql 452 Apr 19 03:56 t_user.MYD
-rw-r----- 1 mysql mysql 2048 Apr 19 03:56 t_user.MYI
[root@localhost ~]# ll /var/lib/mysql/myschool/
total 268
-rw-r----- 1 mysql mysql 114688 Apr 19 21:24 salary_tab.ibd
-rw-r----- 1 mysql mysql 114688 Apr 19 01:13 tb_testinfo.ibd
-rw-r----- 1 mysql mysql 2957 Apr 20 04:10 t_dept_377.sdi
-rw-r----- 1 mysql mysql 80 Apr 20 04:10 t_dept.MYD
-rw-r----- 1 mysql mysql 2048 Apr 20 04:10 t_dept.MYI
-rw-r----- 1 mysql mysql 114688 Apr 19 04:41 t_emp.ibd
-rw-r----- 1 mysql mysql 6876 Apr 19 02:58 t_user_371.sdi
-rw-r----- 1 mysql mysql 452 Apr 19 03:56 t_user.MYD
-rw-r----- 1 mysql mysql 2048 Apr 19 03:56 t_user.MYI
InnoDB是MySQL5.5 之后的默认存储引擎,提供了具有提交,回滚和崩溃恢复能力的事务安全保障,同时提供了更小的粒度和更强的并发能力,拥有自己独立的缓存和日志。但是对比MyISAM的存储引擎,Innodb写的处理效率差一些,并且会占用更多的磁盘空间以保留数据和索引。
InnoDB的外键约束,MYSQL支持外键的存储引擎只有InnoDB,在创建外键的时候,要求父表必须有对应的索引(一般关联表的主键,因为主键非空切唯一)。 3.1. No ACTION和RESTRICT: 是指限制在子表有关联记录的情况下,父表不能更新; 3.2. CASCADE: 父表在更新或者删除时,更新或者删除对应子表的记录。 3.3. SET NULL:表示父表在更新或者删除的时候,子表的对应字段被SET NULL。
InnoDB主键和索引:Innodb的数据文件本身就是以聚簇索引的形式保存,这个聚簇索引也被称为主索引(主键),Innodb的每行数据都保存在主索引的叶子节点上,所以Innodb表必须有索引,没有索引会自动创建一个长度为6个字节的long类型的隐藏字段作为索引,除了主键外的索引都叫辅助索引或者二级索引,他们会指向主索引,并通过主索引获取最终的数据。
Memory 存储引擎将表的数据存放在内存中。每个MEMORY表实际对应一个磁盘文件,后缀是.frm,该文件中只存储表的结构,而其数据文件,都是存储在内存中,这样有利于数据的快速处理,提高整个表的效率。memory类型的表访问非常快,因为他的数据是存放在内存中的,并且默认使用HASH索引,但是服务一旦关闭,表中的数据就会丢失。
create table `city_memory` (
`city_id` int not null auto_increment primary key ,
`city_name` varchar(50) not null ,
`country_id` int not null
) ENGINE=memory auto_increment=5 default charset = utf8;
MERGE存储引擎是一组MyISAM表的组合,这些MyISAM表必须结构完全相同,MERGE表本身并没有存储数据,对MERGE类型的表可以进行查询、更新、删除操作,这些操作实际上是对内部MyISAM表进行的。
对于MERGE类型表的插入操作,是通过INSERT_METHOD字句定义插入的表,可以有3个不同的值,使用FIRST或LAST值使得插入操作被相应作用在第一或者最后一个表上,不定义这个字句或者定义为NO,表示不能对这个MERGE表执行插入操作。
可以对MERGE表进行DROP操作,但是这个操作只是删除MERGE表的定义,对内部的表是没有任何影响的。
MERGE表在磁盘上保留两个文件,文件名以表的名字开始,一个.frm 文件存储表定义,另一个.MRG文件包含组合表的信息。
MERGE存储示例,创建3个测试表:
create table order_1990(
order_id int,
order_money double(10,2),
order_adderss varchar(50),
primary key (order_id)
) engine = myisam default charset = utf8;
create table order_1991(
order_id int,
order_money double(10,2),
order_address varchar(50),
primary key (order_id)
) engine = myisam default charset = utf8;
--前面2张表的merge表
create table order_all(
order_id int,
order_money double(10,2),
order_address varchar(50),
primary key (order_id)
) engine = merge union = (order_1990,order_1991)
-- 表示向merge表插入数据时,插入到最后一个表上
INSERT_METHOD=LAST default charset=utf8;
--向order_1990插入2条数据
insert into order_1990 values (1,100.0,'北京');
insert into order_1990 values (2,100.0,'sh');
--向order_1991插入2条数据
insert into order_1991 values (10,200.0,'bj');
insert into order_1991 values (11,200.0,'sh');
insert into order_all values (15,400.0,'sh');
select * from order_all;