您的位置:首页 > 数据库 > SQL

MySQL深入学习——第二章 MySQL架构与存储引擎

2019-06-21 17:39 1286 查看

一、MySQL的逻辑架构体系

1、逻辑架构

 

2、连接层

连接到服务器,服务器需要对其进行验证,也就是用户名、IP、密码验证,一旦连接成功,还要验证是否具有执行某个特定查询的权限(例如,是否允许客户端对某个数据库某个表的某个操作)。

当MySQL启动(MySQL服务器就是一个进程),等待客户端连接,每一个客户端连接请求,服务器都会新建一个线程处理(如果是线程池的话,则是分配一个空的线程),每个线程独立,拥有各自的内存处理空间。

show VARIABLES like '%max_connections%';

 

连接到服务器,服务器需要对其进行验证,也就是用户名、IP、密码验证,一旦连接成功,还要验证是否具有执行某个特定查询的权限(例如,是否允许客户端对某个数据库某个表的某个操作)

  1. SQL处理层

这一层主要功能有:SQL语句的解析、优化,缓存的查询,MySQL内置函数的实现,跨存储引擎功能(所谓跨存储引擎就是说每个引擎都需提供的功能(引擎需对外提供接口)),例如:存储过程、触发器、视图等。

1)如果是查询语句(select语句),首先会查询缓存是否已有相应结果,有则返回结果,无则进行下一步(如果不是查询语句,同样调到下一步)

2)解析查询,创建一个内部数据结构(解析树),这个解析树主要用来SQL语句的语义与语法解析;

3)优化:优化SQL语句,例如重写查询,决定表的读取顺序,以及选择需要的索引等。这一阶段用户是可以查询的,查询服务器优化器是如何进行优化的,便于用户重构查询和修改相关配置,达到最优化。这一阶段还涉及到存储引擎,优化器会询问存储引擎,比如某个操作的开销信息、是否对特定索引有查询优化等。

3.1、sql缓存

show variables like '%query_cache_type%'   -- 默认不开启

show variables like '%query_cache_size%'  -- 默认值1M

SET GLOBAL query_cache_type = 1;  -- 会报错

query_cache_type只能配置在my.cnf文件中,这大大限制了qc的作用,在生产环境建议不开启,除非经常有sql完全一模一样的查询。QC严格要求2次SQL请求要完全一样,包括SQL语句,连接的数据库、协议版本、字符集等因素都会影响

3.2、解析查询

[code]SELECT DISTINCT <select_list> FROM <left_table> <join_type>
JOIN <right_table> ON <join_condition>
WHERE <where_condition> GROUP BY <group_by_list>
HAVING <having_condition> ORDER BY <order_by_condition> LIMIT <limit_number>;

3.3、sql优化

EXPLAIN select * from account where name ='';

EXPLAIN select * from account where 1=1;

EXPLAIN select * from account where id is null; -- 默认不会使用where条件

通过上面的sql大概就能看出,虽然现在还没学执行计划,但通过这个已经看出一个sql并不一定会去查询物理数据,sql解析器会通过优化器来优化程序员写的sql

explain select * from account t where t.id  in (select t2.id from account t2) show warnings;

4、逻辑架构

MySQL逻辑架构包括:连接层,服务层,引擎层,存储层。

在mysql中其实还有个schema的概念,这概念没什么太多作用,只是为了兼容其他数据库,所以也提出了这个,在mysql中 database 和schema是等价的

create database demo;

show databases;

drop schema demo;  -- 等价于drop database demo;

show databases;

5、物理存储结构

数据库的数据库(DataDir),mysql安装的时候都要指定datadir,其查看方式为:

show VARIABLES like 'datadir',其规定所有建立的数据库存放位置

5.2、数据库

创建了一个数据库后,会在上面的datadir目录新建一个子文件夹

表文件

用户建立的表都会在上面的目录中,它和具体的存储引擎相关,但有个共同的就是都有个frm文件,它存放的是表的数据格式。

mysqlfrm --diagnostic  /data1/hankin/account.frm (要查看.frm需要安装mysql utilities)

mysql utilities 安装

tar -zxvf mysql-utilities-1.6.5.tar.gz

cd mysql-utilities-1.6.5

python ./setup.py build

python ./setup.py install

二、存储引擎

常见的MySQL存储引擎:MyISAM,Innodb,Archive,Memory,Federated

#看你的mysql现在已提供什么存储引擎:

mysql> show engines;

#看你的mysql当前默认的存储引擎:

mysql> show variables like '%storage_engine%';

1、MyISAM

MySql 5.5之前默认的存储引擎,MyISAM 存储引擎由MYD和MYI组成。

[code]create table testmysam (
  id int PRIMARY key
) ENGINE=myisam;

insert into testmysam  VALUES(1),(2),(3);

表压缩

# myisampack -b -f /usr/local/mysql/data/mall/testmysam.MYI

myisampack -b -f /data1/hankin/testmysam.MYI

压缩后再往表里面新增数据就新增不了

insert into testmysam VALUES(1),(2),(3);

[root@localhost /]# insert into testmysam VALUES(5);

