前言

本文内容主要参考自《MySQL DBA 修炼之道》书中的第三章,算是原书的实践与补充。

I. MySQL 5.7配置环境变量

MySQL 5.7 版本安装路径为 C:\Program Files\MySQL\MySQL Server 5.7\bin,默认不会添加环境变量,需要自行添加。

mysql windows7环境变量配置 mysql5.7环境变量_SQL

II. SQL基础

变量

MySQL中变量可以分为用户变量和系统变量。

① 用户变量

用户变量与连接有关,一个客户端定义的变量不能被其他客户端看到或使用。当客户端退出时,该客户端连接的所有变量将自动释放。

用户变量的形式为 @var_name,设置用户变量的一个途径是执行 SET 语句,语法如下:

set @var_name=var_value[, @var_name=var_value]...

mysql windows7环境变量配置 mysql5.7环境变量_CURD_02

② 系统变量

MySQL服务器维护着两种系统变量:全局变量会话变量

全局变量会影响MySQL服务的整体运行方式,会话变量影响客户端连接的操作。

全局变量在MySQL启动的时候由服务器自动将它们初始化为默认值,这些默认值可以通过更改 my.ini 这个文件来更改,或者在命令行中对指定的选项进行更改。服务器启动后,可以通过 SET GLOBAL var_name 语句动态修改。

注意:

  • 想要通过SQL语句动态修改全局变量的话,必须要有SUPER权限
  • 访问全局变量的所有客户端都能看到对全局变量所有的修改
  • 但是注意,全局变量的修改只会影响在修改之后建立的连接。也就是说,对于已经打开的长连接或者连接池来说,由于连接从未关闭重启,全局变量的修改不会有任何效果。

服务器为每个连接的客户端维护一系列的会话变量,在连接时使用相应全局变量的当前值对客户端的会话变量进行初始化。每个客户端可以修改自己的会话变量,通过 SET SESSION var_name 语句更改。

可以使用下面的语法来设置或者检索全局变量或会话变量,使用 sort_buffer_size 作为示例变量名。

mysql windows7环境变量配置 mysql5.7环境变量_全局变量_03

MySQL数据类型


MySQL数据类型 数值类型 整型 TINYINT 1个字节 8位 SMALLINT 2个字节 16位 MEDIUMINT 3个字节 24位 INT 4个字节 32位 BGINT 8个字节 64位 实数 确切精度的值——定点数 DECIMAL 类型 (常用于货币数据),DECIMAL(M,D)占据M+2字节 近似精度的值——浮点数 单精度 FLOAT 4个字节 32位 双精度 DOUBLE 8个字节 64位 字符串类型 CHAR 可以声明0-255个字符,一旦声明完成,则为固定长度。存储值小于固定长度则右侧添加空格,大于固定长度则进行裁剪。常常用于存储长度差不多的数据,例如MD5. VARCHAR 可以声明0-65535个字符,可变长度。存储值时不会进行填充,尾部空格保留。 BINARY 固定字节长度的二进制字符串,没有字符集,排序与比较基于字节的二进制进行的。 VARBINARY 可变字节长度的二进制字符串。 BLOB 存储二进制字符串(字节字符串) 大对象 TINYBLOB BLOB MEDIUMBLOB LONGBLOB TEXT 存储非二进制字符串(字符字符串) 大对象 TINYTEXT TEXT MEDIUMTEXT LONGTEXT ENUM 枚举是一个字符串对象,其值通常选自一个允许值列表,该表是创建表时定义的。一般不推荐用,可以用TINYINT自己维护含义达到相同功能。 SET 日期/时间类型 DTAETIME 8个字节 YYYY-MM-DD HH:MM:SS DATE 3个字节 YYYY-MM-DD TIMESTAMP 4个字节 YYYY-MM-DD HH:MM:SS (更省空间,用的更多) TIME 3个字节 HH:MM:SS YEAR 1个字节 YYYY 可以用字符串或数值进行赋值


对于整型数据,MySQL支持在类型后面的小括号内指定显示宽度,默认为 int(11) 。一般配合 zerofill 使用,当位数不够的时候会补零。当然,如果位数超了,也不会截断或报错,直接显示原来的。

对于 charvarchar 两种类型,后面也可以加上括号,比如 char(11)varchar(11),对于MySQL5.0.3版本之后:

  • char(11) 代表长度固定为11个字符,如果不足会在后面添加空格,取出来的时候需要 trim() 去掉多余的空格。
  • varchar(11) 代表可以最多存储11个字符,无论中英文都可以存11个。不足就按照实际的字符数,不填充。

计算具体存放的字节数,需要考虑字符集,每个字符占用的字节数,同时 varchar 还有2个额外字节记录长度。无论怎样,char的字节数不能超过255字节,varchar 不能超过65535字节。

示例数据库

MySQL提供了一个练习所用的数据库 employees。下载地址:employees_db-full-1.0.6.tar.bz2

