一文带你简单搞懂MySQL变量,今晚可以助眠哦!

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 一文带你简单搞懂MySQL变量,今晚可以助眠哦!

放弃前戏,直奔主题

什么是变量?有点编程基础的盆友都知道啥是变量哈!笔者在此就不啰嗦了。放弃前戏,直接步入主题。那么,在MySQL数据库中,mysql的变量是什么鬼?简单的说:可以在存储过程或函数中,使用变量来存储值,比如存储计算后的中间结果数据等等,mysql的变量又分为“系统变量”以及“用户自定义变量”。

MySQL服务器维护许多配置其操作的系统变量,以下官方文档描述了这些变量的含义:

每个系统变量都有一个默认值。可以在服务器启动时使用命令行或在配置文件(my.cnf)中定义选项来设置系统变量。其中在Mysql运行期间可以通过SET语句在服务器运行时动态更改,这样您就可以修改服务器的操作,而无需停止和重新启动它。您还可以在表达式中使用系统变量值。

想知道一个变量的含义,可以参考官方资料哈

  1. 打开官方文档, 服务器选项、系统变量和状态变量参考链接:https://dev.mysql.com/doc/refman/8.0/en/server-option-variable-reference.html
  2. 如下图:

先大处着眼一下,总结下变量的分类

总结1:变量分为两大类,系统变量和状态变量。

总结2:系统变量又分为全局系统变量和全局会话变量。

  1. 系统变量

系统变量就是Mysql针对自己程序运行的一些参数配置。例如通过系统变量我们可以指定诸如允许同时连入的客户端数量、客户端和服务器通信方式、表的默认存储引擎、查询缓存的大小等设置项。

然后,系统变量还又分2类呢,如下:

  • GLOBAL:全局系统变量,影响服务器的整体操作。
  • SESSION:全局会话变量,影响某个客户端连接的操作。(注:SESSION有个别名叫LOCAL)
  1. 状态变量

MySQL服务器程序中维护了好多关于程序运行状态的变量,它们被称为状态变量,由于状态变量是用来显示服务器程序运行状况的,所以它们的值只能由服务器程序自己来设置,我们程序员是不能设置的。与系统变量类似,状态变量也有GLOBAL和SESSION两个作用范围的。比方说Threads_connected表示当前有多少客户端与服务器建立了连接,Handler_update表示已经更新了多少行记录。

查看状态变量的语法:

SHOW [GLOBAL|SESSION] STATUS [LIKE 匹配的模式];

例如通过全局状态变量Slow_queries,可查询到当前系统中有多少条慢查询记录

mysql> SHOW GLOBAL STATUS LIKE '%Slow_queries%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Slow_queries  | 0     |
+---------------+-------+
1 row in set (0.00 sec)

开始动手实战,二话不说就是撸!

撸什么?笔者带你撸sql,简单的实战,抛砖引玉哈!

一、系统变量之剖析和实战

  • 变量由系统定义,不是用户定义,属于服务器层面
  • 系统变量的值要么是编译MySQL时参数的默认值,要么是 配置文件 (例如my.cnf、my.ini等)中的参数值。
  • 系统变量分为全局系统变量(需要添加 global 关键字)以及会话系统变量(需要添加 session 关键字),有时也把全局系统变量简称为全局变量,有时也把会话系统变量称为local变量。如果不写,默认 会话级别。静态变量(在 MySQL 服务实例运行期间它们的值不能使用 set 动态修改)属于特殊的全局系统变量。

在MySQL中有些系统变量只能是全局的,例如 max_connections 用于限制服务器的最大连接数;有些系统变量作用域既可以是全局又可以是会话,例如 character_set_client 用于设置客户端的字符集;有些系统变量的作用域只能是当前会话,例如 pseudo_thread_id 用于标记当前会话的 MySQL 连接 ID。

1.全局系统变量(简称:全局变量)

案例:查看所有全局变量

mysql> show global variables\G;

案例:查看满足条件的部分系统变量

mysql> SHOW GLOBAL VARIABLES LIKE 'admin_%';
+------------------------+-------------------------------+
| Variable_name          | Value                         |
+------------------------+-------------------------------+
| admin_address          |                               |
| admin_port             | 33062                         |
| admin_ssl_ca           |                               |
| admin_ssl_capath       |                               |
| admin_ssl_cert         |                               |
| admin_ssl_cipher       |                               |
| admin_ssl_crl          |                               |
| admin_ssl_crlpath      |                               |
| admin_ssl_key          |                               |
| admin_tls_ciphersuites |                               |
| admin_tls_version      | TLSv1,TLSv1.1,TLSv1.2,TLSv1.3 |
+------------------------+-------------------------------+
11 rows in set (0.01 sec)
mysql>

2.会话系统变量(简称:local变量)

每一个MySQL客户端成功连接MySQL服务器后,都会产生与之对应的会话。会话期间,MySQL服务实例会在MySQL服务器内存中生成与该会话对应的会话系统变量,这些会话系统变量的初始值是全局系统变量值的复制。如下图:

特别声明:上图摘自互联网,仅作参考之用,如有侵权请告知笔者,将会立刻删除,谢谢!

  • 全局系统变量针对于所有会话(连接)有效,但 不能跨重启
  • 会话1对某个全局系统变量值的修改会导致会话2中同一个全局系统变量值的修改。

案例:查看所有会话变量

mysql> show session variables\G;
# 或者
mysql> show variables\G;

案例:查看满足条件的部分会话变量

mysql> SHOW SESSION VARIABLES LIKE 'admin_%';
+------------------------+-------------------------------+
| Variable_name          | Value                         |
+------------------------+-------------------------------+
| admin_address          |                               |
| admin_port             | 33062                         |
| admin_ssl_ca           |                               |
| admin_ssl_capath       |                               |
| admin_ssl_cert         |                               |
| admin_ssl_cipher       |                               |
| admin_ssl_crl          |                               |
| admin_ssl_crlpath      |                               |
| admin_ssl_key          |                               |
| admin_tls_ciphersuites |                               |
| admin_tls_version      | TLSv1,TLSv1.1,TLSv1.2,TLSv1.3 |
+------------------------+-------------------------------+
11 rows in set (0.01 sec)
mysql>

3. 查看指定系统变量值

作为 MySQL 编码规范,MySQL 中的系统变量以 两个“@” 开头其中“@@global”仅用于标记全局系统变量,“@@session”仅用于标记会话系统变量。 “@@”首先标记会话系统变量,如果会话系统变量不存在,则标记全局系统变量。

案例:系统变量admin_tls_version的值

mysql> select @@global.admin_tls_version;
+-------------------------------+
| @@global.admin_tls_version    |
+-------------------------------+
| TLSv1,TLSv1.1,TLSv1.2,TLSv1.3 |
+-------------------------------+
1 row in set (0.00 sec)

案例:查看会话变量windowing_use_high_precision的值

mysql> select @@session.windowing_use_high_precision;
+----------------------------------------+
| @@session.windowing_use_high_precision |
+----------------------------------------+
|                                      1 |
+----------------------------------------+
1 row in set (0.00 sec)
mysql>

4. 修改系统变量的值

有些时候,数据库管理员需要修改系统变量的默认值,以便修改当前会话或者MySQL服务实例的属性、 特征。具体方法:

  • 方式1:修改MySQL配置文件(如my.cnf、my.ini),继而修改MySQL系统变量的值(该方法需要重启MySQL服务)
  • 方式2:在MySQL服务运行期间,使用“set”命令重新设置系统变量的值,使用该SET语句动态更改,这使您能够修改服务器的操作而无需停止和重新启动它

最佳实践:修改Mysql系统变量的最佳实践是,如果mysql正在运行,且不能重启,但又要修改变量,可用set命令进行修改,就可以不用重启mysql服务而使其马上生效,为了预防忘记,同时还要写入到my.cnf配置文件中,这样的话,等到可以重启mysql的时候,就会从my.cnf配置文件中加载配置了。

全局变量赋值语法格式:

#方式1:
SET @@global.变量名=变量值;
#方式2:
SET GLOBAL 变量名=变量值;

会话变量赋值语法格式:

#方式1:
SET @@session.变量名=变量值;
#方式2:
SET SESSION 变量名=变量值;

二、用户自定义变量简单剖析和实战