-bash: syntax error near unexpected token `('

压缩后,需要

# myisamchk -r -f  /usr/local/mysql/data/mall/testmysam.MYI

myisamchk -r -f  /data1/hankin/testmysam.MYI

1.2、适用场景:

  • ·非事务型应用(数据仓库,报表,日志数据)
  • 只类应用
  • 空间类应用(空间函数,坐标)

由于现在innodb越来越强大,myisam已经停止维护(绝大多数场景都不适合)

2、Innodb

Innodb是一种事务性存储引擎,完全支持事务得ACID特性,具有Redo Log和Undo Log,并且Innodb支持行级锁(并发程度更高)。

show VARIABLES like 'innodb_log_buffer_size';

CSV格式存储:

以csv格式进行数据存储,则所有列都不能为null的,且不支持索引(不适合大表,不适合在线处理),可以对数据文件直接编辑(保存文本文件内容)。

[code]create table mycsv(id int not null,c1 VARCHAR(10) not null,c2 char(10) not null) engine=csv;
create index idx_id on mycsv(id);
insert into mycsv values(1,'aaa','bbb'),(2,'cccc','dddd');

# vi /usr/local/mysql/data/mall/mycsv.CSV  -- 修改文本数据

vi /data1/hankin/mycsv.CSV

flush TABLES;

select * from mycsv;

3、Archive

3.1、组成

以zlib对表数据进行压缩,磁盘I/O更少。

数据存储在ARZ为后缀的文件中。

3.2、特点:

只支持insert和select操作。

只允许在自增ID列上加索引。

[code]create table myarchive(id int auto_increment not null,c1 VARCHAR(10),c2 char(10), key(id)) engine = archive;
create index idx_c1 on myarchive(c1)

INSERT into myarchive(c1,c2) value('aa','bb'),('cc','dd');

注意:执行delete和update的操作会报错

delete from myarchive where id = 1;

update myarchive set c1='aaa' where id = 1;

> 1031 - Table storage engine for 'myarchive' doesn't have this option

> 时间: 0.001s

4、Memory

4.1、特点

  • 文件系统存储特点
  • 也称HEAP存储引擎,所以数据保存在内存中
  • 支持HASH索引和BTree索引
  • 所有字段都是固定长度 varchar(10) = char(10)
  • 不支持Blog和Text等大字段
  • Memory存储引擎使用表级锁
  • 最大大小由max_heap_table_size参数决定

show VARIABLES like 'max_heap_table_size'

[code]create table mymemory(id int,c1 varchar(10),c2 char(10),c3 text) engine = memory;

执行结果:

> 1163 - The used table type doesn't support BLOB/TEXT columns

> 时间: 0s

[code]create table mymemory(id int,c1 varchar(10),c2 char(10)) engine = memory;
create index idx_c1 on mymemory(c1);
create index idx_c2 using btree on mymemory(c2);

show index from mymemory;

show TABLE status LIKE 'mymemory';

与临时表的区别

使用场景

hash索引用于查找或者是映射表(邮编和地区的对应表)

用于保存数据分析中产生的中间表

用于缓存周期性聚合数据的结果表

5、存储引擎-Ferderated

Ferderated存储引擎,默认是不支持的,如果要开启该存储引擎,需要在MySQL安装目录下的my.ini文件中,加上fedetated=1。重启MySQL即可生效。

由于Ferderated表数据不存储本地文件系统,而全部存储到远程服务器上,因此在本地系统中,除了要存储Ferdetated表结构信息,还要存储远程服务器信息。

特点

  • 提供了访问远程MySQL服务器上表的方法
  • 本地不存储数据,数据全部放到远程服务器上
  • 本地需要保存表结构和远程服务器的连接信息

使用场景

偶尔的统计分析及手工查询

如何使用

默认禁止,启用需要再启动时增加federated参数

mysql://user_name[:password]@hostname[:port_num]/db_name/table_name

4.1、查询同一个数据库实例下面不同的数据库表数据

建表语句如上所示,建立远程库remote(表remote_fed),以及本地库local(local_fed)

注意本地数据库引擎配置,然后即可查询:

1)远程库创建,创建远程库remote,创建表remote_fed

[code]CREATE DATABASE remote;
DROP TABLE IF EXISTS remote.`remote_fed`;
CREATE TABLE remote.`remote_fed` (
`id` int(11) NOT NULL,
`c1` varchar(50) DEFAULT NULL,
`c2` int(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO remote.`remote_fed` VALUES ('1', 'aaa', '1111');
INSERT INTO remote.`remote_fed` VALUES ('2', 'bbb', '2222');
INSERT INTO remote.`remote_fed` VALUES ('3', 'ccc', '33333');

2)本地库创建:

[code]CREATE DATABASE local;

DROP TABLE IF EXISTS local.`local_fed`;
CREATE TABLE local.`local_fed` (
  `id` int(11) NOT NULL,
  `c1` varchar(50) DEFAULT NULL,
  `c2` int(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=FEDERATED CONNECTION='mysql://root:123456%@192.168.30.128:3307/remote/remote_fed';

select * from local.local_fed;

注意:首先需要开启ferderated 引擎,默认是关闭的。

4.2、查询不同数据库实例下面不同的数据库表数据

1)远程库创建,创建远程库remote3308,创建表remote_fed

[code]CREATE DATABASE remote3308;

DROP TABLE IF EXISTS remote3308.`remote_fed`;
CREATE TABLE remote3308.`remote_fed`  (
  `id` int(11) NOT NULL,
  `c1` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `c2` int(255) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8;
INSERT INTO remote3308.`remote_fed` VALUES (1, 'aaa', 1111);
INSERT INTO remote3308.`remote_fed` VALUES (2, 'bbb', 2222);
INSERT INTO remote3308.`remote_fed` VALUES (3, 'ccc', 33333);

2)创建本地数据库local3307

[code]CREATE DATABASE local3307;

DROP TABLE IF EXISTS local3307.`local_fed`;
CREATE TABLE local3307.`local_fed` (
  `id` int(11) NOT NULL,
  `c1` varchar(50) DEFAULT NULL,
  `c2` int(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=FEDERATED CONNECTION="mysql://root:123456%@192.168.30.128:3308/remote3308/remote_fed";

select * from local_fed;

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: