社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
一直想抽时间总结下学习的知识,趁此给大家介绍下MySQL的进阶知识,帮大伙儿梳理下关于MySQL那些零散的知识。如果关于MySQL你只知道mysql -uroot -proot登录,并且知道一些ddl、dml语句,而对以下的问题不怎么清楚,那这篇文章就值得一看
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,所以接下来介绍三种启动方式:
以上的启动还是比较简单的”裸启动“,也就是没指明以什么方式启动,比如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的连接过程可以说是非常重要的,明白了这个你就知道你发了一段sql语句,mysql怎么给你返回一个结果。那一般是三个步骤:
这里简单介绍下MYSQL的配置参数,比如之前说的–defaults-file指定对应的配置文件来启动,如果不指定,mysqld默认会在以下路径寻找:/etc/my.cnf、/etc/mysql/my.cnf、$MYSQL_HOME/my.cnf、~/my.cnf等等总共7个路径,而指定–defaults-file就可以跳过这些路径的寻找,直接匹配进入,另外通过–defaults-extra-file 指定额外的路径。
除了配置文件就是配置参数了,常见的比如
关于系统变量即show variables里面的参数设定,前面讲过mysql的CS架构,一个服务端对应多个客户端,就像HTTP一样,http里维护了session这样的一个会话参数来记录每个用户的状态,所以MySQL里相应的也有session这样的会话参数。MySQL服务端启动时默认以global variables启动的,每个客户端连接上去后匹配单独的线程,此时也匹配单独的session variables(初始等同于global),随后用户set variables设置这些配置参数时都是默认在session会话里,而如果想对所有的用户都生效,则要认为指定global,比如set global 变量名=值。
字符集无论是哪门语言还是哪种数据库都是必备的,而讲起来相对篇幅也是比较大,这里就介绍最为重要的几点。我们知道,计算机是基于二进制来交互的,所以一般输入的字符就需要转换为字节,再转换为8个bit成为计算机可以识别的内容。那字符要转换为1个字节还是2个字节?要怎么转换?这之间的规则就是由人定的,比如:
比较规则也是非常重要的内容,MySQL里经常需要排序,那这些排序针对字符串是怎么比较的呢?一般我们都是用其默认的,但有时我们要按照特定的规则排序,那我们就必须了解这块的内容,比如现在一般大小写是忽略的,那如果你想要区分大小写排序,就需要修改比较规则。
查看字符集是show charset,就可以看到当前支持的字符集,以及默认的比较规则,扫过去可以看到default collation都是以ci结尾的,ci即case insensitive表示大小写不敏感,而如果要修改区分大小写,就改成cs(case sensitive)即可。
关于比较规则可以通过show collation查看所有的比较规则,这边就不多说了。现在讲下比较规则和字符集的一一匹配关系,当仅修改字符集(charset)时,比如从utf8->gbk,则对应的collation会由MySQL帮忙修改,反之亦然!
在使用MySQL的过程中,经常会出现编码错误,有时候在一台机器上是正常的,但是迁到另一台机器上又报编码错误,搞得很心烦!所以要解决这个问题,就必须了解MySQL字符集中的转换!
首先我们需要了解三个参数:
以上说明了这三个参数的作用,他们的关系是:当客户端请求服务端的时候,服务端认为客户端是以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%";
可以看到除了filesystem是binary,其他的都是utf8,这是因为都是我设置的,为了保持编码一致!所以如果出现编码错误了,可以查看下这些参数是否一致?亦或是是否和操作系统的一致!
最后不得不说的是字符集和比较规则的粒度可以从列->数据表->数据库->服务器四个级别!这意味着我们可以一张表不同的列具有不同的字符集!可以说非常人性化了!感兴趣的可以自己了解下对应的SQL语句来设置。
考虑到篇幅原因,本篇就介绍到这里,下一篇会继续介绍记录格式、索引等等!好了,多谢观看~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!