Capítulo 1: Cognición de MySQL

Arquitectura cliente/servidor MySQL

Tomando el WeChat que solemos usar como ejemplo, en realidad se compone de dos partes, una es el programa cliente y la otra es el programa servidor. Puede haber muchas formas de clientes, como aplicación móvil, software de computadora o versión web de WeChat, cada cliente tiene un nombre de usuario único, que es su ID de WeChat, por otro lado, Tencent opera en su sala de computadoras con un software de servidor , generalmente usamos el cliente para tratar con este servidor cuando operamos WeChat. Por ejemplo, el proceso en el que Brother Gou envía un mensaje a Master Cat en WeChat es así:

  1. El cliente empaqueta el mensaje, se agrega la información del remitente y el destinatario, y luego se envía desde el cliente de WeChat de Gouge al servidor de WeChat;

  1. El servidor de WeChat obtiene su remitente y receptor del mensaje y envía el mensaje al cliente de WeChat del Maestro Mao de acuerdo con la información del receptor del mensaje, y el cliente de WeChat del Maestro Mao muestra que el hermano Gou le envió un mensaje.

  El proceso de usar MySQL es el mismo que este. Su programa de servidor trata directamente con los datos que almacenamos , y luego muchos programas de cliente pueden conectarse a este programa de servidor, enviar solicitudes para agregar, eliminar, modificar y verificar, y luego el servidor responde a estas solicitudes, manipulando así los datos que mantiene. Al igual que WeChat,cada cliente de MySQL debe proporcionar un nombre de usuario y una contraseña para iniciar sesión, y solo después de iniciar sesión puede enviar una solicitud al servidor para operar con ciertos datos. Nuestro uso diario de MySQL es generalmente así:

  1. Inicie el programa del servidor MySQL .

  1. Inicie el programa cliente MySQL y conéctese al programa servidor.

  1. Ingrese algunas declaraciones de comando en el programa del cliente como solicitudes y envíelas al programa del servidor. Después de recibir estas solicitudes, el programa del servidor operará datos específicos de acuerdo con el contenido de la solicitud y devolverá los resultados de la operación al cliente.

  Sabemos que las computadoras son muy poderosas. Se pueden ejecutar varios programas en una computadora al mismo tiempo, como WeChat, QQ , reproductor de música, editor de texto, etc. Cada programa en ejecución también se denomina proceso. Tanto nuestro programa servidor MySQL como el programa cliente son esencialmente un proceso en la computadora.Este proceso que representa el programa servidor MySQL también se denomina instancia de base de datos MySQL , o instancia de base de datos para abreviar.

  Cada proceso tiene un número único, llamado ID de proceso , y el nombre en inglés es PID . Este número es asignado aleatoriamente por el sistema operativo cuando iniciamos el programa. El sistema operativo se asegurará de que el proceso en la misma máquina en un número de tiempo determinado no se repite. Por ejemplo, si abre el programa QQ en la computadora , el sistema operativo le asignará un número de proceso único, si cierra el programa, el sistema operativo reciclará el número de proceso, que puede reasignarse a otros procesos más adelante. Cuando comencemos el programa QQ la próxima vez, se puede asignar otro número. Cada proceso tiene un nombre, que está definido por la persona que escribió el programa. Por ejemplo, el nombre predeterminado del proceso del servidor MySQL que iniciamos es mysqld , y el nombre predeterminado de nuestro proceso de cliente MySQL comúnmente utilizado es mysql .

Instalación de mysql

Independientemente de si descargamos el código fuente para compilar e instalar nosotros mismos, o si usamos directamente el paquete de instalación oficial para instalar, el programa del servidor MySQL y el programa del cliente se instalarán en nuestra máquina. No importa cuál de los dos métodos de instalación anteriores se utilice, debe recordar (es importante decirlo tres veces) dónde instaló MySQL . En otras palabras, debe recordar el directorio de instalación de MySQL .

小贴士:`MySQL`的大部分安装包都包含了服务器程序和客户端程序,不过在Linux下使用RPM包时会有单独的服务器RPM包和客户端RPM包,需要分别安装。

  Además, MySQL puede ejecutarse en una variedad de sistemas operativos. Discutiremos algunas diferencias entre los sistemas operativos similares a UNIX y los sistemas operativos Windows más adelante. Para facilitar la comprensión de todos, he instalado MySQL tanto en el sistema operativo macOS (el sistema operativo que utilizan los ordenadores de Apple) como en el sistema operativo Windows , sus directorios de instalación son:

  • Directorio de instalación en el sistema operativo macOS :

/usr/local/mysql/
  • Directorio de instalación en el sistema operativo Windows :

C:\Program Files\MySQL\MySQL Server 5.7

  A continuación, tomaré estos dos directorios de instalación como ejemplo para extraer más conceptos, pero debe tenerse en cuenta que estos dos directorios de instalación son los directorios de instalación en mis máquinas que ejecutan diferentes sistemas operativos.Asegúrese de recordar poner lo siguiente Dónde el directorio de instalación se usa en el ejemplo, reemplácelo con el directorio de instalación en su propia máquina.

小贴士:类UNIX操作系统非常多,比如FreeBSD、Linux、macOS、Solaris等都属于UNIX操作系统的范畴,我们这里使用macOS操作系统代表类UNIX操作系统来运行MySQL。

Archivos ejecutables en el directorio bin

Hay un directorio bin particularmente importante  en el directorio de instalación de MySQL . Muchos archivos ejecutables se almacenan en este directorio. Tomando el sistema macOS como ejemplo, la ruta absoluta de este directorio bin es (en mi máquina):

/usr/local/mysql/bin

  Hagamos una lista de algunos archivos ejecutables en este directorio bin en macOS para ver (hay demasiados archivos, todos ellos actualizarán la pantalla):

.
├── mysql
├── mysql.server -> ../support-files/mysql.server
├── mysqladmin
├── mysqlbinlog
├── mysqlcheck
├── mysqld
├── mysqld_multi
├── mysqld_safe
├── mysqldump
├── mysqlimport
├── mysqlpump
... (省略其他文件)
0 directories, 40 files

  Los archivos ejecutables en Windows son similares a los de macOS , pero todos tienen una extensión .exe. Estos archivos ejecutables están relacionados con el programa servidor y el programa cliente. Más adelante presentaremos en detalle algunos archivos ejecutables más importantes. Ahora echemos un vistazo a la forma de ejecutar estos archivos.

  Para un sistema operativo con una interfaz visual, podemos ejecutar un archivo ejecutable con un clic del mouse, pero ahora prestamos más atención a cómo ejecutar estos archivos ejecutables en el entorno de línea de comandos.Frame, aquí se refiere a Shell en UNIX- como systems o cmd.exe en sistemas Windows . Si aún no sabe cómo iniciar estas herramientas de línea de comandos, busque en línea ~ Tomemos el sistema macOS como ejemplo para ver cómo iniciar estos archivos ejecutables ( la operación en Windows es similar, solo siga las instrucciones)

  • Usar la ruta relativa/absoluta del archivo ejecutable
      Supongamos que el directorio de trabajo actual en el que nos encontramos es el directorio de instalación de MySQL , es decir, /usr/local/mysql Queremos iniciar el archivo ejecutable mysqld en el directorio bin , y podemos usar la ruta relativa para iniciar:

./bin/mysqld

  O ingrese directamente la ruta absoluta de mysqld :

/usr/local/mysql/bin/mysqld
  • Agregue la ruta del directorio bin a la variable de entorno PATH.Si
      consideramos que es problemático ingresar una cadena larga de nombres de ruta cada vez que ejecutamos un archivo, podemos agregar la ruta del directorio bin a la variable de entorno PATH . La variable de entorno PATH es una colección de una serie de rutas, cada ruta está separada por dos puntos: por ejemplo, el valor de la variable de entorno PATH en mi máquina es:

/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

El valor de la variable de entorno PATH   en mi sistema muestra que cuando ingreso un comando, el sistema estará en /usr/local/bin , /usr/bin:, / bin:, / usr/sbin , /sbin estos directorios Siguiente , verifique si el comando que ingresamos existe a su vez y, si la búsqueda es exitosa, ejecute el archivo ejecutable correspondiente en el directorio. Entonces podemos modificar esta variable de entorno PATH ahora y agregar la ruta del directorio bin en el directorio de instalación de MySQL a PATH El valor de la variable de entorno modificada PATH en mi máquina es:

/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/mysql/bin

  Así que ahora no importa en qué directorio de trabajo nos encontremos, podemos ingresar directamente el nombre del archivo ejecutable para iniciarlo, por ejemplo:

mysqld

  mucho más conveniente ~

小贴士:关于什么是环境变量以及如何在当前系统中添加或修改系统变量不是我们介绍的范围,大家找本相关的书或者上网查一查~

Inicie el programa del servidor MySQL

Inicie el programa del servidor en UNIX

Hay muchos archivos ejecutables que se utilizan para iniciar el programa del servidor MySQL en sistemas   similares a UNIX , la mayoría de los cuales están en el directorio bin del directorio de instalación de MySQL , echemos un vistazo.

mysqld

  El archivo ejecutable mysqld representa el programa del servidor MySQL , y ejecutar este archivo ejecutable puede iniciar directamente un proceso del servidor. Pero este comando no se usa comúnmente, sigamos viendo los comandos de inicio más impresionantes.

mysqld_safe

  mysqld_safe es un script de inicio que llama indirectamente a mysqld y, por cierto, también inicia otro proceso de monitoreo.Este proceso de monitoreo puede ayudar a reiniciar el proceso del servidor cuando se bloquea. Además, al usar mysqld_safe para iniciar el programa del servidor, redirigirá la información del error y otra información de diagnóstico del programa del servidor a un archivo y generará un registro de errores, lo que puede ayudarnos a encontrar la causa del error.

mysql.servidor

  mysql.server también es un script de inicio, llamará a mysqld_safe indirectamenteel programa del servidor se puede iniciar especificando el parámetro de inicio más adelante cuandollame a mysql.server , así:

mysql.server start

  Cabe señalar que este archivo mysql.server es en realidad un archivo de enlace, y su archivo real es ../support-files/mysql.server . El sistema operativo macOS que uso creará automáticamente un archivo de enlace que apunta al archivo real en el directorio bin. Si su sistema operativo no crea automáticamente este archivo de enlace para usted, cree uno usted mismo ~ No me diga que no puede crear un archivo de enlace, buscar en línea ~

  Además, también podemos usar el comando mysql.server para cerrar el programa del servidor en ejecución, simplemente cambie el parámetro de inicio para detener :

mysql.server stop

mysqld_multi

  De hecho, también podemos ejecutar múltiples instancias de servidor en una computadora, es decir, ejecutar múltiples procesos de servidor MySQL . El ejecutable mysql_multi puede monitorear el inicio o la detención de cada proceso del servidor. El uso de este comando es relativamente complicado.Este libro es principalmente para explicar el proceso de ejecución del servidor y cliente MySQL , y no introducirá demasiado sobre cómo iniciar múltiples programas de servidor.

Inicie el programa del servidor en Windows

  No hay tantos scripts de inicio en Windows como en los sistemas similares a UNIX , pero también proporciona dos formas de iniciar manualmente y comenzar como un servicio. Echemos un vistazo en detalle a continuación.

mysqld

  De manera similar, hay un archivo ejecutable mysqld en el directorio bin del directorio de instalación de MySQL , ingrese mysqld en la línea de comando o haga doble clic directamente para ejecutarlo e iniciar el programa del servidor MySQL .

Ejecute el programa del servidor como un servicio

  Primer vistazo a lo que es un servicio de Windows ? Si no importa quién esté usando esta computadora, necesitamos ejecutar un determinado programa durante mucho tiempo y debemos iniciarlo cuando se inicia la computadora, generalmente lo registraremos como un servicio de Windows y el sistema operativo nos ayudará a administrarlo . eso La forma de registrar un programa como servicio de Windows es bastante sencilla, así:

"完整的可执行文件路径" --install [-manual] [服务名]

  Entre ellos , se puede omitir -manual Si se agrega, significa que el servicio no se iniciará automáticamente cuando se inicie el sistema Windows , de lo contrario, se iniciará automáticamente. El nombre del servicio también se puede omitir y el nombre del servicio predeterminado es MySQL . Por ejemplo, la ruta completa a mysqld en mi computadora con Windows es:

C:\Program Files\MySQL\MySQL Server 5.7\bin\mysqld

  Entonces, si queremos registrarlo como un servicio, podemos escribir esto en la línea de comando:

"C:\Program Files\MySQL\MySQL Server 5.7\bin\mysqld" --install

  Después de registrar mysqld como un servicio de Windows , podemos iniciar el programa del servidor MySQL con el siguiente comando:

net start MySQL

  Por supuesto, si le gusta una interfaz gráfica, puede usar el administrador de servicios de Windows para iniciar y detener el servicio haciendo clic con el mouse (como programador, usemos un marco negro ~).

Cerrar este servicio también es muy simple, simplemente reemplace el comienzo   anterior con detener , así:

net stop MySQL

Inicie el programa cliente MySQL

  Después de iniciar con éxito el programa del servidor MySQL, podemos iniciar el programa cliente para conectarnos al servidor. Hay muchos programas cliente en el directorio bin , como mysqladmin , mysqldump , mysqlcheck, etc. (hay muchos, así que gané no enumerarlos uno por uno arriba). Aquí nos enfocamos en el archivo ejecutable mysql , que nos permite interactuar con el proceso del programa del servidor, es decir, enviar solicitudes y recibir los resultados del procesamiento del servidor. Generalmente se requieren algunos parámetros al iniciar este archivo ejecutable, el formato es el siguiente:

mysql -h主机名  -u用户名 -p密码

  El significado de cada parámetro es el siguiente:

nombre del parámetro

significado

-h

Indica el nombre de dominio o la dirección IP de la computadora donde se encuentra el proceso del servidor.Si el proceso del servidor se está ejecutando en la máquina local, este parámetro se puede omitir, o se puede completar localhost o 127.0.0.1. También se puede escribir en la forma --host=nombre de host.

-tu

Indica el nombre de usuario. También se puede escribir en la forma --user=nombre de usuario.

-pag

Indica la contraseña. También se puede escribir en la forma --password=contraseña.

小贴士:像 h、u、p 这样名称只有一个英文字母的参数称为短形式的参数,使用时前面需要加单短划线,像 host、user、password 这样大于一个英文字母的参数称为长形式的参数,使用时前面需要加双短划线。后边会详细讨论这些参数的使用方式的,稍安勿躁~

  Por ejemplo, si ejecuto el siguiente archivo ejecutable (complete el nombre de usuario y la contraseña de acuerdo con su situación real), puede iniciar el cliente MySQL y conectarse al servidor.

mysql -hlocalhost -uroot -p123456

  Echemos un vistazo a la interfaz después de que la conexión sea exitosa:

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>   en la última línea es un aviso del cliente, después de lo cual los comandos enviados por el cliente al servidor deben escribirse después de este aviso.

  Si queremos desconectar el cliente del servidor y cerrar el cliente, podemos ingresar cualquiera de los siguientes comandos en el indicador mysql> :

1. `quit`
2. `exit`
3. `\q`

  Por ejemplo, intentemos ingresar quit :

mysql> quit
Bye

  输出了Bye说明客户端程序已经关掉了。值得注意的是,这是关闭客户端程序的方式,不是关闭服务器程序的方式,怎么关闭服务器程序上一节里介绍过了。

  如果你愿意,你可以多打开几个黑框框,每个黑框框都使用mysql -hlocahhost -uroot -p123456来运行多个客户端程序,每个客户端程序都是互不影响的。如果你有多个电脑,也可以试试把它们用局域网连起来,在一个电脑上启动MySQL服务器程序,在另一个电脑上执行mysql命令时使用IP地址作为主机名来连接到服务器。

连接注意事项

  • 最好不要在一行命令中输入密码。

  我们直接在黑框框里输入密码很可能被别人看到,这和你当着别人的面输入银行卡密码没什么区别,所以我们在执行mysql连接服务器的时候可以不显式的写出密码,就像这样:

mysql -hlocahhost -uroot -p

  点击回车之后才会提示你输入密码:

Enter password:

  不过这回你输入的密码不会被显示出来,心怀不轨的人也就看不到了,输入完成点击回车就成功连接到了服务器。

  • 如果你非要在一行命令中显式的把密码输出来,那-p和密码值之间不能有空白字符(其他参数名之间可以有空白字符),就像这样:

mysql -h localhost -u root -p123456

如果加上了空白字符就是错误的,比如这样:

mysql -h localhost -u root -p 123456
  • mysql的各个参数的摆放顺序没有硬性规定,也就是说你也可以这么写:

mysql -p  -u root -h localhost
  • 如果你的服务器和客户端安装在同一台机器上,-h参数可以省略,就像这样:

mysql -u root -p  
  • 如果你使用的是类UNIX系统,并且省略-u参数后,会把你登陆操作系统的用户名当作MySQL的用户名去处理。

  比方说我用登录操作系统的用户名是xiaohaizi,那么在我的机器上下面这两条命令是等价的:

mysql -u xiaohaizi -p
mysql -p

  对于Windows系统来说,默认的用户名是ODBC,你可以通过设置环境变量USER来添加一个默认用户名。

客户端与服务器连接的过程

  我们现在已经知道如何启动MySQL的服务器程序,以及如何启动客户端程序来连接到这个服务器程序。运行着的服务器程序和客户端程序本质上都是计算机上的一个进程,所以客户端进程向服务器进程发送请求并得到回复的过程本质上是一个进程间通信的过程!MySQL支持下面三种客户端进程和服务器进程的通信方式。

TCP/IP

  真实环境中,数据库服务器进程和客户端进程可能运行在不同的主机中,它们之间必须通过网络来进行通讯。MySQL采用TCP作为服务器和客户端之间的网络通信协议。在网络环境下,每台计算机都有一个唯一的IP地址,如果某个进程有需要采用TCP协议进行网络通信方面的需求,可以向操作系统申请一个端口号,这是一个整数值,它的取值范围是0~65535。这样在网络中的其他进程就可以通过IP地址 + 端口号的方式来与这个进程连接,这样进程之间就可以通过网络进行通信了。

  MySQL服务器启动的时候会默认申请3306端口号,之后就在这个端口号上等待客户端进程进行连接,用书面一点的话来说,MySQL服务器会默认监听3306端口。

小贴士:TCP/IP 网络体系结构是现在通用的一种网络体系结构,其中的 TCP 和 IP 是体系结构中两个非常重要的网络协议,如果你并不知道协议是什么,或者并不知道网络是什么,那恐怕兄弟你来错地方了,找本计算机网络的书去看看吧!

  如果3306端口号已经被别的进程占用了或者我们单纯的想自定义该数据库实例监听的端口号,那可以在启动服务器程序的命令行里添加-P参数来明确指定一下端口号,比如这样:

mysqld -P3307

  这样MySQL服务器在启动时就会去监听我们指定的端口号3307

  如果客户端进程想要使用TCP/IP网络来连接到服务器进程,比如我们在使用mysql来启动客户端程序时,在-h参数后必须跟随IP地址来作为需要连接的服务器进程所在主机的主机名,如果客户端进程和服务器进程在一台计算机中的话,我们可以使用127.0.0.1来代表本机的IP地址。另外,如果服务器进程监听的端口号不是默认的3306,我们也可以在使用mysql启动客户端程序时使用-P参数(大写的P,小写的p是用来指定密码的)来指定需要连接到的端口号。比如我们现在已经在本机启动了服务器进程,监听的端口号为3307,那我们启动客户端程序时可以这样写:

mysql -h127.0.0.1 -uroot -P3307 -p

  不知大家发现了没有,我们在启动服务器程序的命令mysqld和启动客户端程序的命令mysql后边都可以使用-P参数,关于如何在命令后边指定参数,指定哪些参数我们稍后会详细介绍的,稍微等等~

命名管道和共享内存

  如果你是一个Windows用户,那么客户端进程和服务器进程之间可以考虑使用命名管道或共享内存进行通信。不过启用这些通信方式的时候需要在启动服务器程序和客户端程序时添加一些参数:

  • 使用命名管道来进行进程间通信
      需要在启动服务器程序的命令中加上--enable-named-pipe参数,然后在启动客户端程序的命令中加入--pipe或者--protocol=pipe参数。

  • 使用共享内存来进行进程间通信
      需要在启动服务器程序的命令中加上--shared-memory参数,在成功启动服务器后,共享内存便成为本地客户端程序的默认连接方式,不过我们也可以在启动客户端程序的命令中加入--protocol=memory参数来显式的指定使用共享内存进行通信。

  不过需要注意的是,使用共享内存的方式进行通信的服务器进程和客户端进程必须在同一台Windows主机中。

小贴士:命名管道和共享内存是Windows操作系统中的两种进程间通信方式,如果你没听过的话也不用纠结,并不妨碍我们介绍MySQL的知识~