默认导入数据是InnoDB引擎,如果需要其他引擎,可以修改 employees.sql 文件,取消相关注释。并且如果是MySQL 5.7版本将 storage_engine 修改为 default_storage_engine

set storage_engine = InnoDB;
-- set storage_engine = MyISAM;
-- set storage_engine = Falcon;
-- set storage_engine = PBXT;
-- set storage_engine = Maria;

修改成:

set default_storage_engine = InnoDB;
-- set default_storage_engine = MyISAM;
-- set default_storage_engine = Falcon;
-- set default_storage_engine = PBXT;
-- set default_storage_engine = Maria;

select CONCAT('storage engine: ', @@default_storage_engine) as INFO;

导入 employees.sql 进数据库。

mysql -u root -p1234 -t < employees.sql

employees 数据库的 ER 关系图如下,利用 Navicat for MySQL 软件生成。

mysql windows7环境变量配置 mysql5.7环境变量_CURD_04

SQL语法

① SQL常见操作

连接 MySQL Server

mysql -h 127.0.0.1 -P 3306 -u root -p1234

连接成功,通过输入 quit 或者 exit; 进行退出。

查询当前 MySQL Server 的版本以及当前时间。

select version(), current_date, now();

创建一个数据库,名为 test

create database test;

显示所有的数据库,使用刚刚创建的 test 数据库。

show databases;
use test;

查看当前正在使用的数据库,列出其中包含的所有的表。

select database();
show tables;

mysql windows7环境变量配置 mysql5.7环境变量_CURD_05

② 数据库定义语言DDL

创建查看删除表:利用 CREATE TABLE 创建表格,利用 DESC 语句可以验证创建的表结构信息,通过 DROP TABLE 则可以删除表。

mysql windows7环境变量配置 mysql5.7环境变量_MySQL_06

修改表:主要利用 ALTER TABLE 修改表的结构。

mysql windows7环境变量配置 mysql5.7环境变量_基础_07

创建索引:使用 CREATE INDEX 语句创建索引。

mysql windows7环境变量配置 mysql5.7环境变量_MySQL_08

删除索引:使用 DROP INDEX 语句删除索引。

mysql windows7环境变量配置 mysql5.7环境变量_SQL_09

修改字符集和排序规则

alter table lookup change name name varchar(10) character set latin1 collate latin1_bin;

mysql windows7环境变量配置 mysql5.7环境变量_全局变量_10

③ 数据库操作语言DML

INSERT 语句。

新增一条数据:

insert into table_name (列1,列2,列3) values (值1,值2,值3);

新增多条:

insert into table_name (列1,列2,列3) values (值1,值2,值3),(值4,值5,值6);

DELETE 语句。

单表删除:

delete from table_name [where 条件];

多表连接删除:

delete table_name1[, table_name2...] from table_name1, table_name2... [where 条件];

UPDATE 语句。

update table_name set 列1=值1,列2=值2,列3=值3... [where 条件];

SELECT 语句。

~ 查询所有数据:

select * from table_name;

~ 查询指定列名指定数据:

select 列1,列2,列3 from table_name [where 条件];

~ SQL模式匹配:
SQL有两个通配符,下划线 “_” 匹配任意单个字符,“%” 匹配任意多个字符,包括 0 字符。模式匹配默认区分大小写,一般使用 LIKE 或者 NOT LIKE 这些比较操作符。

~ 逻辑操作符与或非 AND、OR、NOT :

select 列1,列2,列3 from table_name where 条件1 AND 条件2;
select 列1,列2,列3 from table_name where 条件1 OR 条件2;
select 列1,列2,列3 from table_name where NOT 条件1;

~ 范围操作符 INBETWEEN :

select 列1,列2,列3 from table_name where xxx in (条件1, 条件2, 条件3);
select 列1,列2,列3 from table_name where xxx between 条件1 and 条件2);

~ 限制获取记录数 LIMIT :

select * from table_name limit 起点 记录数;

~ 排序 ORDER BY :

select * from table_name order by 列名 asc;
select * from table_name order by 列名1, 列名2 desc limit 起点 记录数;

~ 数据计算:
使用 MySQL 的计算函数来进行相关计算。

~ 利用 DISTINCT 获取不重复的唯一值:
在 SQL 语句中利用 DISTINCT 相当于去重,相同的只会留下一个。

~ 聚集函数:

聚集函数包含 COUNT、MIN、MAX、AVG、SUM

mysql windows7环境变量配置 mysql5.7环境变量_CURD_11

~ 分组统计 GROUP BY

一般将分组语句与聚集函数一起使用,从而实现分组统计。不仅如此,还支持对多个列同时进行聚集计算。

select Max(a), Max(b), Max(c) from table_name where... group by d;

上面这个就是先以 d 字段进行分组,然后组内再选出利用聚集函数计算出的结果。

我们还可以在 GROUP BY 语句后面添加 HAVING 子句,并对聚集结果进行筛选。

mysql windows7环境变量配置 mysql5.7环境变量_MySQL_12

~ 并集操作 UNIONUNION ALL

