炸裂!MySQL 82 张图带你飞!(二)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 这篇文章我们来了解一下 MySQL 中的高级内容。

事务表和非事务表

事务表故名思义就是支持事务的表,支不支持事务和 MySQL 的存储类型有关,一般情况下,InnoDB 存储引擎的表是支持事务的,关于 InnoDB 的知识,我们会在后面详细介绍。

非事务表相应的就是不支持事务的表,在 MySQL 中,存储引擎 MyISAM 是不支持事务的,非事务表的特点是不支持回滚。

对于回滚的话,还要讲一点就是 SAVEPOINT,它能指定事务回滚的一部分,但是不能指定事务提交的一部分。SAVEPOINT 可以指定多个,在满足不同条件的同时,回滚不同的 SAVEPOINT。需要注意的是,如果定义了两个相同名称的 SAVEPOINT,则后面定义的 SAVEPOINT 会覆盖之前的定义。如果 SAVEPOINT 不再需要的话,可以通过 RELEASE SAVEPOINT 来进行删除。删除后的 SAVEPOINT 不能再执行 ROLLBACK TO SAVEPOINT 命令。

我们通过一个示例来进行模拟不同的 SAVEPOINT

首先先启动一个事务 ,向 cxuan005 中插入一条数据,然后进行查询,那么是可以查询到这条记录的

start transaction;
insert into cxuan005(id,info) values(666,'cxuan666');
select * from cxuan005 where id = 666;

查询之后的记录如下

微信图片_20220418192858.png

然后我们定义一个 SAVEPOINT,如下所示

savepoint test;

然后继续插入一条记录

insert into cxuan005(id,info) values(777,'cxuan777');

此时就可以查询到两条新增记录了,id 是 666 和 777 的记录。

select * from cxuan005 where id = 777;

微信图片_20220418192902.png

那么我们可以回滚到刚刚定义的 SAVEPOINT

rollback to savepoint test;

再次查询 cxuan005 这个表,可以看到,只有 id=666 的这条记录插入进来了,说明 id=777 这条记录已经被回滚了。

微信图片_20220418192905.png

此时我们看到的都是 mysql01 中事务还没有提交前的状态,所以这时候 mysql02 中执行查询操作是看不到 666 这条记录的。

然后我们在 mysql01 中执行 commit 操作,那么此时在 mysql02 中就可以查询到这条记录了。

SQL 安全问题

SQL 安全问题应该是我们程序员比较忽视的一个地方了。日常开发中,我们一般只会关心 SQL 能不能解决我们的业务问题,能不能把数据查出来,而对于 SQL 问题,我们一般都认为这是 DBA 的活,其实我们 CRUD 程序员也应该了解一下 SQL 的安全问题。

SQL 注入简介

SQL 注入就是利用某些数据库的外部接口将用户数据插入到实际的 SQL 中,从而达到入侵数据库的目的。SQL 注入是一种常见的网络攻击的方式,它不是利用操作系统的 BUG 来实现攻击的。SQL 主要是针对程序员编写时的疏忽来入侵的。

SQL 注入攻击有很大的危害,攻击者可以利用它读取、修改或者删除数据库内的数据,获取数据库中的用户名和密码,甚至获得数据库管理员的权限。并且 SQL 注入一般比较难以防范。

SQL Mode

MySQL 可以运行在不同的 SQL Mode 模式下,不同的 SQL Mode 定义了不同的 SQL 语法,数据校验规则,这样就能够在不同的环境中使用 MySQL ,下面我们就来介绍一下 SQL Mode。

SQL Mode 解决问题

SQL Mode 可以解决下面这几种问题

  • 通过设置 SQL Mode,可以完成不同严格程度的数据校验,有效保障数据的准确性。
  • 设置 SQL Mode 为 ANSI 模式,来保证大多数 SQL 符合标准的 SQL 语法,这样应用在不同数据库的迁移中,不需要对 SQL 进行较大的改变
  • 数据在不同数据库的迁移中,通过改变 SQL Mode 能够更方便的进行迁移。

下面我们就通过示例来演示一下 SQL Mode 用法

我们可以通过

select @@sql_mode;

来查看默认的 SQL Mode,如下是我的数据库所支持的 SQL Mode

微信图片_20220418192911.png

涉及到很多 SQL Mode,下面是这些 SQL Mode 的解释

ONLY_FULL_GROUP_BY:这个模式会对 GROUP BY 进行合法性检查,对于 GROUP BY 操作,如果在SELECT 中的列,没有在 GROUP BY 中出现,那么将认为这个 SQL 是不合法的,因为列不在 GROUP BY 从句中

同样举个例子,我们现在查询一下 cxuan005 的 id 和 info 字段。

select id,info from cxuan005;

这样是可以运行的

微信图片_20220418192915.png

然后我们使用 GROUP BY 字句进行分组,这里只对 info 进行分组,我们看一下会出现什么情况

select id,info from cxuan005 group by info;

微信图片_20220418193123.png

我们可以从错误原因中看到,这条 SQL 语句是不符合 ONLY_FULL_GROUP_BY 的这条 SQL Mode 的。因为我们只对 info 进行分组了,没有对 id 进行分组,我们把 SQL 语句改成如下形式

select id,info from cxuan005 group by id,info;

微信图片_20220418192919.png

这样 SQL 就能正确执行了。

当然,我们也可以删除 sql_mode = ONLY_FULL_GROUP_BY 的这条 Mode,可以使用

SET sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));

来进行删除,删除后我们使用分组语句就可以放飞自我了。

select id,info from cxuan005 group by info;

微信图片_20220418192926.png

但是这种做法只是暂时的修改,我们可以修改配置文件 my.ini 中的 sql_mode= STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

STRICT_TRANS_TABLES:这就是严格模式,在这个模式下会对数据进行严格的校验,错误数据不能插入,报error 错误。如果不能将给定的值插入到事务表中,则放弃该语句。对于非事务表,如果值出现在单行语句或多行语句的第1行,则放弃该语句。

当使用 innodb 存储引擎表时,考虑使用 innodb_strict_mode 模式的 sql_mode,它能增量额外的错误检测功能。

NO_ZERO_IN_DATE:这个模式影响着日期中的月份和天数是否可以为 0(注意年份是非 0 的),这个模式也取决于严格模式是否被启用。如果这个模式未启用,那么日期中的零部分被允许并且插入没有警告。如果这个模式启用,那么日期中的零部分插入被作为 0000-00-00 并且产生一个警告。

这个模式需要注意下,如果启用的话,需要 STRICT_TRANS_TABLESNO_ZERO_IN_DATE 同时启用,否则不起作用,也就是

set session sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE';

然后我们换表了,使用 cxuan003 这张表,表结构如下

微信图片_20220418192930.png

我们主要测试日期的使用,在 cxuan003 中插入一条日期为 0000-00-00 的数据

insert into cxuan003 values(111,'study','0000-00-00');

发现能够执行成功,但是把年月日各自变为 0 之后再进行插入,则会插入失败。

insert into cxuan003 values(111,'study','2021-00-00');

微信图片_20220418192937.png

insert into cxuan003 values(111,'study','2021-01-00');

微信图片_20220418192940.png

这些组合有很多,我这里就不再细致演示了,读者可以自行测试。

如果要插入 0000-00-00 这样的数据,必须设置 NO_ZERO_IN_DATENO_ZERO_DATE

ERROR_FOR_DIVISION_BY_ZERO:如果这个模式未启用,那么零除操作将会插入空值并且不会产生警告;如果这个模式启用,零除操作插入空值并产生警告;如果这个模式和严格模式都启用,零除从操作将会产生一个错误。

NO_AUTO_CREATE_USER:禁止使用 grant 语句自动创建用户,除非认证信息被指定。

NO_ENGINE_SUBSTITUTION:此模式指定当执行 create 语句或者 alter 语句指定的存储引擎没有启用或者没有编译时,控制默认存储引擎的自动切换。默认是启用状态的。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
机器学习/深度学习 算法 TensorFlow
Python 强化学习实用指南:1~5
Python 强化学习实用指南:1~5
190 1
|
安全 Java Linux
讲讲用户态和内核态之间的爱恨情仇(面试篇)
讲讲用户态和内核态之间的爱恨情仇(面试篇)
260 0
|
XML Java 数据格式
|
3天前
|
存储 弹性计算 人工智能
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
2025年9月24日,阿里云弹性计算团队多位产品、技术专家及服务器团队技术专家共同在【2025云栖大会】现场带来了《通用计算产品发布与行业实践》的专场论坛,本论坛聚焦弹性计算多款通用算力产品发布。同时,ECS云服务器安全能力、资源售卖模式、计算AI助手等用户体验关键环节也宣布升级,让用云更简单、更智能。海尔三翼鸟云服务负责人刘建锋先生作为特邀嘉宾,莅临现场分享了关于阿里云ECS g9i推动AIoT平台的场景落地实践。
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
|
2天前
|
云安全 人工智能 自然语言处理
阿里云x硅基流动:AI安全护栏助力构建可信模型生态
阿里云AI安全护栏:大模型的“智能过滤系统”。
|
2天前
|
人工智能 自然语言处理 自动驾驶
关于举办首届全国大学生“启真问智”人工智能模型&智能体大赛决赛的通知
关于举办首届全国大学生“启真问智”人工智能模型&智能体大赛决赛的通知
|
5天前
|
存储 机器学习/深度学习 人工智能
大模型微调技术:LoRA原理与实践
本文深入解析大语言模型微调中的关键技术——低秩自适应(LoRA)。通过分析全参数微调的计算瓶颈,详细阐述LoRA的数学原理、实现机制和优势特点。文章包含完整的PyTorch实现代码、性能对比实验以及实际应用场景,为开发者提供高效微调大模型的实践指南。
564 2
|
3天前
|
Linux 虚拟化 iOS开发
VMware Workstation Pro 25H2 for Windows & Linux - 领先的免费桌面虚拟化软件
VMware Workstation Pro 25H2 for Windows & Linux - 领先的免费桌面虚拟化软件
843 4
VMware Workstation Pro 25H2 for Windows & Linux - 领先的免费桌面虚拟化软件
kde
|
5天前
|
人工智能 关系型数据库 PostgreSQL
n8n Docker 部署手册
n8n是一款开源工作流自动化平台,支持低代码与可编程模式,集成400+服务节点,原生支持AI与API连接,可自托管部署,助力团队构建安全高效的自动化流程。
kde
386 3