1.MySQL环境

1.1.环境安装

  1. # 查看Linux服务器上是否安装过MySQL
  2. rpm -qa | grep -i mysql # 查询出所有mysql依赖包
  3. # 1、拉取镜像
  4. docker pull mysql:5.7
  5. # 2、创建实例并启动
  6. docker run -p 3306:3306 --name mysql \
  7. -v /root/mysql/log:/var/log/mysql \
  8. -v /root/mysql/data:/var/lib/mysql \
  9. -v /root/mysql/conf:/etc/mysql \
  10. -e MYSQL_ROOT_PASSWORD=root \
  11. -d mysql:5.7
  12. # 3、mysql配置 /root/mysql/conf/my.conf
  13. [client]
  14. #mysqlde utf8字符集默认为3位的,不支持emoji表情及部分不常见的汉字,故推荐使用utf8mb4
  15. default-character-set=utf8
  16. [mysql]
  17. default-character-set=utf8
  18. [mysqld]
  19. #设置client连接mysql时的字符集,防止乱码
  20. init_connect='SET collation_connection = utf8_general_ci'
  21. init_connect='SET NAMES utf8'
  22. #数据库默认字符集
  23. character-set-server=utf8
  24. #数据库字符集对应一些排序等规则,注意要和character-set-server对应
  25. collation-server=utf8_general_ci
  26. # 跳过mysql程序起动时的字符参数设置 ,使用服务器端字符集设置
  27. skip-character-set-client-handshake
  28. # 禁止MySQL对外部连接进行DNS解析,使用这一选项可以消除MySQL进行DNS解析的时间。
  29. # 但需要注意,如果开启该选项,则所有远程主机连接授权都要使用IP地址方式,
  30. # 否则MySQL将无法正常处理连接请求!
  31. skip-name-resolve
  32. # 4、重启mysql容器
  33. docker restart mysql
  34. # 5、进入到mysql容器
  35. docker exec -it mysql /bin/bash
  36. # 6、查看修改的配置文件
  37. cat /etc/mysql/my.conf

设置开机启动

  1. #没有chkconfig安装
  2. apt install sysv-rc-conf
  3. # 设置开机启动
  4. chkconfig mysql on
  5. # 查看启动级别
  6. chkconfig --list|grep mysql

1.2.安装位置

Docker容器就是一个小型的Linux环境,进入到MySQL容器中

  1. docker exec -it mysql /bin/bash

Linux环境下MySQL的安装目录

路径 解释
/var/lib/mysql MySQL数据库文件存放位置
/usr/share/mysql 错误消息和字符集文件配置
/usr/bin 客户端程序和脚本 mysqladmin mysqldump
/etc/init.d/mysql 启停脚本相关

1.3.修改字符集(略)

  1. # 1、进入到mysql数据库并查看字符集
  2. # show variables like 'character%';
  3. # show variables like '%char%';
  4. mysql> show variables like 'character%';
  5. +--------------------------+----------------------------+
  6. | Variable_name | Value |
  7. +--------------------------+----------------------------+
  8. | character_set_client | utf8 |
  9. | character_set_connection | utf8 |
  10. | character_set_database | utf8 |
  11. | character_set_filesystem | binary |
  12. | character_set_results | utf8 |
  13. | character_set_server | utf8 |
  14. | character_set_system | utf8 |
  15. | character_sets_dir | /usr/share/mysql/charsets/ |
  16. +--------------------------+----------------------------+
  17. 8 rows in set (0.00 sec)
  18. mysql> show variables like '%char%';
  19. +--------------------------+----------------------------+
  20. | Variable_name | Value |
  21. +--------------------------+----------------------------+
  22. | character_set_client | utf8 |
  23. | character_set_connection | utf8 |
  24. | character_set_database | utf8 |
  25. | character_set_filesystem | binary |
  26. | character_set_results | utf8 |
  27. | character_set_server | utf8 |
  28. | character_set_system | utf8 |
  29. | character_sets_dir | /usr/share/mysql/charsets/ |
  30. +--------------------------+----------------------------+
  31. 8 rows in set (0.01 sec)

打开 /etc/mysql/my.cnf 文件,里面有两行配置

  1. !includedir /etc/mysql/conf.d/
  2. !includedir /etc/mysql/mysql.conf.d/

/etc/mysql/mysql.conf.d/mysqld.cnf 添加

  1. [mysqld]
  2. character_set_server=utf8

