同学安利了一个掘金手册《MySQL是怎样运行的:从根上理解MySQL》,翻阅了一下目录,发现它讲的正是我一直想要了解的数据库优化、InnoDB(虽然一直不知道这个InnoDB是什么,不过面试很爱考就是了。)、日志、事务、锁… 于是我开始了这个小册的学习,仍是用先学习一遍,然后自己写总结,而后根据资料补充的方式。毕竟书买了看了多少不重要,能有多少被内化成自己的东西才是最重要的。这篇博客主要记录学习历程,希望它完结之时,我对MySQL的理解可以较以前深入,更上一层楼,不只是停留在之前只会写简单的增删改查语句(不过也是得先会增删改查,而后才能删库跑路啊呼哈哈哈哈哈哈O(∩_∩)O)。
《重新认识MySQL》20191225
1. 先把我能想到的写下来:
MySQL这个软件和Web服务一样,也是采用的C/S模型,当我们使用MySQL时,(我的版本是5.7.21),其实是使用着MySQL服务器与客户端。由客户端向服务器发送查询语句,由服务器执行,然后将查询的结果返回给客户端。服务器程序和客户端程序都可以看作一个进程,进程会有唯一的编号PID,如MySQL服务器程序的是mysqld,客户端的是mysql,操作系统会为各进程随机分配端口号,并保证同一时间同一台电脑上各进程的端口号不重复。启动MySQL服务器的默认进程端口号是3306。
[补:代表着MySQL服务器程序的进程也被称为(MySQL)数据库实例。]
服务器进程与客户端进程之间的通信有以下三种形式:
1.
如果服务器与客户端不是同一台主机,它们之间的通信需要借助网络,遵循TCP/IP协议,采用IP地址+端口号的形式,套接字???
[补:
采用 TCP 作为服务器和客户端之间的网络通信协议。每台计算机都有一个唯一的IP地址,如果进程有需要采用TCP协议进行网络通信方面的需求,可以向操作系统申请一个端口号,0—65535,这样在网络中的其他进程就可以通过IP地址+端口号的方式来与这个进程连接。
MySQL服务器启动时默认申请3306端口,之后就在这个端口上等待客户端进程进行连接,即MySQL服务器会监听3306端口。]
如果是在Windows系统上,可能采用命名管道,在启动服务器程序的命令后加 --enabled-name-pipe,和共享内存 --shared-memory(前提是服务器与客户端在同一台主机上)的形式。
[改: --enabled-named-pipe]
如果是在类Unix系统(类Unix系统的特点是可分时、多任务、多客户端,像macOS、寒假要学的Linux操作系统),可采用域套接字文件。
如果一个程序经常被使用,可以使它在Windows系统被启动时也被启动,用命令:“完整的可执行文件路径” --install
把它注册为Windows服务。然后用net start mysql
就可以启动它,用net stop mysql
就可以停止服务。
MySQL服务器响应客户端请求的过程是这样的:
1.建立连接:连接管理,也就是上面进程通信的三种方式。
[ 补:
每当有客户端连接到服务器进程时,服务器进程就会创建一个线程来专门处理与客户端的交互,客户端退出时会与服务器断开连接,服务器并不会立即把与该客户端交互的线程销毁掉,而是缓存起来,在与另一个新的客户端再进行连接时,把这个缓存的线程分配给该新客户端,这样就不会频繁创建和销毁线程,节省开销。
如果客户端和服务器不在一台主机上,可以用SSL(安全套接字)的网路连接来进行通信,保证数据传输的安全性。]
2.查询与优化
(1)查询
(2)
(3)查询优化
查询缓存的作用是避免重复查询,效率低下。
[改:
2.解析与优化:
查询缓存
语法解析
查询优化]
[补:
从MySQL5.7.20开始,不推荐使用查询缓存,并在8.0中删除。
查询优化:对语句进行一些优化,如外连接变成内连接、表达式简化、子查询变成内连接等等。
优化的结果是生成一个执行计划,通过EXPLAIN语句可以查看某个语句的执行计划。]
3.存储引擎
存储引擎指的是数据的读取与操作的方式,怎样读取数据?怎样写入数据?可以为不同的表设置不同的存储引擎。
[改:存储引擎:数据的存储和提取操作。]
如InnoDB,MyISAM默认的存储引擎是InnoDB,可以提供多表连接操作。
[改:InnoDB:具备外键支持功能的事务存储引擎。]
下载MySQL的一系列东西以后,可以看到:
有许多可执行文件,重点关注mysql.exe, 与微信类似,作为客户端需要向服务器提供用户名、密码的信息:之前老是在cmd命令行里写:
mysql -h localhost -u root -p
其实就是运行这个mysql.exe文件,并且配置了参数"-h"表示服务器的IP号,如果服务器与客户端在一台主机上,这个参数可以省略,或者用localhost或者用127.0.0.1,而"-u"是user用户名,-p是password密码。
[改:"-h"表示服务器进程所在计算机的域名或IP地址]
[补:只有一个英文字母的参数称为短形式的参数,使用前需要加单短划线,否则为长形式的参数,加双短划线]
[补:
mysql>是一个客户端的提示符,后面写的是客户端向服务器发送的命令。
如果想断开客户端与服务器的连接并关闭客户端,可以用quit或者exit或者\q
它会回个bye
]
2.补充:
-
我们日常使用MySQL的情景一般是这样:
1.启动MySQL服务器程序。
2.启动MySQL客户端程序,并连接到服务器程序。
3.在客户端程序中输入一些命令语句作为请求发给服务器,… -
Mysql存储引擎:
在mysql客户端中,使用以下命令可以查看MySQL支持的引擎:
show engines;
运行结果如图:
- MyISAM
MyISAM表是独立于操作系统的,这说明可以轻松地将其从Windows服务器移植到Linux服务器;每当我们建立一个MyISAM引擎的表时,就会在本地磁盘上建立三个文件,文件名就是表名。例如,我建立了一个MyISAM引擎的tb_Demo表,那么就会生成以下三个文件:
1.tb_demo.frm,存储表定义;
2.tb_demo.MYD,存储数据;
3.tb_demo.MYI,存储索引。
MyISAM表 无法处理事务 ,这就意味着有事务处理需求的表,不能使用MyISAM存储引擎。
MyISAM存储引擎特别适合在以下几种情况下使用:
- 选择密集型 的表。MyISAM存储引擎在筛选大量数据时非常迅速,这是它最突出的优点。
- 插入密集型 的表。MyISAM的并发插入特性允许同时选择和插入数据。例如:MyISAM存储引擎很适合管理邮件或Web服务器日志数据。
-
InnoDB
InnoDB是一个健壮的事务型存储引擎,这种存储引擎已经被很多互联网公司使用,为用户操作非常大的数据存储提供了一个强大的解决方案。我的电脑上安装的MySQL5.6.13版,InnoDB就是作为默认的存储引擎。InnoDB还引入了行级锁定和外键约束,在以下场合下,使用InnoDB是最理想的选择:
1.更新密集的表。InnoDB存储引擎特别适合处理多重并发的更新请求。
2.事务。InnoDB存储引擎是支持事务的标准MySQL存储引擎。
3.自动灾难恢复。与其它存储引擎不同,InnoDB表能够自动从灾难中恢复。
4.外键约束。MySQL支持外键的存储引擎只有InnoDB。
5.支持自动增加列AUTO_INCREMENT属性。
一般来说,如果***需要事务支持,并且有较高的并发读取频率***,InnoDB是不错的选择。 -
MEMORY
使用MySQL Memory存储引擎的出发点是 速度 。为得到最快的响应时间,采用的逻辑存储介质是系统内存。虽然在内存中存储表数据确实会提供很高的性能,但当mysqld守护进程崩溃时,所有的Memory数据都会丢失。 获得速度的同时也带来了一些缺陷。它要求存储在Memory数据表里的数据使用的是长度不变的格式,这意味着不能使用BLOB和TEXT这样的长度可变的数据类型,VARCHAR是一种长度可变的类型,但因为它在MySQL内部当做长度固定不变的CHAR类型,所以可以使用。
一般在以下几种情况下使用Memory存储引擎:
1.目标数据较小,而且被非常频繁地访问。在内存中存放数据,所以会造成内存的使用,可以通过参数max_heap_table_size控制Memory表的大小,设置此参数,就可以限制Memory表的最大大小。
2.如果数据是***临时***的,而且***要求必须立即可用***,那么就可以存放在内存表中。
3.存储在Memory表中的数据如果突然丢失,不会对应用服务产生实质的负面影响。
Memory同时支持散列索引和B树索引。B树索引的优于散列索引的是,可以使用部分查询和通配查询,也可以使用<、>和>=等操作符方便数据挖掘。散列索引进行“相等比较”非常快,但是对“范围比较”的速度就慢多了,因此散列索引值适合使用在=和<>的操作符中,不适合在<或>操作符中,也同样不适合用在order by子句中。
可以在表创建时利用USING子句指定要使用的版本。例如:
复制代码代码如下:
create table users
(
idsmallint unsigned not null auto_increment,
usernamevarchar(15) not null,
pwdvarchar(15) not null,
indexusing hash (username),
primarykey (id)
)engine=memory;
上述代码创建了一个表,在username字段上使用了HASH散列索引。下面的代码就创建一个表,使用BTREE索引。
复制代码代码如下:
create table users
(
idsmallint unsigned not null auto_increment,
usernamevarchar(15) not null,
pwdvarchar(15) not null,
indexusing btree (username),
primarykey (id)
)engine=memory;
-
MERGE
MERGE存储引擎是一组MyISAM表的组合,这些MyISAM表结构必须完全相同,尽管其使用不如其它引擎突出,但是在某些情况下非常有用。说白了,Merge表就是几个相同MyISAM表的聚合器;Merge表中并没有数据,对Merge类型的表可以进行查询、更新、删除操作,这些操作实际上是对内部的MyISAM表进行操作。Merge存储引擎的使用场景。
对于服务器日志这种信息,一般常用的存储策略是将数据分成很多表,每个名称与特定的时间端相关。例如:可以用12个相同的表来存储服务器日志数据,每个表用对应各个月份的名字来命名。当有必要基于所有12个日志表的数据来生成报表,这意味着需要编写并更新多表查询,以反映这些表中的信息。与其编写这些可能出现错误的查询,不如将这些表合并起来使用一条查询,之后再删除Merge表,而不影响原来的数据,删除Merge表只是删除Merge表的定义,对内部的表没有任何影响。 -
ARCHIVE
Archive是归档的意思,在归档之后很多的高级功能就不再支持了,仅仅支持最基本的插入和查询两种功能。在MySQL5.5版以前,Archive是不支持索引,但是在MySQL 5.5以后的版本中就开始支持索引了。Archive拥有很好的压缩机制,它使用zlib压缩库,在记录被请求时会实时压缩,所以它经常被用来当做仓库使用。 -
存储引擎的一些问题
1.如何查看服务器有哪些存储引擎可以使用?
为确定你的MySQL服务器可以用哪些存储引擎,执行如下命令:
show engines;
这个命令就能搞定了。
2.如何选择合适的存储引擎?
(1)选择标准可以分为:
(2)是否需要支持事务;
(3)是否需要使用热备;
(4)崩溃恢复:能否接受崩溃;
(5)是否需要外键支持;
然后按照标准,选择对应的存储引擎即可。
问题汇总
- 可以有多个客户端,那么可以有多个服务器吗?我们在自己电脑用的服务器是不是只有一个呢?
已解决:
”其实我们一台计算机上也可以运行多个服务器实例,也就是运行多个MySQL服务器进程。mysql_multi 可执行文件可以对每一个服务器进程的启动或停止进行监控。这个命令的使用比较复杂,本书主要是为了讲清楚MySQL服务器和客户端运行的过程,不会对启动多个服务器程序进行过多唠叨。“
2.IP号+端口=套接字?套接字是干嘛用的?
已解决:
网络通信,归根结底是进程间的通信(不同计算机上的进程间通信)。
在一台计算机中,端口号和进程之间是一一对应的关系,所以,使用端口号和网络地址的组合可以唯一地确定整个网络中的一个网络进程。