MySQL进阶必备知识(一):CS架构、配置文件、字符集等等

文章目录

      • 前文
      • MySQL的CS架构
          • MYSQL的连接过程
          • mysql的一些配置参数
      • MySQL的字符集和比较规则
        • MySQL字符集中的转换
      • 总结

前文

  一直想抽时间总结下学习的知识,趁此给大家介绍下MySQL的进阶知识,帮大伙儿梳理下关于MySQL那些零散的知识。如果关于MySQL你只知道mysql -uroot -proot登录,并且知道一些ddl、dml语句,而对以下的问题不怎么清楚,那这篇文章就值得一看

  • mysql服务端的启动方式?
  • mysql的字符集?
  • mysql的索引是B+树?具体是怎样的?
  • mysql的记录存放是怎么存放的?
  • mysql的基本存放单位是记录还是页?他们之间是什么关系?单链表or双链表?
      以上等等,如果你想了解就接着往下看吧!本篇文章是基于混曰子的MySQL 是怎样运行的:从根儿上理解 MySQL,这是本掘金的小册,因为我本人也买过很多极客时间的课程,可以说这本小册丝毫不逊色于极客时间里动则上百的课程,我本人看的是受益匪浅。在这里也是良心推介,有兴趣的朋友可以去购买阅读。本篇大多数内容是基于小册的概括总结。

MySQL的CS架构

  CS架构顾名思义就是client & server架构,在看小册之前,我对服务端的了解也非常少,因为一般只要启动一次,后续就不用再启动了,用的最多的还是mysql -uroot -proot客户端登录。但实际上mysql分为服务端和客户端,服务端仅一个,而客户端可以有多个,甚至每个shell都能算一个单独的客户端!而服务端也设置了默认的最大连接数,一般是151。并且服务端的启动也是比较简单的。
  我们知道,平常输的mysql仅是添加到$PATH路径下的绝对路径,在开启终端时由shell比如bash来读取这些路径,从而linux就能通过mysql这个指令找到对应的安装目录下mysql这个程序。
  ok,如果你忘了你的绝对路径,通过linux的which mysql可以查看:

$ which mysql
$ /usr/local/mysql/bin/mysql

  那我的mysql安装目录就是/usr/local/mysql,在其bin目录下除了mysql外,还有我们比较熟悉的mysqldump、mysqladmin、mysqlbinlog这些,另还有启动服务端的mysqld、mysqld_safe,所以接下来介绍三种启动方式:

  1. mysqld启动:/usr/local/mysql/bin/mysqld 即可启动
  2. mysqld_safe 启动(推介):这是启动脚本,在mysqld上再封装了一个监控程序,当mysqld挂了的时候,可以帮忙重启,直接调用启动即可
  3. mysql.server:这也是启动脚本,调用mysqld_safe启动,启动mysql.server start

  以上的启动还是比较简单的”裸启动“,也就是没指明以什么方式启动,比如socket?比如tcp/ip?,也没指定额外的配置文件,而是用默认路径下的配置文件,比如我们可以用–defaults-file来指定配置文件,有点类似于redis-server redis.conf的形式!
  ok,先简单介绍客户端和服务端的通信方式,这两者都运行起来就是linux上的进程了,所以二者的通信即是进程间的通信,在linux上一般就是用两种:tcpip和socket,关于这两者区别,我们可以参考mysql官网的一段话:

A MySQL client on Unix can connect to the mysqld server in two different ways: By using a Unix socket file to connect through a file in the file system (default /tmp/mysql.sock), or by using TCP/IP, which connects through a port number. A Unix socket file connection is faster than TCP/IP, but can be used only when connecting to a server on the same computer. A Unix socket file is used if you don’t specify a host name or if you specify the special host name loc -alhost.

  可以看到二者的区别就是文中我标粗的,socket连接速度更快于tcpip,但是它仅适用于客户端和服务端在同一台主机上,而tcpip则可以通过制定-h -P这样的ip端口形式实现跨主机的连接,所以平常用的最多的还是tcpip,但是socket了解一下也是非常有必要的。

MYSQL的连接过程

  mysql的连接过程可以说是非常重要的,明白了这个你就知道你发了一段sql语句,mysql怎么给你返回一个结果。那一般是三个步骤:

  • 建立连接:每个客户端与服务器连接,服务器都会安排一个线程,当客户端断开时,线程会复用;当连接失败,比如密码错误则拒绝连接
  • 解析与优化:sql语句到了服务端就会立马执行吗?不会,会先查询缓存,然后进行语法解析,最后查询优化,这一切的目的都是为了最快地返回结果。但缓存因维护成本过高,在mysql8.0就会被移除了。
  • 存储引擎:目前最通用的就是innodb和myisam了,区别就是:物理上如何表示记录,怎么从表中读取数据返回给客户端。