Unix域套接字文件

  如果我们的服务器进程和客户端进程都运行在同一台操作系统为类Unix的机器上的话,我们可以使用Unix域套接字文件来进行进程间通信。如果我们在启动客户端程序的时候指定的主机名为localhost,或者指定了--protocol=socket的启动参数,那服务器程序和客户端程序之间就可以通过Unix域套接字文件来进行通信了。MySQL服务器程序默认监听的Unix域套接字文件路径为/tmp/mysql.sock,客户端程序也默认连接到这个Unix域套接字文件。如果我们想改变这个默认路径,可以在启动服务器程序时指定socket参数,就像这样:

mysqld --socket=/tmp/a.txt

  这样服务器启动后便会监听/tmp/a.txt。在服务器改变了默认的UNIX域套接字文件后,如果客户端程序想通过UNIX域套接字文件进行通信的话,也需要显式的指定连接到的UNIX域套接字文件路径,就像这样:

mysql -hlocalhost -uroot --socket=/tmp/a.txt -p

  这样该客户端进程和服务器进程就可以通过路径为/tmp/a.txtUnix域套接字文件进行通信了。

服务器处理客户端请求

  其实不论客户端进程和服务器进程是采用哪种方式进行通信,最后实现的效果都是:客户端进程向服务器进程发送一段文本(MySQL语句),服务器进程处理后再向客户端进程发送一段文本(处理结果)。那服务器进程对客户端进程发送的请求做了什么处理,才能产生最后的处理结果呢?客户端可以向服务器发送增删改查各类请求,我们这里以比较复杂的查询请求为例来画个图展示一下大致的过程:

  从图中我们可以看出,服务器程序处理来自客户端的查询请求大致需要经过三个部分,分别是连接管理、解析与优化、存储引擎。下面我们来详细看一下这三个部分都干了什么。

连接管理

  客户端进程可以采用我们上面介绍的TCP/IP、命名管道或共享内存、Unix域套接字这几种方式之一来与服务器进程建立连接,每当有一个客户端进程连接到服务器进程时,服务器进程都会创建一个线程来专门处理与这个客户端的交互,当该客户端退出时会与服务器断开连接,服务器并不会立即把与该客户端交互的线程销毁掉,而是把它缓存起来,在另一个新的客户端再进行连接时,把这个缓存的线程分配给该新客户端。这样就起到了不频繁创建和销毁线程的效果,从而节省开销。从这一点大家也能看出,MySQL服务器会为每一个连接进来的客户端分配一个线程,但是线程分配的太多了会严重影响系统性能,所以我们也需要限制一下可以同时连接到服务器的客户端数量,至于怎么限制我们后边再说~

  在客户端程序发起连接的时候,需要携带主机信息、用户名、密码,服务器程序会对客户端程序提供的这些信息进行认证,如果认证失败,服务器程序会拒绝连接。另外,如果客户端程序和服务器程序不运行在一台计算机上,我们还可以采用使用了SSL(安全套接字)的网络连接进行通信,来保证数据传输的安全性。

  当连接建立后,与该客户端关联的服务器线程会一直等待客户端发送过来的请求,MySQL服务器接收到的请求只是一个文本消息,该文本消息还要经过各种处理,预知后事如何,继续往下看~

解析与优化

  到现在为止,MySQL服务器已经获得了文本形式的请求,接着还要经过九九八十一难的处理,其中的几个比较重要的部分分别是查询缓存、语法解析和查询优化,下面我们详细来看。

查询缓存

  如果我问你9+8×16-3×2×17的值是多少,你可能会用计算器去算一下,或者牛逼一点用心算,最终得到了结果35,如果我再问你一遍9+8×16-3×2×17的值是多少,你还会再傻呵呵的算一遍么?我们刚刚已经算过了,直接说答案就好了。MySQL服务器程序处理查询请求的过程也是这样,会把刚刚处理过的查询请求和结果缓存起来,如果下一次有一模一样的请求过来,直接从缓存中查找结果就好了,就不用再傻呵呵的去底层的表中查找了。这个查询缓存可以在不同客户端之间共享,也就是说如果客户端A刚刚查询了一个语句,而客户端B之后发送了同样的查询请求,那么客户端B的这次查询就可以直接使用查询缓存中的数据。

  当然,MySQL服务器并没有人聪明,如果两个查询请求在任何字符上的不同(例如:空格、注释、大小写),都会导致缓存不会命中。另外,如果查询请求中包含某些系统函数、用户自定义变量和函数、一些系统表,如 mysqlinformation_schemaperformance_schema 数据库中的表,那这个请求就不会被缓存。以某些系统函数举例,可能同样的函数的两次调用会产生不一样的结果,比如函数NOW,每次调用都会产生最新的当前时间,如果在一个查询请求中调用了这个函数,那即使查询请求的文本信息都一样,那不同时间的两次查询也应该得到不同的结果,如果在第一次查询时就缓存了,那第二次查询的时候直接使用第一次查询的结果就是错误的!

  不过既然是缓存,那就有它缓存失效的时候。MySQL的缓存系统会监测涉及到的每张表,只要该表的结构或者数据被修改,如对该表使用了INSERTUPDATEDELETETRUNCATE TABLEALTER TABLEDROP TABLEDROP DATABASE语句,那使用该表的所有高速缓存查询都将变为无效并从高速缓存中删除!