/etc/mysql/conf.d/mysql.cnf 添加

  1. [mysql]
  2. default-character-set=utf8
  1. #作废
  2. [client]
  3. default-character-set=utf8
  4. [mysql]
  5. default-character-set=utf8
  6. character_set_client=utf8
  7. # 数据库默认字符集
  8. character_set_server=utf8
  9. #数据库字符集对应一些排序等规则,注意要和character-set-server对应
  10. collation-server=utf8_general_ci
  11. [mysqld]
  12. # 设置client连接mysql时的字符集,防止乱码
  13. init_connect='SET NAMES utf8'
  14. init_connect='SET collation_connection = utf8_general_ci'
  15. # 跳过mysql程序起动时的字符参数设置 ,使用服务器端字符集设置
  16. skip-character-set-client-handshake
  17. # 禁止MySQL对外部连接进行DNS解析,使用这一选项可以消除MySQL进行DNS解析的时间。但需要注意,如果开启该选项,则所有远程主机连接授权都要使用IP地址方式,否则MySQL将无法正常处理连接请求!
  18. skip-name-resolve

注意:安装**MySQL**完毕之后,第一件事就是修改字符集编码

1.4.配置文件

**MySQL**配置文件 https://www.cnblogs.com/gaoyuechen/p/10273102.html
1、二进制日志log-bin:主从复制

  1. # my,cnf
  2. # 开启mysql binlog功能
  3. log-bin=mysql-bin

2、错误日志log-error:默认是关闭的,记录严重的警告和错误信息,每次启动和关闭的详细信息等

  1. # my,cnf
  2. # 数据库错误日志文件
  3. log-error = error.log

3、查询日志log:默认关闭,记录查询的sql语句,如果开启会降低MySQL整体的性能,因为记录日志需要消耗系统资源

  1. # my,cnf
  2. # 慢查询sql日志设置
  3. slow_query_log = 1
  4. slow_query_log_file = slow.log

