MySQL架构
MySQL8.0服务器是由连接池、服务管理⼯具和公共组件、NoSQL接口、SQL接口、解析器、优化 器、缓存、存储引擎、⽂件系统组成。MySQL还为各种编程语言提供了⼀套⽤于外部程序访问服务器 的连接器。整体架构图如下所示:
我们来简单举个栗子来描述这个,,过程吧
假设;励志轩是一名邮专的弟子(我要吐了),他现在考完试了放寒假回家和好朋友聚餐,肯定要去一个餐厅(也不是吧,假设去),那两个角色就出来了:
角色1:励志轩及其友人(客户方)
角色2:餐厅(服务方)
励志轩到餐厅了,服务员问他:几位?(1.确认人数 2.看看有无预定 2.看看还有没有空的桌子,如果没有那排号)
到了里面(服务器)之后捏?
那就不是连接层操心的事了
MySQL connectors:为了使用MySQL服务的编程语言平台,提供了访问接口,可以根据自己实际使用的编程语言到官网地址下载
MySQL :: MySQL Community Downloadshttps://dev.mysql.com/downloads/
MySQL Shell:是一个高级客户端和代码编辑器,以组件的形式提供,需要单独安装,除了提供的类似于mysql客户端的功能,还可以使用JavaScript和Python调用MySQL的API,一般为开发人员使用
连接层:对客户端连接进行权限校验并保存客户端的连接信息,通过池化技术实现线程重用,以及根据具体的配置限制连接数量
服务管理和公共组件:提供了数据备份和恢复,安全组件,主从复制和集群管理,表分区等实用功能
服务层:提供了NoSQL API、SQL API,SQL语句解析,SQL语句优化,SQL语句缓存等组件,并将优化后的SQL语句发送至相应的存储引擎执行相应的操作并返回结果
存储引擎层:一系列可插拔的存储引擎,主要负责数据的写入和读取,与底层的数据和日志文件进行交互,可以根据具体的业务需求选择不同的存储引擎
文件系统层:包含了MySQL发行版的文件和程序,以及具体的数据库文件和日志
连接层
连接层的作用是处理客户端的连接
MySQL是一个网络服务,通过IP+端口号就可以找到网络上指定的MySQL服务(程序在启动时可以向OS申请一个端口)
网络端口
一台服务器可以侦听多个网络端口上的客户端连接,开放多个端口,只需要在选项文件中指定多个端口即可:
sql
[mysqld] # mysqld节点
port=3306 # 端⼝1
port=3307 # 端⼝2
连接管理线程
在所有平台上,用一个管理层线程处理所有的TCP/IP连接请求
在Unix上,管理器线程还可以处理其他的Unix socket连接请求
在Windows上,用一个管理器线程处理通过shared-memory的方式连接请求,使用另一个管理器线程(老板单独的桌子)处理Named-Pipe方式连接请求
在所有的平台上,可以额外启用一个端口用于接收针对管理的TCP/IP连接请求,管理端口的连接可以使用处理普通TCP/IP请求的管理器线程,也可以通过选项文件配置单独的线程
客户端连接线程管理
连接管理器线程在接收到每个客⼾端连接后,把请求转发到真正的执⾏线程(餐厅内部的服务员,前面刚进门服务你的属于迎宾),每个请求都对应⼀ 个执⾏线程,该线程处理连接的⾝份验证和具体请求。执⾏线程使⽤线程池技术进⾏缓存,当⼀个请 求需要处理时,先从线程池中查找是否有可⽤的线程,如果没有则新创建⼀个,当连接结束时,如果线程池没有满,则把当前线程放⼊线程池,主要的作⽤是提⾼线程的复⽤,减少创建线程造成的系统 开销从⽽提⾼效率。
对,线程的池化技术真是伟大的发明:
可以提升线程的复用率,减少线程因不断进行创建销毁的开销
sql
[mysqld] # mysqld节点
thread_cache_size=16 #线程池⼤⼩
thread_stack=1048576 #堆栈内存⼤⼩
thread_cache_size和thread_stack的大小需要根据机器的具体配置进行调整
连接量管理
系统变量max_connections 可以控制服务器允许同时连接的最大客户端数,当服务器达到max_connections 指定的连接数时会拒绝所有的新的连接请求,同时会增加状态变量Connection_errors_max_connections
mysqld 实际上允许max_connections+1 个客户端链接,额外的连接为拥有CONNECTION_ADMIN 权限的账户(管理员)使用,即使普通连接达到了max_connections的数量,管理员也可以链接到服务器进行管理操作
在部署为主的主从复制环境中,从节点的链接数也会计入max_connections中,如果连接到上限则主从复制也会失败
max_connections具体数据和服务器的硬件有关,比如可用的内存,每个连接消耗的内存,每个连接的工作负载,响应时间,可用的文件描述符的数量。。。
服务层
数据库服务层是整个数据库服务器的核心,主要包括了服务器管理和公共组件,NoSQL和SQL接口,解析器、查询优化器和缓存。。。
服务管理和公共组件
MySQL提供了多种功能服务以满足在不同场景下的需要,下面是一些常用的服务:
Backup&Recovery:备份与恢复
Security:安全
Replication:主从复制
Cluster:MySQL集群
Partitioning:表分区
Instance Manager:实例管理
Administrator:MySQL管理员
Migration Toolkit:迁移⼯具包
NoSQL接口和SQL接口
主要负责接收客⼾端发送的各种SQL语句和命令,并将SQL发送到其他部分,然后把接收到的结果返回给客⼾端
Parser(语法分析器)
语法分析器的主要作⽤是将客⼾端发来的SQL语句中的关键字和⾃定义字段进⾏提取、解析,最 终将SQL语句转换为⼀棵解析树,分析的过程中包含词法分析和语法分析;词法分析,主要是对关键字进⾏提取,⽐如 select/update/delete/create... ;
语法分析,主要判断SQL语句是否满 ⾜语法规则,如果语法错误则异出异常,也就是我们常⻅的ERROR 1064(42000):You have an error in your SQL syntax
sql
# 例如有如下SQL语句, 对应的解析树⼤致如图所⽰
select sn, name from student where id = 1;
Optimizer(查询优化器)
通过语法校验的SQL语句将进入查询优化器处理阶段,查询优化器将会将解析树转化为查询计划,一般情况下一条查询可以有很多种执行方案,查询优化器会根据执行计划匹配合适的索引,选择最佳的执行方案,最终把确定要执行的SQL文件交给执行器调用存储引擎API
tips:优化后的SQL语句在条件查询时可能与程序员写的条件过滤顺序不同,但是最终返回的结果一致
Caches&Buffers(缓存)
MySQL的缓存主要的作用是为了提升查询的效率,当服务器接收到⼀个 select 查询语句时,会先进⼊缓存查询当前SQL语句在缓存中是否存在,缓存以 key 和 value 的形式存储,key是具体的 SQL语句,value是结果的集合,如果命中缓存,直接返回结果,⽆法命中缓存,则进⼊分析器进⾏正 常查询流程。
缓存数据对应的数据在被更新之后将会失效,尤其在写多读少的场景中,缓存会频繁失效与新增,命中率⾮常低,因此MySQL5.6之后服务层缓存功能默认关闭,⽽且在 MySQL8.0中服务层缓存被官⽅删除
SQL语句的执行流程
一张图秒了,欢迎荷叶饭来偷
存储引擎
还是看一眼整体的架构图,看看存储引擎的所在位置
在服务层下面,作用是对数据进行处理,属于核心层
1.如何组织数据也是选用哪种数据结构
2.如何保证数据安全
3.如何保证读写效率
4.使用哪种存储介质
存储引擎是处理不同类型SQL操作的MySQL组件,MySQL服务器采用可插拔的存储引擎架构,在服务器运行时可以动态加载和卸载
查看当前服务器支持哪些存储引擎可以使用SHOW ENGINES语句
Engine表示存储引擎的名称
Support表示当前服务器是否支持(值分别为YES,NO,DEFAULT)分别表示,支持或者不支持和当前的设置或者默认引擎:
sql
mysql> SHOW ENGINES\G
ERROR 4031 (HY000): The client was disconnected by the server because of inactivity. See wait_timeout and interactive_timeout for configuring this behavior.
No connection. Trying to reconnect...
Connection id: 19
Current database: mysql
*************************** 1. row ***************************
Engine: ARCHIVE
Support: YES
Comment: Archive storage engine
Transactions: NO
XA: NO
Savepoints: NO
*************************** 2. row ***************************
Engine: BLACKHOLE
Support: YES
Comment: /dev/null storage engine (anything you write to it disappears)
Transactions: NO
XA: NO
Savepoints: NO
*************************** 3. row ***************************
Engine: MRG_MYISAM
Support: YES
Comment: Collection of identical MyISAM tables
Transactions: NO
XA: NO
Savepoints: NO
*************************** 4. row ***************************
Engine: FEDERATED
Support: NO
Comment: Federated MySQL storage engine
Transactions: NULL
XA: NULL
Savepoints: NULL
*************************** 5. row ***************************
Engine: MyISAM
Support: YES
Comment: MyISAM storage engine
Transactions: NO
XA: NO
Savepoints: NO
*************************** 6. row ***************************
Engine: PERFORMANCE_SCHEMA
Support: YES
Comment: Performance Schema
Transactions: NO
XA: NO
Savepoints: NO
*************************** 7. row ***************************
Engine: InnoDB
Support: DEFAULT
Comment: Supports transactions, row-level locking, and foreign keys
Transactions: YES
XA: YES
Savepoints: YES
*************************** 8. row ***************************
Engine: MEMORY
Support: YES
Comment: Hash based, stored in memory, useful for temporary tables
Transactions: NO
XA: NO
Savepoints: NO
*************************** 9. row ***************************
Engine: CSV
Support: YES
Comment: CSV storage engine
Transactions: NO
XA: NO
Savepoints: NO
9 rows in set (0.27 sec)
下面的介绍就是:存储引擎名,简介,是否支持食物,分布式,事务的保存点
InnoDB
InnoDB是一款兼顾可靠性和高性能的通用存储引擎,在MySQL8.0默认的存储引擎是InnoDB,使用create table语句创建表时,在没有修改默认存储引擎或明确其他存储引擎时,将创建一个InnoDB的表
特性
分别是:
B+树索引
备份与恢复
聚簇索引
数据压缩
数据缓存
数据加密
外键
全文索引
地理空间数据类型,经纬度
地理空间索引
内部使用自适应哈希实现
索引的缓存
锁粒度,行级锁
多版本并发控制
主从复制
存储最大限制
事务
更新数据字典的统计
主要优势
DML操作遵循ACID模型,事务具有提交、回滚和崩溃恢复功能、以保护用户数据
🧐 如果发生意外而崩溃,无论当时数据库发生了什么,都不需要重启数据库后执行任何特殊操作
InnoDB的崩溃功能会自动完成崩溃之前提交的更改,并撤销崩溃前正在但未提交的更改,从而允许我们从中断的地方继续执行
🤓 支持行级锁,提高了多用户的读取和并发性和性能
😭InnoDB存储引擎维护了自己的缓冲池(以SQL为KEY,对应的数据为VALUE),访问数据时在内存中缓存表和索引数据,对于经常使用的数据直接从内存中处理,大幅提升了效率,在在专用数据库服务器上,通常会将80%的物理内存分配给缓冲池
🧐InnoDB表优化了基于主键的查询,每个InnoDB表都有一个聚簇索引的主键索引,实现通过最少的磁盘I/O完成对主键的查找
🤓为了保持数据完整性,InnoDB支持FOREIGN KEY外键约束,在进行插入、更新和删除数据时确保相关表之间的一致性
😭当从表中反复查询相同的行时,自适应哈希索引会自动接管这些查询,此时的查询效率和哈希表相同
最佳实践(利用InnoDB的特性实现最佳性能)
为了表中最查询的列(或者多个列)指定主键,如果没有明显的主键,则创建一个自增的列作为主键
从多个表中根据相同的ID查询数据,建议使用表连接,可以连接的列上定义外键,并在每个表中提交相同的数据类型声明这些列,添加外键可以确保被引用的列使用索引,从而提高性能
在每秒提交数百次事务的服务器上,结合存储设备的写入速度,关闭事务的自动提交,通过系统变量autocommit=OFF设置
把相关的DML操作⽤START TRANSACTION 和 COMMIT 语句括在⼀起,分组为事务⼀起提交或 回滚
不要使⽤ LOCK TABLES 语句,InnoDB可以在不牺牲可靠性和⾼性能的情况下处理多个会话同时 对⼀个表进⾏读写操作
验证InnoDB是否为存储引擎
sql
*************************** 7. row ***************************
Engine: InnoDB
Support: DEFAULT
Comment: Supports transactions, row-level locking, and foreign keys
Transactions: YES
XA: YES
Savepoints: YES
执行SHOW ENGINES语句查看可用的存储引擎时,查找SUPPORT列的值DEFAULT的行
可以这样查询Information Schema库中的ENGINES表
如果InnoDB不是默认的存储引擎,可以通过在命令行指定选项--default-storage-engine=InnoDB或者在选项文件中的[mysqld]结点定义default-storage-engine=InnoDB并重新启动服务器来设置InnoDB存储引擎
sql
[mysqld] # 服务器节点下
default-storage-engine=InnoDB #明确指定InnoDB存储引擎
由于业务实际需要,服务器默认存储引擎不是InnoDB时,想要创建一个InnoDB表,可以在使用CREATE TABLE语句创建表时明确指定InnoDB存储引擎,当然这样方式可以指定其他任何支持的存储引擎
sql
CREATE TABLE table_name (
... 定义字段
) ENGINE = InnoDB; # 指定存储引擎
如果想测试使用其他存储引擎表的数据在InnoDB表中的工作情况,在确保不影响原始表的情况下,使用以下方式创建一张InnoDB表:
sql
CREATE TABLE ... ENGINE=InnoDB AS SELECT * FROM other_engine_table;
sql
# 选择⽬标数据库
use test_db
# 创建⼀个使⽤InnoDB存储引擎的表
CREATE TABLE t_innodb (
id int(11) PRIMARY KEY AUTO_INCREMENT,
name varchar(20)
) ENGINE = InnoDB;
在创建一个存储引擎为InnoDB的表时,会在data_dir/test_db目录下生成一个用来存储真实数据的物理文件,命名格式为表名.idb,以当前为例会在/var/lib/mysql/test_db目录下生成一个t_innodb.idb的表空间数据文件
在MySQL8.0中表结构的信息也保存在.idb文件中,可以使用ibd2sdi工具提取表定义的具体信息,使用方法,使用方法: ibd2sdi --dump-file=t_innodb.txt t_innodb.ibd,生成的t_innodb.txt文件中有对应的表的具体描述
sid=Serialized Dictionary Information序列化字典信息
和8.0有所不同的是,在MySQL5.X及以前的版本中使⽤⼀个后缀为 .frm 的二进制文件来记录和描述表定义的信息
MyISAM
在MySQL5.5之前默认的存储引擎是MyISAM的存储引擎
既然能被MySQL选中称为默认存储引擎,那证明它是有一定的独特之处的
使用MySQL存储引擎的表占用空间小,但是由于使用表级锁定,所以限制了读/写操作的性能,通常用于中小型的Web应用和数据配置中的只读或者主要是读的场景
查询效率很高(因为用了B+树索引)
和InnoDB的区别就在于,外键、事务、Hash索引都不支持,锁粒度不同,单表的大小限制不一样
主要优势
MyISAM表的最大行数为(2^32)^2及(1.844E+19)行
每个MyISAM表最多可以创建64个索引,每个索引最多可以包含16个列
支持并发插入
通过Create Table创建表时指定DATA DIRECTORY=PATH和INDEX
DIRECTORY=PATH将数据文件和索引文件放在不同设备的不同目录中,从而提高访问速度
BLOB和TEXT数据类型的列也可以被索引
在索引列中允许使用NULL值
如果mysqld启动的时候设置了myisam_recover_options系统变量,那么MyISAM表在打开的时候进行自查,如果上一次表没有正确的关闭将会修复
表中VARCHAR和CHAR列的长度总和最多可以到达64KB
UNIQUE约束的长度不受限制
表
在MySQL8.0中默认是InnoDB引擎,所以在创建表的时候需要指定ENGINE=MyISAM:
sql
# 创建⼀个使⽤MyISAM存储引擎的表
CREATE TABLE t_myisam (
id int(11) PRIMARY KEY AUTO_INCREMENT,
name varchar(20)
) ENGINE = MyISAM;
创建MyISAM表会根据表名生成三个不同的后缀名文件,分别是以.MYD(MYData)为后缀的数据文件,以.MYI(MYIndex)为后缀的索引文件,以.sdi为后缀的表的信息描述文件(JSON格式)
在8.0之前的版本表信息描述文件是以.frm为后缀的二进制文件:
818是自动生成的序号
sql
mysql> system ls -l
total 584
-rw-r----- 1 mysql mysql 114688 Oct 22 23:18 classes.ibd
-rw-r----- 1 mysql mysql 114688 Oct 22 23:18 course.ibd
-rw-r----- 1 mysql mysql 131072 Oct 24 09:30 general_log.ibd
-rw-r----- 1 mysql mysql 114688 Oct 22 23:18 score.ibd
-rw-r----- 1 mysql mysql 114688 Oct 22 23:18 student.ibd
-rw-r----- 1 mysql mysql 2777 Oct 28 12:19 t_myisam_818.sdi
-rw-r----- 1 mysql mysql 0 Oct 28 12:19 t_myisam.MYD
-rw-r----- 1 mysql mysql 1024 Oct 28 12:19 t_myisam.MYI
存储格式
🕊 MyISAM 表⽀持三种不同的存储格式,其中FIXED 静态(固定) 格式和DYNAMIC 动态 格式,根据 使⽤的列类型⾃动选择,第三种是压缩格式,只能使⽤ myisampack 实⽤程序⽣成并且是只读格 式
🐕 当表中没有 BLOB 或 TEXT 数据类型的列,在使⽤ CREATE TABLE 或 ALTER TABLE 语句创 建或修改表时,可以结合 ROW_FORMAT 表选项将表格式设置为 FIXED 或 DYNAMIC
🐈 使⽤ myisamchk 实⽤⼯具对已压缩的MyISAM进⾏解压操作, myisamchk --unpack
静态格式表(Fixed-Length)
静态格式是MyISAM表的默认格式,当表不含可变长度的列(VARCHAR、VARBINARY、BLOB、TEXT)时使用,每行都使用固定数量的字节存储
MyISAM 的三种存储格式中,静态格式是最简单和最安全的(最不容易损坏),同时也是最快的 磁盘格式,因为每⾏的⻓度固定,根据索引中的⾏号乘以⾏⻓度就可以计算出⾏位置,此外,每次 读取固定数量的⾏也⾮常的⾼效
静态格式表特点:
CHAR 和VARCHAR 类型的列⽤空格填充到指定的列宽
BINARY 和VARBINARY 类型的列 ⽤ 0x00 字节填充到列宽
每个允许为NULL的列,都⽤⼀个1 BIT 的额外空间记录当前列是否为空
速度⾮常快,且易于缓存
崩溃后易于重建,因为⾏都位于固定位置
通常需要⽐动态格式表更多的磁盘空间
动态格式表
动态格式表也有一些特点,当表中包含变⻓度列( VARCHAR 、 VARBINARY 、 BLOB 或TEXT )或者在创建表时使⽤ ROW_FORMAT=DYNAMIC 选项,则表格式为动态存储格式,一般有这样的特点:
列类型是字符串,且⻓度⼤于等于4,⻓度都是动态的;
🐩 每⼀⾏都有⼀个标志来指⽰⾏有多⻓,当因更新操作⽽变得更⻓时,数据可能存储在不连续的空间,可以使⽤ OPTIMIZE TABLE table_name 语句或myisamchk -r 对表进⾏碎⽚整理;
🐇 每个允许为NULL的列,都⽤⼀个1 BIT 的额外空间记录当前列是否为空;
🐿 每⾏前⾯都有⼀个 bitmap (位图),⽤来记录包含空字符串或0的列,如果字符串类型的列⻓度 为零,或者数字列的值0,则在位图中标记并且不会保存到磁盘;
🦔 通常磁盘空间占⽤⽐固定⻓度表要少很多; (行中存储的是真是数据的长度)
每⾏都单独压缩,每列都可能⽤单独的⽅式进⾏压缩
常见的压缩方式:
🐕 如果数值列的值为0,⽆论原始数据类型是哪种都⽤⼀个 BIT 类型存储
🐈 如果整数列中的值范围较⼩,则尽可能使⼩的类型存储该列,⽐如:列中的值范围在 -128 到127 之间,即使原始类型为 bigint (8bytes),也使⽤ TINYINT (1byte)类型存储
🕊 如果列中只有⼀⼩组可能出现的值,则数据类型转换为 ENUM
压缩格式表
压缩存储格式是使用myisampack工具生成的只读格式数据表,压缩表可以使用myisamchk解压缩
压缩格式表具有以下的特点:
压缩表占用很少的磁盘空间,最大限度的减少了磁盘的使用
可以用于固定长度或动态长度的行
压缩表是只读的,因此不能在表中更新或者添加数据
MEMORY
对于InnoDB和MyISAM是比较重要的,要知道特性和使用场景,还要会用,其他的知道就行了,用不用就是我们的事情了,使⽤MEMORY存储引擎(以前称为HEAP)创建的表,内容存储在内存中。当服务器由于硬件问题、 断电或其他原因崩溃时数据会丢失,因此这些表仅⽤作临时⼯作区或从其他表中提取数据的只读缓存
使用场景
使用场景因为它的特性就很明晰了
涉及瞬时、非关键数据的操作、例如会话管理或者需要缓存的数据,当服务器停止或重新启动的时候,MEMORY表中的数据会丢失
用于快速访问和低延时,数据量可以完全放在物理内存中,不使用虚拟内存
只读或者以读为主的数据访问场景(有限的更新)
特性
使用固定长度的存储格式,可变长度类型,例如VARCHAR使用固定长度存储
不能包含BLOB或者TEXT列
支持AUTO_INCREMENT的列
非TEMPORARY MEMORY表在所有客户端之间共享
支持HASH索引(默认)和BTREE索引
不支持表分区
由于单线程,在高负载的情况下可能会涉及严重的锁竞争,特别是在多个客户端并发执行更新操作的情况下,性能并不一定会比InnoDB更快
建表
sql
CREATE TABLE t_memory1 (
id int(11) PRIMARY KEY AUTO_INCREMENT,
name varchar(20)
) ENGINE = MEMORY;
由于数据在内存中保存,所以MEMORY表不会再磁盘生成数据文件,表结构保存数据字典和.sdi文件中:
这是从其他表中加载数据:
sql
CREATE TABLE t_memory ENGINE=MEMORY select * from student;
这是查看内存表中的数据:
sql
select * from t_memory;
如果服务器重启,那么表中的数据就没了,那么重启之后的数据该怎么加载呢?
当然是有机制:
启动时填充MEMORY表的内容,可以使用init_file系统变量指定一个SQL文件,文件中可以编写用于初始化数据的SQL语句,例如:INSERT INTO...SELECT或者LOAD DATA
内存管理
删除单⾏数据,不会回收内存,只有删除整个表时才会回收内存。当不需要内存表的内容时,要释 放该表所使⽤的所有内存,可以执⾏ DELETE 或 TRUNCATE table 删除所有⾏,或者使⽤ DROP table 删除表。如果要释放被删除⾏所使⽤的内存,使⽤ ALTER TABLE ENGINE= MEMORY 命令强制重建表
表中一行数据所需的内存使用以下表达式计算:
sql
SUM_OVER_ALL_BTREE_KEYS(max_length_of_key + sizeof(char*) * 4)
+ SUM_OVER_ALL_HASH_KEYS(sizeof(char*) * 2)
+ ALIGN(length_of_row+1, sizeof(char*))
ALIGN()函数的作用:使行长度为char类型大小的精确倍数,sizeof(char*)在32位机器上是4,在64位机器上是8
max_heap_table_size系统变量设置了内存表的最大限制,默认为16MB,要控制单个表的最大大小,在创建每个表之前设置该变量的session值(不要全局的max_heap_table_size 值,除⾮要明确设置所有客⼾端创建的内存表)
这是内存表(最大大小:1MB/2MB):
sql
# 指定第⼀张表的内存最⼤值为1MB
mysql> SET max_heap_table_size = 1024*1024;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE t1 (id INT, UNIQUE(id)) ENGINE = MEMORY;
Query OK, 0 rows affected (0.01 sec)
# 指定第⼆张表的内存最⼤值为2MB
mysql> SET max_heap_table_size = 1024*1024*2;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE t2 (id INT, UNIQUE(id)) ENGINE = MEMORY;
Query OK, 0 rows affected (0.00 sec)
每次重启服务器内存表中的数据将要被清空,内存表中的数据永远不会写入磁盘
CSV
CSV是逗号分割值的缩写,以纯文本形式存储表格数据
创建CSV表
在MySQL8.0中InnoDB是默认引擎,所以在创建表的时候需要指定engine=CSV
sql
CREATE TABLE t_csv (id INT NOT NULL, content CHAR(100) NOT NULL) ENGINE
= CSV;
创建CSV表的时候,服务器会创建三个文件,其中以.CSV为扩展名的文件用于以逗号分隔值的格式保存数据,扩展名为.CSM的文件,用于存储表的状态和表中的行数,以.sdi为后缀的表的信息描述文件(JSON格式):
CSV表中的数据
sql
INSERT INTO t_csv VALUES(1,'record one'),(2,'record two');
sql
SELECT * FROM t_csv ;
由于.CSV是文件格式的文件,所以查看文件内容如下:
CSV格式可以被Microsoft Excel等电子表格应用程序读取和写入
CSV表的修复和检查
CSV 存储引擎⽀持使⽤CHECK TABLE 和REPAIR TABLE 语句来验证或修复损坏的 CSV 表:
这是检查:
sql
CHECK TABLE t_csv;
当用文本编辑器打开t_csv.CSV文件,并写入一条新数据可以这样:
sql
vim t_csv.CSV #编辑CSV⽂件
1,"record one"
2,"record two"
3,"record three" # ⼿动写⼊⼀条新数据, 保存并退出
再次执行查询语句的时候发现没有第三条数据 ,这是由于.CSM文件中没有记录新增的行,可以使用REPAIR TABLE 语句修改表内容和CSM⽂件:
sql
REPAIR TABLE t_csv;
再次查看的时候发现手动写入的记录显示出来了:
如果我们检查的是损坏的表,那就会返回错误
当运行修复的语句时,就会删除错误的数据
tips:在修复期的时候,只有.CSV文件第一行到第一个损坏行的行被复制到新表中,从第一个损坏的行到表末尾的其他行都会被删除,即使是有效数据
CSV表限制
CSV存储引擎不支持索引
不支持分区
使用CSV存储引擎创建的表中所有列都必须为NOT NULL
ARCHIVE
使用ARCHIVE存储引擎创建的表,存储大量不被索引的数据且占用空间很小,一般用于归档(归档类似于,入学的时候学籍存在档案室)数据的存储
特性
建表
sql
CREATE TABLE t_archive (
id int(11) UNIQUE AUTO_INCREMENT,
name varchar(20)
) ENGINE = ARCHIVE;
创建ARCHIVE表会根据表名生成两个不同后缀名的文件,分别是.ARZ为后缀的数据文件,以.sdi为后缀的表信息描述文件(JSON格式),.ARN文件在优化操作期间可能会出现
BLACKHOLE
BLACKHOLE存储引擎就像是一个黑洞,接收数据但是不存储数据,检索时总是会返回一个空结果
特性
BLACKHOLE表不会存储任何数据,但如果启用了基于语句的二进制日志记录,则会记录SQL语句并将其复制到副本服务器
支持索引
不支持分区
用途
验证转储文件语法
通过比较启用和不启用二进制日志记录的性能,测量二进制日志记录的开销
本质上是一个"无操作"的存储引擎,可用于查找与存储引擎本身无关的性能瓶颈
建表
创建BLACKHOLE表时,服务器会在全局数据字典中定义表并生成.sdi为后缀的表的信息描述文件:
sql
CREATE TABLE t_blackhole(id INT, content CHAR(10)) ENGINE = BLACKHOLE;
INSERT INTO t_blackhole VALUES(1,'record one'),(2,'record two');
SELECT * FROM t_blackhole;
MERGE
MERGE存储引擎,也称之为MRG_MyISAM引擎,允许MySQL DBA或开发人员在逻辑上将一系列相同的MyISAM分组,并将它们作为一个对象引用,适用于VLDB(Very Large Data Bases)环境,如数据仓库,这里的相同表示所有表的列都有相同的数据类型和索引信息:
逻辑表是逻辑上的统一入口,基础表是真实存储数据的表
创建MERGE表
在MySQL8.0中InnoDB是默认引擎,所以在创建表时需要指定ENGINE=MERGE
创建MERGE表必须指定UNION=(list-of-tables) 选项,表⽰要使⽤哪些MyISAM表;
还可以通过指定 INSERT_METHOD 选项来控制如何对MERGE表进⾏插⼊操作, FIRST 或 LAST 值分别表⽰在第⼀个或最后⼀个基础表中进⾏插⼊,如果没有指定 INSERT_METHOD 选项,或者指定它的值为 NO ,那么在 MERGE 表中执⾏插⼊将会报错
创建基础表1:
sql
CREATE TABLE test_m1 (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
content CHAR(20)) ENGINE=MyISAM;
创建基础表2:
sql
CREATE TABLE test_m2 (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
content CHAR(20)) ENGINE=MyISAM;
向基础表中写入数据:
sql
INSERT INTO test_m1 (content) VALUES ('Testing1'),('table1'),
('test_m1');
INSERT INTO test_m2 (content) VALUES ('Testing2'),('table2'),
('test_m2');
创建MERGE表:
sql
CREATE TABLE t_merge (
id INT NOT NULL AUTO_INCREMENT,
content CHAR(20), INDEX(id))
ENGINE=MERGE UNION=(test_m1,test_m2) INSERT_METHOD=LAST;
创建MERGE表时,会在磁盘上创建一个.mrg文件,其中包含了基础MyISAM表的名称,MERGE的表格式存储在MySQL数据字典中,.sdi为后缀的表信息描述文件
操作MERGE表
基础表中的id列作为PRIMARY KEY索引,但是在MERGE表中并不作为主键,但是可以被索引
因为MERGE表不能对基础表集强制唯一性
基础表中具有UNIQUE索引的列可以在MERGE表中被索引,但不能作为唯一约束:
要将MERGE表重新映射到不同的MyISAM基础表集合,可以这样做:
删除MERGE表并重新创建
使⽤ ALTER TABLE tbl_name UNION=(...) 修改基础表的集合
ALTER TABLE...UNION=()列表为空时,表⽰删除所有基础表
使⽤ DROP TABLE 只会删除MERGE表定义,基础MyISAM表不受影响
FEDERATED
默认是不支持的,但是可以在启动的时候通过命令行选项--federated或者选项文件的配置来启用
可以看到确实是不支持
允许访问远程MySQL数据库中的数据,在不使⽤复制或集群技术的情况下, FEDERATED 存储引 擎可以实现对远程MySQL数据库中数据的访问,以多个物理服务器为基础创建⼀个逻辑数据库,当 查询 FEDERATED 表时,将会从远程数据库获取数据,⾮常适合分布式或数据集市环境。
两个环境的表的定义是相同的
本地环境只定义了表的结构,不存储真正的数据,是逻辑表
本地和远程之间通过网络连接
真实的数据保存在远程服务器
建表
本地配置文件的[mysqld]节点下加入federated=1来启用FEDERATED引擎,之后重启MySQL服务:
sql
# 配置⽂件路径 /etc/mysql/mysql.cnf
[mysqld]
federated=1 #加⼊配置
按照道理来说应该是可以启用成功的,但是我的一直报错是为什么呢
很想让荷叶饭也试试,但是她肯定会说
咱俩云服务器都是一样的,有什么试的必要么
看见我改bug你很开心吗
之类的话
主要就是改完配置文件的时候重启系统不知道为什么配置不生效
那还是先说知识吧
创建FEDERATED表时,本地的表定义与远程服务器的表定义相同,但是数据存储在远程服务器上
本地表中使用CONNECTION连接字符串指向远程表的连接字符串
sql
# 远程服务器上的建表语句
CREATE TABLE t_federated (
id INT(20) PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(32) NOT NULL DEFAULT '',
INDEX name (name)
)
ENGINE=MyISAM
DEFAULT CHARSET=utf8mb4;
语法是这样的,但是我连引擎都启动不了
sql
# 本地服务器上的建表语句
CREATE TABLE t_federated (
id INT(20) PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(32) NOT NULL DEFAULT '',
INDEX name (name)
)
ENGINE=FEDERATED
DEFAULT CHARSET=utf8mb4
CONNECTION='mysql://fed_user@remote_host:3306/test_database/test_table'; # 指定远程服务器的连接
连接字符串的格式:
scheme://user_name[:password]@host_name[:port_num]/db_name/tbl_name
scheme :连接协议,⽬前只⽀持mysql;
user_name : ⽤于连接远程服务器的⽤⼾名,注意:这个⽤⼾在远程服务器已创建,并授予了相应的操作权限;
password:用户的密码
host_name:远程服务器的IP地址
port_num:远程服务器MySQL服务的端口号
db_name:远程表所在的数据库名
tbl_name远程表名,本地表名与远程表名可以不同,但建议保持一致
这个时候就想说,连ssh的时候ssh连不上,连git的时候git连不上,现在还要有远程链接,,做不起
不会生成数据文件,表定义在数据字典中,生成.sdi为后缀的表信息描述文件(JSON格式)
建表成功后对本地表的增删改查和远程操作表一样
注意事项
远程服务器必须是MySQL服务器
使用CONNECTION字符串时,密码中不能使用"@"字符
DROP TABLE只删除本地表,不删除远程表
不支持事务
EXAMPLE
EXAMPLE是干什么的?它其实什么也不做,存在的目的是为了告诉开发人员如何编写一个新的存储引擎,是源码的示例(针对编写MySQL存储引擎的程序员,和我没关系)
不支持索引和表分区
当创建一个EXAMPLE表时,不会在磁盘上创建任何文件,表中不能存储任何数据,查询的时候始终返回一个空结果
其他
不容的存储引擎的特性对比: