(一)初识 MySQL
- MySQL 的客户端/服务器架构
和我们平时使用的大部分软件一样,MySQL 由这两部分组成(客户端和服务器),它的使用过程大致是:服务器程序直接和我们存储的数据打交道,然后可以有多个客户端程序连接到这个服务器程序,发送增删改查的请求,服务器接收到这些请求后响应,从而操作它维护的数据。
MySQL 服务器程序和客户端程序本质上都算是计算机上的一个进程,每个进程都有一个唯一的编号,称为进程ID,英文名叫 PID,这个编号是在我们启动程序的时候由操作系统随机分配的(每次启动时可能都不一样)。每个进程都有一个名称,这个名称是编写程序的人自己定义的,比如我们启动的 MySQL 服务器进程的默认名称为 mysqld, 而我们常用的MySQL客户端进程的默认名称为 mysql。
- MySQL 的安装
一般我们正常安装 MySQL 的话都会把服务器程序和客户端程序装到我们的机器里,安装时注意记住你的安装目录(安装跳过)。
以在 UNIX 操作系统的安装目录为例:
/usr/local/mysql/
在 MySQL 的安装目录下有一个特别重要的 bin 目录,这个目录下存放着许多可执行文件:
/usr/local/mysql/bin
假设我们现在所处的工作目录是 MySQL 的安装目录,也就是 /usr/local/mysql,我们想启动 bin 目录下的 mysqld 这个可执行文件,可以使用相对路径来启动:
./bin/mysqld
或者直接输入 mysqld
/usr/local/mysql/bin/mysqld
又或者将该 bin 目录的路径加入到环境变量 PATH 中,各个路径之间使用冒号":"隔离开:
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
上面例子中的环境变量 PATH 的值表明:当我在输入一个命令时,系统便会在 /usr/local/bin、/usr/bin、/bin、/usr/sbin、/sbin 这些目录下依次寻找是否存在我们输入的那个命令(如果存在则执行),将 MySQL 安装目录下的bin目录的路径也加入到 PATH 中:
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/mysql/bin
这样现在不论我们所处的工作目录是啥,我们都可以直接输入可执行文件的名字就可以启动它,比如这样:
mysqld
启动 MySQL 服务器程序
- mysqld
mysqld 这个可执行文件就代表着 MySQL 服务器程序,运行这个可执行文件就可以直接启动一个服务器进程,另外还有mysqld_safe、mysql.server、mysqld_multi 等启动命令,之前倒没怎么用过。
这里穿插一下 Windows 服务(之前没了解过)
- Windows 服务
如果需要长时间的运行某个程序,并且在计算机启动的时候便启动它,一般我们都会把它注册为一个 Windows 服务,操作系统会帮我们管理它。把某个程序注册为 Windows 服务的方式挺简单,如下:
"完整的可执行文件路径" --install [-manual] [服务名]
其中的 -manual 可以省略,加上它的话表示在 Windows 系统启动的时候不自动启动该服务,否则会自动启动。服务名也可以省略,默认的服务名就是 MySQL。比如我的 Windows 计算机上 mysqld 的完整路径是:
C:\Program Files\MySQL\MySQL Server 5.7\bin\mysqld
所以如果我们想把它注册为服务的话可以在命令行里这么写:
"C:\Program Files\MySQL\MySQL Server 5.7\bin\mysqld" --install
在把 mysqld
net start MySQL
关闭这个服务也非常简单,只要把上边的 start 换成 stop
net stop MySQL
启动 MySQL 客户端程序
在成功启动 MySQL 服务器程序后,就可以接着启动客户端程序来连接到这个服务器了,这里主要使用 bin 目录下的可执行文件 mysql。启动这个可执行文件时一般需要一些参数,格式如下:
mysql -h主机名 -u用户名 -p密码
按照你的情况填写就可以启动 MySQL 客户端,并且连接到服务器了。
mysql -hlocalhost -uroot -p123456
连接成功后的界面:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.21 Homebrew
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
最后一行的 mysql> 是一个客户端的提示符,之后客户端发送给服务器的命令都需要写在这个提示符后边。
如果需要断开连接并且关闭客户端的话,可以在 mysql> 提示符后输入下边任意一个命令:
- quit
- exit
- \q
mysql> quit
Bye
- 服务器处理客户端请求
大部分服务器程序处理来自客户端的查询请求需要经过三个部分,分别是连接管理、解析与优化、存储引擎。
连接管理
每当有客户端断开连接,服务器并不会立即把与该客户端交互的线程销毁掉,而是把它缓存起来,从而节省开销。
如果客户端程序和服务器程序不运行在一台计算机上,可以采用使用了 SSL(安全套接字)的网络连接进行通信,来保证数据传输的安全性。
当连接建立后,服务器线程会一直等待客户端发送过来的请求,MySQL 服务器接收到的请求只是一个文本消息,想执行该文本消息还要经过各种解析和优化。
解析与优化
拿到了文本形式的请求,还需要经过几个重要的过程,分别是查询缓存、语法解析和查询优化
- 查询缓存
如果我问你 123 × 456 = ?,你可能会动脑去算一下,得到了结果 56088,如果我再问你一遍 123 × 456 = ?我们便可以跳过计算过程直接说答案就好了(缓存)。MySQL 也会把刚刚处理过的查询请求和结果缓存起来,并且这个查询缓存可以在不同客户端之间共享。
缓存失效的情况:①任何字符上的不同(例如:空格、注释、大小写) ②包含系统函数、用户自定义变量和函数、一些系统表 ③表的结构或者数据被修改。
- 语法解析
从指定的文本中提取出我们需要的信息本质上算是一个编译过程,涉及词法解析、语法分析、语义分析等阶段。
- 查询优化
语法解析之后,已经知道了要查询的列是哪些,表是哪个,搜索条件是什么等,但 SQL 语句执行起来的效率可能不高,MySQL 的优化程序会对我们的语句做一些优化,如外连接转换为内连接、表达式简化、子查询转为连接等。优化的结果就是生成一个执行计划,这个执行计划表明了应该使用哪些索引进行查询,表之间的连接顺序是怎样的,执行计划可用 EXPLAIN 语句查看。
存储引擎
截止到服务器程序完成了查询优化为止,还没有真正的去访问真实的数据表,MySQL服务器把数据的存储和提取操作都封装到了一个叫存储引擎的模块里。我们知道表是由一行一行的记录组成的,但这只是一个逻辑上的概念,物理上如何表示记录,怎么从表中读取数据,怎么把数据写入具体的物理存储器上,这都是存储引擎负责的事情。为了实现不同的功能,MySQL 提供了各式各样的存储引擎,不同存储引擎管理的表具体的存储结构可能不同,采用的存取算法也可能不同。
常用的存储引擎有 InnoDB、MyISAM 和 Memory(置于内存的表)
关于存储引擎的一些操作
查看当前服务器程序支持的存储引擎:
SHOW ENGINES;
设置表的存储引擎
前边说过,存储引擎是负责对表中的数据进行提取和写入工作的,我们可以为不同的表设置不同的存储引擎,也就是说不同的表可以有不同的物理存储结构,不同的提取和写入方式。
创建表时指定存储引擎:
CREATE TABLE 表名(
建表语句;
) ENGINE = 存储引擎名称;
比如想创建一个存储引擎为 MyISAM 的表可以这么写:
mysql> CREATE TABLE engine_demo_table(
-> i int
-> ) ENGINE = MyISAM;
Query OK, 0 rows affected (0.02 sec)
mysql>
修改表的存储引擎
如果表已经建好了,可以使用下边这个语句来修改表的存储引擎:
ALTER TABLE 表名 ENGINE = 存储引擎名称;
比如我们修改一下 engine_demo_table 表的存储引擎:
mysql> ALTER TABLE engine_demo_table ENGINE = InnoDB;
Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql>
这时再查看一下 engine_demo_table 的表结构:
mysql> SHOW CREATE TABLE engine_demo_table\G
*************************** 1. row ***************************
Table: engine_demo_table
Create Table: CREATE TABLE `engine_demo_table` (
`i` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.01 sec)
mysql>
可以看到该表的存储引擎已经改为 InnoDB 了。