用户变量是用户自己定义的,作为 MySQL 编码规范,MySQL中的用户变量以一个 “@” 开头。根据作用范围不同,又分为 会话用户变量 和 局部变量 。

  • 会话用户变量:作用域和会话变量一样,只对 当前连接 会话有效。
  • 局部变量:只在 BEGIN 和 END 语句块中有效。局部变量只能在 存储过程和函数 中使用。

1.自定义会话用户变量

变量的定义,语法格式:

#方式1:“=”或“:=” 
SET @用户变量 = 值; 
SET @用户变量 := 值; 
#方式2:“:=” 或 INTO关键字 
SELECT @用户变量 := 表达式 [FROM 等子句]; 
SELECT 表达式 INTO @用户变量 [FROM 等子句];

查看用户变量的值语法:

SELECT @用户变量;

案例1:自定义变量name,并将字符串"chavis"赋值给该变量

# 定义变量和赋值
mysql> set @name="chavis";
Query OK, 0 rows affected (0.00 sec)
# 查询
mysql> select @name;
+--------+
| @name  |
+--------+
| chavis |
+--------+
1 row in set (0.00 sec)
mysql>

案例2:将数字101赋值给变量n,注意,数字值类型一定要使用”:=“进行赋值,不能用”=“

mysql> select @n := 101;
+-----------+
| @n := 101 |
+-----------+
|       101 |
+-----------+
1 row in set, 1 warning (0.00 sec)
# 查询变量
mysql> select @n;
+------+
| @n   |
+------+
|  101 |
+------+
1 row in set (0.00 sec)
mysql>

案例3:随便查询一个没有声明的变量,不会报错,只是值会是NULL

mysql> select @a;
+------------+
| @a         |
+------------+
| NULL       |
+------------+
1 row in set (0.12 sec)

案例4:统计history表有多少条记录,并将统计后的值并赋值给自定义变量abc

# 查询和赋值
mysql> select @abc := count(*) from zabbix.history;
+------------------+
| @abc := count(*) |
+------------------+
|          1274372 |
+------------------+
1 row in set, 1 warning (5.79 sec)
# 查询变量的值
mysql> select @abc;
+---------+
| @abc    |
+---------+
| 1274372 |
+---------+
1 row in set (0.00 sec)
mysql>

案例5:查询hosts表中name为zbxproxy01的记录,并将字段name的值赋给变量@hname

# 查询和赋值
mysql> select name into @hname from zabbix.hosts where name='zbxproxy01';
Query OK, 1 row affected (0.02 sec)
# 查询变量值
mysql> select @hname;
+------------+
| @hname     |
+------------+
| zbxproxy01 |
+------------+
1 row in set (0.00 sec)
mysql>

案例6:可以同时将多个字段值分别赋值给不同的变量,一一对应即可

# 查询和赋值
mysql> select name,hostid into @hname,@hid from zabbix.hosts where name='zbxproxy01';                
Query OK, 1 row affected (0.00 sec)
mysql> select @hname;
+------------+
| @hname     |
+------------+
| zbxproxy01 |
+------------+
1 row in set (0.00 sec)
# 查询变量值
mysql> select @hid;
+-------+
| @hid  |
+-------+
| 10357 |
+-------+
1 row in set (0.00 sec)
mysql>

2.自定义局部变量

  • 定义:可以使用 DECLARE 语句定义一个局部变量
  • 作用域:仅仅在定义它的 BEGIN ... END 中有效,也就是在存储过程或存储函数中的 BEGIN ... END
  • 位置:只能放在 BEGIN ... END 中,而且只能放在第一句

语法格式如下:

BEGIN
    #声明局部变量
    DECLARE 变量名1 变量数据类型 [DEFAULT 变量默认值]; 
    DECLARE 变量名2,变量名3,... 变量数据类型 [DEFAULT 变量默认值]; 
    #为局部变量赋值 
    SET 变量名1 = 值; 
    SELECT 值 INTO 变量名2 [FROM 子句]; 
    #查看局部变量的值 
    SELECT 变量1,变量2,变量3; 
END
  1. 定义变量