4、数据文件

  • frm文件:存放表结构
  • myd文件:存放表数据
  • myi文件:存放表索引

    1. # mysql5.7 使用.frm文件来存储表结构
    2. # 使用 .ibd文件来存储表索引和表数据
    3. -rw-r----- 1 mysql mysql 8988 Jun 25 09:31 pms_category.frm
    4. -rw-r----- 1 mysql mysql 245760 Jul 21 10:01 pms_category.ibd

    MySQL5.7Innodb存储引擎可将所有数据存放于ibdata*的共享表空间,也可将每张表存放于独立的.ibd文件的独立表空间。
    共享表空间以及独立表空间都是针对数据的存储方式而言的

  • 共享表空间:某一个数据库的所有的表数据,索引文件全部放在一个文件中,默认这个共享表空间的文件路径在data目录下。 默认的文件名为:ibdata1 初始化为10M

  • 独立表空间:每一个表都将会生成以独立的文件方式来进行存储,每一个表都有一个.frm表描述文件,还有一个.ibd文件。 其中这个文件包括了单独一个表的数据内容以及索引内容,默认情况下它的存储位置也是在表的位置之中。在配置文件my.cnf中设置: innodb_file_per_table

    2.MySQL逻辑架构

    MySQL高级 1 安装 架构 存储引擎 - 图1

  • **Connectors**指的是不同语言中与SQL的交互

  • **Connection Pool**管理缓冲用户连接,线程处理等需要缓存的需求。MySQL数据库的连接层
  • **Management Serveices & Utilities**系统管理和控制工具。备份、安全、复制、集群等等
  • **SQL Interface**接受用户的SQL命令,并且返回用户需要查询的结果
  • **Parser**SQL语句解析器
  • **Optimizer**查询优化器,SQL语句在查询之前会使用查询优化器对查询进行优化。就是优化客户端请求query,根据客户端请求的 query 语句,和数据库中的一些统计信息,在一系列算法的基础上进行分析,得出一个最优的策略,告诉后面的程序如何取得这个 query 语句的结果。For Exampleselect uid,name from user where gender = 1;这个select查询先根据where语句进行选取,而不是先将表全部查询出来以后再进行gender过滤;然后根据uidname进行属性投影,而不是将属性全部取出以后再进行过滤。最后将这两个查询条件联接起来生成最终查询结果
  • **Caches & Buffers**查询缓存

  • **Pluggable Storage Engines**存储引擎接口。MySQL区别于其他数据库的最重要的特点就是其插件式的表存储引擎(注意:存储引擎是基于表的,而不是数据库

  • **File System**数据落地到磁盘上,就是文件的存储

和其他数据库相比,MySQL有点与众不同,主要体现在存储引擎的架构上,插件式的存储引擎架构将查询处理和其他的系统任务以及数据的存储提取相分离。这种架构可以根据业务的需求和实际需求选择合适的存储引擎
逻辑架构分层
MySQL高级 1 安装 架构 存储引擎 - 图2

  • 连接层:最上层是一些客户端和连接服务,包含本地sock通信和大多数基于客户端/服务端工具实现的类似于tcp/ip的通信。主要完成一些类似于连接处理、授权认证、及相关的安全方案。在该层上引入了线程池的概念,为通过认证安全接入的客户端提供线程。同样在该层上可以实现基于SSL的安全链接。服务器也会为安全接入的每个客户端验证它所具有的操作权限
  • 服务层MySQL的核心服务功能层,是MySQL的核心,包括查询缓存,解析器,解析树,预处理器,查询优化器。主要进行查询解析、分析、查询缓存、内置函数、存储过程、触发器、视图等,select操作会先检查是否命中查询缓存,命中则直接返回缓存数据,否则解析查询并创建对应的解析树
  • 引擎层:存储引擎层,存储引擎真正的负责了MySQL中数据的存储和提取,服务器通过API与存储引擎进行通信。不同的存储引擎具有的功能不同,可以根据自己的实际需要进行选取
  • 存储层:数据存储层,主要是将数据存储在运行于裸设备的文件系统之上,并完成与存储引擎的交互

    3.存储引擎

    **show engines;** 命令查看MySQL5.7支持的存储引擎
    1. mysql> show engines;
    MySQL高级 1 安装 架构 存储引擎 - 图3
    **show variables like 'default_storage_engine%';** 查看当前数据库正在使用的存储引擎
    1. mysql> show variables like 'default_storage_engine%';
    2. +------------------------+--------+
    3. | Variable_name | Value |
    4. +------------------------+--------+
    5. | default_storage_engine | InnoDB |
    6. +------------------------+--------+
    7. 1 row in set (0.01 sec)

InnoDB和MyISAM对比

对比项 MyISAM InnoDB
外键 不支持 支持
事务 不支持 支持
行表锁 表锁,即使操作一条记录也会锁住整张表,不适合高并发操作 行锁,操作时只锁某一行,不对其他行有影响,适合高并发操作
缓存 只缓存索引,不缓存真实数据 不仅缓存索引还要缓存真实数据,対内存要求较高,而且内存大小対性能有决定性影响
表空间
关注点 性能 事务
默认安装 Y Y

4.SQL性能下降的原因

  • 查询语句写的差
  • 索引失效:索引建了,但是没有用上
  • 关联 查询太多join(设计缺陷或者不得已的需求)
  • 服务器调优以及各个参数的设置(缓冲、线程数等)

    5.SQL执行顺序

    1. select # 7
    2. from # 1
    3. join # 3
    4. on # 2
    5. where # 4
    6. group by # 5
    7. having # 6
    8. distinct # 8
    9. order by # 9
    10. limit # 10

    6.七种JOIN理论

    MySQL高级 1 安装 架构 存储引擎 - 图4 ```sql / 1 / SELECT FROM TableA A LEFT JOIN TableB B ON A.Key = B.Key;

/ 2 / SELECT FROM TableA A RIGHT JOIN TableB B ON A.Key = B.Key;

/ 3 / SELECT FROM TableA A INNER JOIN TableB B ON A.Key = B.Key;

/ 4 / SELECT FROM TableA A LEFT JOIN TableB B ON A.Key = B.Key WHERE B.Key IS NULL;

/ 5 / SELECT FROM TableA A RIGHT JOIN TableB B ON A.Key = B.Key WHERE A.Key IS NULL;

/ 6 / — SELECT FROM TableA A FULL OUTER JOIN TableB B ON A.Key = B.Key; / MySQL不支持FULL OUTER JOIN这种语法 可以改成 1+2 / SELECT FROM TableA A LEFT JOIN TableB B ON A.Key = B.Key UNION SELECT FROM TableA A RIGHT JOIN TableB B ON A.Key = B.Key;

/ 7 / — SELECT FROM TableA A FULL OUTER JOIN TableB B ON A.Key = B.Key — WHERE A.Key IS NULL OR B.Key IS NULL; / MySQL不支持FULL OUTER JOIN这种语法 可以改成 4+5 / SELECT FROM TableA A LEFT JOIN TableB B ON A.Key = B.Key WHERE B.Key IS NULL; UNION SELECT FROM TableA A RIGHT JOIN TableB B ON A.Key = B.Key WHERE A.Key IS NULL; ```