对两个结果集进行合并,UNIONUNION ALL 都是对结果集合并, UNION 会去重而 UNION ALL 不会。一般情况下两个结果集并不会重复,所以为了性能能用 UNION ALL 就用 UNION ALL

合并的两个结果集也必须形式上一致,否则出错。

mysql windows7环境变量配置 mysql5.7环境变量_SQL_13

~ NULL

NULL 值的判断一般使用 IS NULL 或者 IS NOT NULL,不能使用上面的比较操作符 =,因为 NULL 是个特殊的值,表示这个值时未知或者没有定义的。

select * from table_name where 列名 is not null;

对于 GROUP BY 字句,两个 NULL 值可以认为是相等的。

对于 NULL 值的排序,NULL 认为是最小的。

④ JOIN连接

MySQL利用连接 JOIN 来查询多个表数据。表连接的方式主要是通过循环拼接方式进行的,例如表 A 连接表 B,假设表 A 的记录数比表 B 少 (记录少的在内层循环),相当于:

for 记录b_j in B:
  for 记录a_i in A:
    拼接记录a_i和记录b_j

连接的表越多,循环的层数也越多,所以设计查询时要尽量减少连接表的个数。

一般有三种连接:内连接左连接右连接。左连接和右连接其实都是外连接,MySQL中左外连接与左连接,右外连接和右连接是同一个。

内连接可以进一步分为等值连接、自然连接和交叉连接。等值连接是比较常用的,自然连接一般应该避免使用,而交叉连接其实就相当于上面的演示代码思想。

我们简单的进行演示,使用 employees 数据库中的 departmentsdept_manager 数据表。departments 中有 9 条数据,dept_manager 中有 24 条数据。

mysql windows7环境变量配置 mysql5.7环境变量_SQL_14

内连接使用 INNER JOIN 关键字。交叉连接其实就是两张表的笛卡尔积,如图交叉结果所示,departments 连接 dept_manager 表其实就是 dept_manager × departments (右表×左表),外层是24次循环,内层是9次循环。而等值连接相当于内外层循环添加了条件,条件通过 ON 关键字来实现。

for 记录b_j in B:
  for 记录a_i in A:
    if 条件1 and 条件2:
      拼接记录a_i和记录b_j

mysql windows7环境变量配置 mysql5.7环境变量_MySQL_15

左连接/左外连接用 LEFT JOIN 关键字来实现,右连接/右外连接用 RIGHT JOIN 关键字来实现。左连接的含义是指如果表 A 左连接表 B,那么最后连接的结果必然包含全部的左表 A,即使 B 中没有满足条件的,那么直接补充为 NULL。右连接含义相同,仅仅只是必然包含右表 B。一般都习惯使用左连接,因为 A LEFT JOIN B 相当于 B RIGHT JOIN A。外连接的内外层循环和记录数目无关,用代码描述 A LEFT JOIN B 其实是(A 外层循环,B 内层循环,A 是驱动表,B 是被驱动表):

for 记录a_j in A:
  for 记录b_i in B:
    if 条件1 and 条件2:
      临时表 = 拼接记录a_i和记录b_j
if 临时表 不包含所有A记录:
  临时表添加A记录中缺失的,B的那些字段值设为NULL

继续从上面的例子分析,我们先删除 dept_manager 表中所有 dept_nod009 的记录。然后我们再次通过等值连接查看结果数变为 20,将 INNER JOIN 变为 LEFT JOIN,结果多出一条,多出的正是 dept_nod009 的记录,而右表 dept_manager 中的字段属性都是 NULL

mysql windows7环境变量配置 mysql5.7环境变量_CURD_16

当然,对于连接出的结果,我们可以继续使用 WHERE 来添加条件进行过滤,但是出于性能,一般条件都在 ON 中表示,因为 ON 的条件是在连接表循环的中间判断的,而 WHERE 则需要连接产生的大表结束后一一遍历判断,性能受到影响。

具体关于连接的过程可以参考:Mysql - JOIN 详解

⑤ 子查询

子查询是指查询语句中嵌套着 SELECT 语句。例如:

select * table1 where column1 = (select column1 from table2);

select * table1 是外部查询,select column1 from table2 是子查询。MySQL 对于子查询的优化不佳,所以一般可以将子查询的语句改写为 JOIN 语句,因此一般建议使用 JOIN 的方式查询数据。

生产环境一般不推荐 select * 的通配符 *

⑥ 查询执行顺序

MySQL 查询执行的顺序是:

(7)     SELECT
(8)     DISTINCT <select_list>
(1)     FROM <left_table>
(3)     <join_type> JOIN <right_table>
(2)     ON <join_condition>
(4)     WHERE <where_condition>
(5)     GROUP BY <group_by_list>
(6)     HAVING <having_condition>
(9)     ORDER BY <order_by_condition>
(10)    LIMIT <limit_number>

记忆口诀:从上连那组,有查问许仙
解释:从From上On连Join哪Where组GroupBy 有Having查Select唯 Distinct序OrderBy限Limit
不喜勿喷 ?