小贴士:虽然查询缓存有时可以提升系统性能,但也不得不因维护这块缓存而造成一些开销,比如每次都要去查询缓存中检索,查询请求处理完需要更新查询缓存,维护该查询缓存对应的内存区域。从MySQL 5.7.20开始,不推荐使用查询缓存,并在MySQL 8.0中删除。

语法解析

  如果查询缓存没有命中,接下来就需要进入正式的查询阶段了。因为客户端程序发送过来的请求只是一段文本而已,所以MySQL服务器程序首先要对这段文本做分析,判断请求的语法是否正确,然后从文本中将要查询的表、各种查询条件都提取出来放到MySQL服务器内部使用的一些数据结构上来。

小贴士:这个从指定的文本中提取出我们需要的信息本质上算是一个编译过程,涉及词法解析、语法分析、语义分析等阶段,这些问题不属于我们讨论的范畴,大家只要了解在处理请求的过程中需要这个步骤就好了。

查询优化

  语法解析之后,服务器程序获得到了需要的信息,比如要查询的列是哪些,表是哪个,搜索条件是什么等等,但光有这些是不够的,因为我们写的MySQL语句执行起来效率可能并不是很高,MySQL的优化程序会对我们的语句做一些优化,如外连接转换为内连接、表达式简化、子查询转为连接等等的一堆东西。优化的结果就是生成一个执行计划,这个执行计划表明了应该使用哪些索引进行查询,表之间的连接顺序是什么样的。我们可以使用EXPLAIN语句来查看某个语句的执行计划,关于查询优化这部分的详细内容我们后边会仔细介绍,现在你只需要知道在MySQL服务器程序处理请求的过程中有这么一个步骤就好了。

存储引擎

  截止到服务器程序完成了查询优化为止,还没有真正的去访问真实的数据表,MySQL服务器把数据的存储和提取操作都封装到了一个叫存储引擎的模块里。我们知道表是由一行一行的记录组成的,但这只是一个逻辑上的概念,物理上如何表示记录,怎么从表中读取数据,怎么把数据写入具体的物理存储器上,这都是存储引擎负责的事情。为了实现不同的功能,MySQL提供了各式各样的存储引擎,不同存储引擎管理的表具体的存储结构可能不同,采用的存取算法也可能不同。

小贴士:为什么叫`引擎`呢?因为这个名字更拉风~ 其实这个存储引擎以前叫做`表处理器`,后来可能人们觉得太土,就改成了`存储引擎`的叫法,它的功能就是接收上层传下来的指令,然后对表中的数据进行提取或写入操作。

  为了管理方便,人们把连接管理、查询缓存、语法解析、查询优化这些并不涉及真实数据存储的功能划分为MySQL server的功能,把真实存取数据的功能划分为存储引擎的功能。各种不同的存储引擎向上面的MySQL server层提供统一的调用接口(也就是存储引擎API),包含了几十个底层函数,像"读取索引第一条内容"、"读取索引下一条内容"、"插入记录"等等。

  所以在MySQL server完成了查询优化后,只需按照生成的执行计划调用底层存储引擎提供的API,获取到数据后返回给客户端就好了。

常用存储引擎

  MySQL支持非常多种存储引擎,我这先列举一些:

存储引擎

描述

ARCHIVE

用于数据存档(行被插入后不能再修改)

BLACKHOLE

丢弃写操作,读操作会返回空内容

CSV

在存储数据时,以逗号分隔各个数据项

FEDERATED

用来访问远程表

InnoDB

具备外键支持功能的事务存储引擎

MEMORY

置于内存的表

MERGE

用来管理多个MyISAM表构成的表集合

MyISAM

主要的非事务处理存储引擎