DECLARE 变量名 类型 [default 值]; # 如果没有DEFAULT子句,初始值为NULL
  1. 变量赋值 方式1:一般用于赋简单的值
SET 变量名=值;
SET 变量名:=值;

方式2:一般用于赋表中的字段值

SELECT 字段名或表达式 INTO 变量名 FROM 表;
  1. 使用变量(查看、比较、运算等)
SELECT 局部变量名;
  1. 实践例子

案例:声明局部变量hostname和ipaddr,并将查询到的结果通过into赋值给局部变量hostname和ipaddr,最好通过select进行输出

# 修改结束符为“//”
delimiter //
# 创建存储过程get_hostname_and_ip
create procedure zabbix.get_hostname_and_ip()
begin
declare hostname varchar(64);
declare ipaddr varchar(64);
select host.name,host.ip into hostname,ipaddr from (select h.name,i.ip from zabbix.hosts h join zabbix.interface i on h.hostid=i.hostid and h.name='zbxser01') host; 
select hostname,ipaddr;
end //
# 将结束符修改回默认“;”
delimiter ;
# 调用存储过程
mysql> call zabbix.get_hostname_and_ip;
+----------+----------------+
| hostname | ipaddr         |
+----------+----------------+
| zbxser01 | 192.168.11.153 |
+----------+----------------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql>

案例:声明两个变量,求和并打印 (分别使用会话用户变量、局部变量的方式实现)

方式1:使用会话用户变量

mysql> set @x=3;
mysql> set @y=5;
mysql> set @sum=@x+@y;
Query OK, 0 rows affected (0.00 sec)
mysql> select @sum;
+------+
| @sum |
+------+
|    8 |
+------+
1 row in set (0.00 sec)
mysql>

方式2:在存储过程中使用局部变量

# 修改结束符
delimiter //
# 创建存储过程
CREATE procedure p_add_value()
BEGIN
DECLARE x INT DEFAULT 3;
DECLARE y INT DEFAULT 5;
DECLARE sum INT;
set sum=x+y;
select sum;
END //
# 修改回默认的结束符
delimiter ;
# 调用
mysql> call p_add_value;
+------+
| sum  |
+------+
|    8 |
+------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql>

写在最后

运维是一门实战性非常强的学科,必须动手实践,光看是学不会的。望有兴趣的盆友多动手、多实践哈!当然,背后的原理也需要搞懂,但一开始笔者不建议直接陷入原理的环节,先动手把环境搞起来再说!简单的入了门之后,再分块剖析原理并结合实践,真正做到理论指导实践,实践验证理论的真理。好了,今晚时间有限,就此搁笔,望多多支持、关注、点赞、转发。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
30天前
|
存储 关系型数据库 MySQL
mysql 使用变量存储中间结果的写法
mysql 使用变量存储中间结果的写法
|
3月前
|
存储 SQL 关系型数据库
15. Mysql 变量的使用
15. Mysql 变量的使用
33 1
|
4月前
|
存储 关系型数据库 MySQL
【MySQL进阶之路 | 基础篇】变量
【MySQL进阶之路 | 基础篇】变量
|
3月前
|
存储 SQL 关系型数据库
MySQL数据库——存储过程-变量(系统变量、用户定义变量、局部变量)
MySQL数据库——存储过程-变量(系统变量、用户定义变量、局部变量)
108 0
|
3月前
|
存储 关系型数据库 MySQL
Mysql存储过程查询结果赋值到变量
Mysql存储过程查询结果赋值到变量
130 0
|
4月前
|
关系型数据库 MySQL
mysql 动态变量,可以在线修改
7.1.9.2 Dynamic System Variables
37 0
|
关系型数据库 MySQL
|
4月前
|
存储 SQL 关系型数据库
MySQL存储过程 if、case、while、loop、游标、变量、条件处理程序
MySQL存储过程 if、case、while、loop、游标、变量、条件处理程序
127 0
|
4月前
|
存储 关系型数据库 MySQL
认识MySQL数据库中用户自定义变量
认识MySQL数据库中用户自定义变量。
76 0
|
9月前
|
存储 SQL 关系型数据库
MySQL基础-变量/流程控制/游标/触发器
MySQL基础-变量/流程控制/游标/触发器

热门文章

最新文章