mysql的一些配置参数

  这里简单介绍下MYSQL的配置参数,比如之前说的–defaults-file指定对应的配置文件来启动,如果不指定,mysqld默认会在以下路径寻找:/etc/my.cnf、/etc/mysql/my.cnf、$MYSQL_HOME/my.cnf、~/my.cnf等等总共7个路径,而指定–defaults-file就可以跳过这些路径的寻找,直接匹配进入,另外通过–defaults-extra-file 指定额外的路径。
  除了配置文件就是配置参数了,常见的比如

  • –skip-networking可以禁止tcpip登录
  • –skip-grant-tables 跳过权限表即在忘了登录密码时可以这样启动服务器

  很多时候我们需要查看一些参数的配置,mysql提供了几个有用的语句,我们知道关于show语句,常见的就是show databases、show tables;那除了这两个,以下的这几个你也需要知道:
  • show variables:查看配置参数,我的mysql是453个,要查看具体的通过like来实现,比如show variables like “max_connections”/“query_cache_size”,前者表示查看最大连接数,后者表示查看缓存的大小。
  • show status:查看当前的运行状态,状态变量相对查看的比较少,因为这些都是系统运行时服务端产生的一些状态,无法修改,比如查看当前的连接数:show status like “Threads_connected”
  • show engines:查看当前版本都支持哪些引擎,以及默认的存储殷勤是哪个

  关于系统变量即show variables里面的参数设定,前面讲过mysql的CS架构,一个服务端对应多个客户端,就像HTTP一样,http里维护了session这样的一个会话参数来记录每个用户的状态,所以MySQL里相应的也有session这样的会话参数。MySQL服务端启动时默认以global variables启动的,每个客户端连接上去后匹配单独的线程,此时也匹配单独的session variables(初始等同于global),随后用户set variables设置这些配置参数时都是默认在session会话里,而如果想对所有的用户都生效,则要认为指定global,比如set global 变量名=值。

MySQL的字符集和比较规则

  字符集无论是哪门语言还是哪种数据库都是必备的,而讲起来相对篇幅也是比较大,这里就介绍最为重要的几点。我们知道,计算机是基于二进制来交互的,所以一般输入的字符就需要转换为字节,再转换为8个bit成为计算机可以识别的内容。那字符要转换为1个字节还是2个字节?要怎么转换?这之间的规则就是由人定的,比如:

  • ASCII:定义了128个数,1个字符对应1个字节,包含空格、标点符号、数字、大小写字母
  • latin1:在ASCII上扩充了128个西欧字符,也是1个字符对应1个字节
  • GBK:在ascii上扩充了中文、俄语等,ascii的对应1个字节,其他的2个字节
  • utf8:编码一个字符对应1-4个字节,和utf16、utf32都属于Unicode

  MySQL里utf8和utfmb4很多人还是分的不清楚,简单来讲,utf8即是utf8mb3的缩写,表示1-3个字节,utfmb4表示1-4个字节,这两者最大的区别是utf8mb4包含的内容要更多,比如一些emoji在utf8就无法显示,在utf8mb4就能显示!

  比较规则也是非常重要的内容,MySQL里经常需要排序,那这些排序针对字符串是怎么比较的呢?一般我们都是用其默认的,但有时我们要按照特定的规则排序,那我们就必须了解这块的内容,比如现在一般大小写是忽略的,那如果你想要区分大小写排序,就需要修改比较规则。
  查看字符集是show charset,就可以看到当前支持的字符集,以及默认的比较规则,扫过去可以看到default collation都是以ci结尾的,ci即case insensitive表示大小写不敏感,而如果要修改区分大小写,就改成cs(case sensitive)即可。
MySQL进阶必备知识(一):CS架构、配置文件、字符集等等_第1张图片
  关于比较规则可以通过show collation查看所有的比较规则,这边就不多说了。现在讲下比较规则和字符集的一一匹配关系,当仅修改字符集(charset)时,比如从utf8->gbk,则对应的collation会由MySQL帮忙修改,反之亦然!

MySQL字符集中的转换

  在使用MySQL的过程中,经常会出现编码错误,有时候在一台机器上是正常的,但是迁到另一台机器上又报编码错误,搞得很心烦!所以要解决这个问题,就必须了解MySQL字符集中的转换!
  首先我们需要了解三个参数:

  1. character_set_client —>服务端认为客户端的字符集
  2. character_set_connection—>连接的字符集
  3. character_set_results—>返回结果的字符集

  以上说明了这三个参数的作用,他们的关系是:当客户端请求服务端的时候,服务端认为客户端是以set_client所设置的编码发送的,但客户端默认是以操作系统发送的,所以当操作系统的和set_client的不同,就会报错!比如windows系统的默认是gbk,如果设置的是utf8,则报编码异常,因为我用的是mac,默认是utf8,所以是正确的。我们接着说,当客户端的内容成功被解码后,服务器还需要通过set_connection进行一次编码在内部操作,然后再对应的解码,最后用set_results编码返回给客户端!所以这三者把服务器的编码解码相对弄复杂了,但是如果你是类unix系统,就无须考虑太多,三个都设置成utf8即可!MySQL还贴心的给了一行代码一口气设置三个:

SET NAMES 字符集名; #比如set names utf8;

  除了以上的三个参数,实际上MySQL还提供了以下的参数,通过命令:

show variables like "character_set%";

MySQL进阶必备知识(一):CS架构、配置文件、字符集等等_第2张图片
  可以看到除了filesystem是binary,其他的都是utf8,这是因为都是我设置的,为了保持编码一致!所以如果出现编码错误了,可以查看下这些参数是否一致?亦或是是否和操作系统的一致!
  最后不得不说的是字符集和比较规则的粒度可以从列->数据表->数据库->服务器四个级别!这意味着我们可以一张表不同的列具有不同的字符集!可以说非常人性化了!感兴趣的可以自己了解下对应的SQL语句来设置。

总结

  考虑到篇幅原因,本篇就介绍到这里,下一篇会继续介绍记录格式、索引等等!好了,多谢观看~

你可能感兴趣的:(mysql)