NDB

MySQL集群专用存储引擎

  这么多我们怎么挑啊,你多虑了,其实我们最常用的就是InnoDBMyISAM,有时会提一下Memory。其中InnoDBMySQL默认的存储引擎,我们之后会详细介绍这个存储引擎的各种功能,现在先看一下一些存储引擎对于某些功能的支持情况:

Feature

MyISAM

Memory

InnoDB

Archive

NDB

B-tree indexes

yes

yes

yes

no

no

Backup/point-in-time recovery

yes

yes

yes

yes

yes

Cluster database support

no

no

no

no

yes

Clustered indexes

no

no

yes

no

no

Compressed data

yes

no

yes

yes

no

Data caches

no

N/A

yes

no

yes

Encrypted data

yes

yes

yes

yes

yes

Foreign key support

no

no

yes

no

yes

Full-text search indexes

yes

no

yes

no

no

Geospatial data type support

yes

no

yes

yes

yes

Geospatial indexing support

yes

no

yes

no

no

Hash indexes

no

yes

no

no

yes

Index caches

yes

N/A

yes

no

yes

Locking granularity

Table

Table

Row

Row

Row

MVCC

no

no

yes

no

no

Query cache support

yes

yes

yes

yes

yes

Replication support

yes

Limited

yes

yes

yes

Storage limits

256TB

RAM

64TB

None

384EB

T-tree indexes

no

no

no

no

yes

Transactions

no

no

yes

no

yes

Update statistics for data dictionary

yes

yes

yes

yes

yes

  密密麻麻列了这么多,看的头皮都发麻了,达到的效果就是告诉你:这玩意儿很复杂。其实这些东西大家没必要立即就给记住,我列出来的目的就是想让大家明白不同的存储引擎支持不同的功能,有些重要的功能我们会在后边的介绍中慢慢让大家理解的~

关于存储引擎的一些操作

查看当前服务器程序支持的存储引擎

  我们可以用下面这个命令来查看当前服务器程序支持的存储引擎:

SHOW ENGINES;

  来看一下调用效果:

mysql> SHOW ENGINES;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine             | Support | Comment                                                        | Transactions | XA   | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| InnoDB             | DEFAULT | Supports transactions, row-level locking, and foreign keys     | YES          | YES  | YES        |
| MRG_MYISAM         | YES     | Collection of identical MyISAM tables                          | NO           | NO   | NO         |
| MEMORY             | YES     | Hash based, stored in memory, useful for temporary tables      | NO           | NO   | NO         |
| BLACKHOLE          | YES     | /dev/null storage engine (anything you write to it disappears) | NO           | NO   | NO         |
| MyISAM             | YES     | MyISAM storage engine                                          | NO           | NO   | NO         |
| CSV                | YES     | CSV storage engine                                             | NO           | NO   | NO         |
| ARCHIVE            | YES     | Archive storage engine                                         | NO           | NO   | NO         |
| PERFORMANCE_SCHEMA | YES     | Performance Schema                                             | NO           | NO   | NO         |
| FEDERATED          | NO      | Federated MySQL storage engine                                 | NULL         | NULL | NULL       |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.00 sec)

mysql>

  其中的Support列表示该存储引擎是否可用,DEFAULT值代表是当前服务器程序的默认存储引擎。Comment列是对存储引擎的一个描述,英文的,将就着看吧。Transactions列代表该存储引擎是否支持事务处理。XA列代表该存储引擎是否支持分布式事务。Savepoints代表该列是否支持部分事务回滚。

小贴士:好吧,也许你并不知道什么是个事务、更别提分布式事务了,这些内容我们在后边的章节会详细介绍,现在瞅一眼看个新鲜就行。

设置表的存储引擎

  我们前面说过,存储引擎是负责对表中的数据进行提取和写入的,我们可以为不同的表设置不同的存储引擎,也就是说不同的表可以有不同的物理存储结构,不同的提取和写入方式。

创建表时指定存储引擎

  我们之前创建表的语句都没有指定表的存储引擎,那就会使用默认的存储引擎InnoDB(当然这个默认的存储引擎也是可以修改的,我们在后边的章节中再说怎么改)。如果我们想显式的指定一下表的存储引擎,那可以这么写:

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了。

Supongo que te gusta

Origin blog.csdn.net/qq_42857603/article/details/129427862
Recomendado
Clasificación