MySQL C/S架构
MySQL是基于客户机-服务器的数据库,客户机-服务器应用分为两个不同的部分:
- 服务器程序直接跟要存储的数据打交道,多个客户端程序可以连接到这个服务器程序,向服务器发送增删改查的请求,然后服务器程序根据这些请求,对存储的数据做出相应的处理。
- 客户端是与用户打交道的软件,客户机将用户请求发送给服务器程序。客户机软件可以是MySQL提供的工具、脚本语言、Web开发语言、程序设计语言等。
mysqld和mysql
- mysqld:服务端守护进程,代表MySQL服务器程序的进程称之为MySQL数据库实例(instance)。
- mysql:客户端连接命令,每个MySQL都安装有一个名为mysql的简单命令行实用程序,加上一些参数连接到服务端进程。
MySQL两种连接模式
-
TCP/IP方式(远程、本地 ):真实环境中数据库的服务器进程和客户端进程可能运行在不同的主机中,它们之间必须通过网络进行通信。MySQL采用TCP作为服务器和客户端之间的网络通信协议,通过IP地址+端口的方式实现进程之间的通信。MySQL服务器在启动时默认申请3306端口号,之后监听这个端口号等待客户端进程连接。
mysql -uroot -p123456 -h 10.0.0.6 -P3306
可以通过在启动服务器程序的命令添加启动选项或者编辑配置文件的方式修改默认端口号:
# 启动选项 mysqld -P3307 # 配置文件 vim my.cnf port=3307
-
Socket方式(仅本地):如果服务器进程和客户端进程都运行在类Unix的同一台机器上,则可以通过Unix域套接字进行进程间通信。MySQL服务器程序默认监听的Unix域套接字文件名称为/tmp/mysql.sock,客户端程序也默认连接到该套接字文件。
mysql -uroot -p123456 -S /tmp/mysql.sock
可以通过在启动服务器程序的命令添加启动选项或者编辑配置文件的方式修改套接字文件:
# 启动选项 mysqld --socket=/tmp/a.txt # 配置文件 vim my.cnf socket=/tmp/a.txt
mysqld程序结构
一条SQL语句的执行过程
连接层
客户端进程可以通过TCP/IP、套接字等方式与服务端进程建立连接;
每当有一个客户端进程连接到服务端进程时,服务端进程都会创建一个线程专门处理与这个客户端的交互;
在客户端程序发起连接时,需要携带主机信息、用户名、密码等信息,服务器程序会对客户端程序提供的信息进行认证。
连接层作用总结:
- 提供连接协议:TCP/IP、SOCKET
- 提供验证:用户、密码、IP、SOCKET
- 提供专用连接线程:接收用户SQL,返回结果
在成功建立连接后,与该客户端关联的服务端线程会一直等待客户端发送过来的请求。
可以通过通过show processlist;语句查看连接线程基本情况:
mysql [(none)]>show processlist;
+----+------+-----------+------+---------+------+----------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+------+-----------+------+---------+------+----------+------------------+
| 10 | root | localhost | NULL | Query | 0 | starting | show processlist |
+----+------+-----------+------+---------+------+----------+------------------+
1 row in set (0.00 sec)
SQL层
在建立连接后,当输入select user,authentication_string,host from mysql.user;语句后,需要进行下一步的处理,此时进入SQL层。
- 接收上层传送的SQL语句
- 语法验证:验证语句语法,是否满足SQL_MODE
- 语义检查:判断SQL语句的类型
DDL :数据定义语言
DCL :数据控制语言
DML :数据操作语言
DQL: 数据查询语言
… - 权限检查:用户对库表有没有权限
- 解析器:对语句执行前,进行预处理,生成解析树(执行计划),即就是生成多种执行方案.
- 优化器:根据解析器得出的多种执行计划,进行判断,选择最优的执行计划(可以通过EXPLAIN语句来查看某语句的执行计划)
基于代价模型:资源(CPU IO MEM)的耗损评估性能好坏 - 执行器:根据最优执行计划,执行SQL语句,产生执行结果
执行结果:在磁盘的某位置上 - 提供查询缓存(默认是没开启的),会使用redis tair替代查询缓存功能。
- 提供日志记录(日志管理章节):binlog,默认是没开启的。
存储引擎层
到服务器程序完成了查询优化为止,还没有真正的去访问真实的表中数据。MySQL服务器把数据的存储和提取操作都封装到了名为存储引擎的模块中。存储引擎层类似于Linux中的文件系统,在物理上如何记录、怎么从表中读取数据、以及怎么把数据写入具体的物理存储器上,都是存储引擎负责的事情。为了实现不同的功能,MySQL提供了各式各样的存储引擎,不同存储引擎管理的表可能有不同的存储结构。
存储引擎为上层提供了统一的调用接口,在上层完成了查询优化生成执行计划后,按照计划调用存储引擎提供的接口获取到数据后返回给客户端即可(一般以记录为单位)。
- 负责根据SQL层执行的结果,从磁盘上拿数据。
- 将16进制的磁盘数据交由SQL结构化化成表,
- 最后由连接层的专用线程将结果返回给用户。
SHOW ENGINES;查看当前服务器程序支持的存储引擎
mysql [(none)]>SHOW ENGINES;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| CSV | YES | CSV storage engine | NO | NO | NO |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
| FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.00 sec)
MySQL逻辑结构
-
库:保存有组织的数据的容器,通常是一个文件或一组文件。
-
表:某种特定类型的结构化清单,数据库中的每个表都有一个唯一的名字用来标识自己;表有一些特性,这些特性定义了数据在表中如何存储。
表属性:- 存储引擎:InnoDB(默认)
- 字符集:UTF8、UTF8MB4
在MySQL中,字符集表示一个字符所用的最大字节长度,在某些方面会影响系统的存储和性能;
utfmb3(utf8):使用1-3个字节表示字符
utfmb4:使用1-4个字节表示字符mysql [mysql]>show charset like 'utf8%'; +---------+---------------+--------------------+--------+ | Charset | Description | Default collation | Maxlen | +---------+---------------+--------------------+--------+ | utf8 | UTF-8 Unicode | utf8_general_ci | 3 | | utf8mb4 | UTF-8 Unicode | utf8mb4_general_ci | 4 | +---------+---------------+--------------------+--------+ 2 rows in set (0.34 sec)
- 排序规则:可设置大小写是否敏感,后缀为_ci不区分大小写,后缀为_cs区分大小写,后缀为_bin以二进制方式比较
mysql [mysql]>show collation like 'utf8_general%'; +--------------------------+---------+-----+---------+----------+---------+ | Collation | Charset | Id | Default | Compiled | Sortlen | +--------------------------+---------+-----+---------+----------+---------+ | utf8_general_ci | utf8 | 33 | Yes | Yes | 1 | | utf8_general_mysql500_ci | utf8 | 223 | | Yes | 1 | +--------------------------+---------+-----+---------+----------+---------+ 2 rows in set (0.00 sec)
-
列:列是表中的一个字段,所有表都是由一个或多个列组成的;每个列都有相应的数据类型,数据类型限制列中存储的数据,以及帮助正确的排列数据,且在优化磁盘使用方面起到了重要的作用。
列属性:约束(一般建表时添加)- primary key:主键约束。设置为主键的列,此列的值必须非空且唯一,主键在一个表中只能有一个,但是可以由多个列构成。
- not null:非空约束。列值不能为空,也是表设计的规范,尽可能将所有列设置为非空,可以设置默认值为0。
- unique:唯一键。列值不能重复。
- unsigned:无符号。针对数字列,非负数。
其他属性
- key:索引。可以在某列上建立索引来优化查询,一般根据需要后添加。
- default:默认值。列中如果没有写入值则自动使用default的值填充。
- auto_increment:自增长。针对数字列,顺序的自动填充数据(默认从1开始,可以设定起始点和偏移量)。
- comment:注释。
-
行:一行表示一个记录,表中的行数为记录的总数。表中的每一行都应该有唯一标识自己的一列(或一组列),称之为主键。表中的任何列都可以作为主键,只要满足两个条件:任意两行都不具有相同的主键值;每个行都必须具有一个主键值(主键列不允许NULL值)。
MySQL存储结构
- 库:库其实就是操作系统下的一个目录
# 创建一个test库 mysql [(none)]>create database test; Query OK, 1 row affected (0.25 sec) mysql [(none)]>show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | test | +--------------------+ 5 rows in set (0.36 sec) # 退出到操作系统shell mysql [(none)]>exit Bye # 进入数据库数据目录,可以发现库其实就是操作系统下的一个目录 [root@localhost ~]# cd /data/mysql/ [root@localhost mysql]# ls auto.cnf ib_logfile0 localhost.localdomain.err performance_schema ib_buffer_pool ib_logfile1 localhost.pid sys ibdata1 ibtmp1 mysql test
- 表:对于不同存储引擎下的表存储方式不同
mysql 5.7.20 库下的表[root@localhost mysql]# cd mysql/ [root@localhost mysql]# ll ... # MyISAM存储引擎 -rw-r-----. 1 mysql mysql 10816 Sep 23 12:17 user.frm --存储表结构信息 -rw-r-----. 1 mysql mysql 396 Sep 23 12:42 user.MYD --存储表数据信息 -rw-r-----. 1 mysql mysql 4096 Sep 23 12:42 user.MYI --存储表索引信息 # InnoDB存储引擎(默认存储引擎) -rw-r-----. 1 mysql mysql 8636 Sep 23 12:17 time_zone.frm --存储表结构信息 -rw-r-----. 1 mysql mysql 98304 Sep 23 12:17 time_zone.ibd --存储表数据信息(记录+索引)
- 表的段、区、页
页:最小存储单元(16K)
区:一个或多个连续的页
段:一个或多个连续的区,一个表就是一个段