MySQL架构和存储引擎

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请求的管理器线程,也可以通过选项文件配置单独的线程

客户端连接线程管理

连接管理器线程在接收到每个客⼾端连接后,把请求转发到真正的执⾏线程(餐厅内部的服务员,前面刚进门服务你的属于迎宾),每个请求都对应⼀ 个执⾏线程,该线程处理连接的⾝份验证和具体请求。执⾏线程使⽤线程池技术进⾏缓存,当⼀个请 求需要处理时,先从线程池中查找是否有可⽤的线程,如果没有则新创建⼀个,当连接结束时,如果线程池没有满,则把当前线程放⼊线程池,主要的作⽤是提⾼线程的复⽤,减少创建线程造成的系统 开销从⽽提⾼效率。

对,线程的池化技术真是伟大的发明:

子非线程池中物_c#thread.isback-CSDN博客https://blog.csdn.net/chestnut_orenge/article/details/142555540?spm=1001.2014.3001.5501

可以提升线程的复用率,减少线程因不断进行创建销毁的开销

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表时,不会在磁盘上创建任何文件,表中不能存储任何数据,查询的时候始终返回一个空结果

其他

不容的存储引擎的特性对比:

相关推荐
努力算法的小明3 分钟前
SQL 复杂查询
数据库·sql
斗-匕6 分钟前
MySQL 三大日志详解
数据库·mysql·oracle
代码中の快捷键12 分钟前
MySQL数据库存储引擎
数据库·mysql
只因在人海中多看了你一眼13 分钟前
数据库体系
数据库
尘浮生35 分钟前
Java项目实战II基于微信小程序的电影院买票选座系统(开发文档+数据库+源码)
java·开发语言·数据库·微信小程序·小程序·maven·intellij-idea
六月闻君1 小时前
MySQL 报错:1137 - Can‘t reopen table
数据库·mysql
SelectDB技术团队1 小时前
兼顾高性能与低成本,浅析 Apache Doris 异步物化视图原理及典型场景
大数据·数据库·数据仓库·数据分析·doris
inventecsh1 小时前
mongodb基础操作
数据库·mongodb
白云如幻1 小时前
SQL99版链接查询语法
数据库·sql·mysql
爱吃烤鸡翅的酸菜鱼2 小时前
MySQL初学之旅(4)表的设计
数据库·sql·mysql·database