SQL变更评审常见问题分享

SQL变更评审分享

概述

SQL变更,是我们在开发迭代中不可避免的场景,SQL变更通常是指DDL和DML语句变更,这些sql会影响到数据库表结构或具体数据,变更时如果执行到存在问题的sql脚本,会对实际应用操作难以评估的损失,比如咱们常挂在嘴边的删库跑路。

通常情况下程序员并发故意想“删库跑路”,而是因为种种原因,将存在问题的sql脚本放到了生产环境执行,导致最终出现生产环境数据异常。我们避免异常SQL在生产环境执行的一个有效方式,就是进行SQL变更评审,在评审过程中,我们能将一些有明显缺陷的SQL语句及时拦截,也能凭借评审人的sql经验,把一些不容易发现的问题在评审过程中暴露,进而优化。

sql变更不能完全依赖于评审发现问题,评审只是变更流程中不可获取的一环,评审可以一定程度上防止变更人的疏忽大意以及惯性思维,另外将sql暴露在多个评审人眼前,也容易让问题更容易被发现。sql评审比较依赖于评审人的相关经验,我参与过一些sql评审,故在这里对评审总结的一些经验进行分析,共勉。

一、常见的一些DML操作

以表t_user为例

CREATE TABLE `t_user` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`password` varchar(32) DEFAULT NULL,`role` int(11) DEFAULT NULL,`creation_date` datetime DEFAULT NULL,`last_update_date` datetime DEFAULT NULL,`is_deleted` tinyint(4) DEFAULT '0',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1486021 DEFAULT CHARSET=latin1;

数据样式
在这里插入图片描述

1、执行语句是否有加 where条件,或者where后面的条件是符合预期

update t_user set `password` = 222 -- 变更人遗忘了where条件delete from t_user where is_deleted = 'Y';  -- 变更人希望清除标记为已删除的数据

上述update语句,由于“where”条件缺失,将对整张表进行字段“password”字段修改

上述delete语句,变更人希望清除标记为已删除的数据,is_deleted为int类型,值1表示已删除,值0表示未删除,由于变更人把枚举理解为“Y”表示已删除,数值类型与字符串比较时,会进行隐式转换,字符串开头不为数字,会被转换成0,结果执行sql,t_user表将所有未标记删除的数据进行删除。

2、执行语句覆盖的数据量是否过大

当执行dml语句,如果表数据量大,同时执行语句覆盖的数据量大,会导致执行时间较长,执行语句行锁时间长,结果导致其他业务操作受到影响。

常见的导致覆盖数据太大的情况有如下几种

1)where条件中,索引失效或未使用到包含索引的字段

由于索引失效,where条件查询满足条件的行,会对全表进行扫描,导致数据库锁表

语句一:

update t_user set `password` = 222 where id + 1 = 2; -- id为主键,但是表达式左侧进行运算导致主键索引失效,查询更新数据时进行了全表扫描

在这里插入图片描述

语句二:

update t_user set `password` = 222 where name = "ck"; -- name未添加索引,查询更新数据时全表扫描

在这里插入图片描述

语句一,将索引失效问题处理,即可解决锁表问题
在这里插入图片描述

语句二,如果实际要修改的数据量不多,几个或者几十个,可将数据先提前查出,记录行数据主键或其中一个具有唯一值且有索引的字段,在原查询条件中添加索引字段条件,可有效缩小范围;实际要修改的数据量较大,可通过建立临时表,临时表存储需要修改数据的唯一索引字段,再通过联表的方式进行索引字段关联,缩小范围。

临时表 t_user_id 保存name为“ck” 的id
在这里插入图片描述

2)索引未失效,但仍进行了全表扫描

update t_user set `password` = 222 where id in (select id from t_user_id); -- 全表扫描,update时,每行数据都会进行in select操作

在查询时,这种写法会用到索引,select id from t_user_id 也只会执行1次
在这里插入图片描述

但是在update或delete语句中
在这里插入图片描述

每次每行语句都会执行 select id from t_user_id,因此进行了全表扫描,可将语句改为联表操作,数据范围即可缩小

修改后:

update t_user u join t_user_id ui on u.id = ui.id set `password` = 222;

在这里插入图片描述

3)exist 引入的异常sql

delete from t_user where EXISTS (select 1 from t_user_id ui where ui.id = id); --将进行全表数据删除

t_user 与t_user_id表中都有id字段,exists中就近取t_user_id表的id字段,ui.id = id 恒成立

在删除sql中,exists中的语句不能医用被删除表的中字段,最终写出来能执行的sql,但是却是全表删除
在这里插入图片描述

建议delete语句和update语句使用exists时不要使用这类写法。

修改为联表方式

delete t_user, t_user_id from t_user join t_user_id on t_user.id = t_user_id.id

在这里插入图片描述

二、常见的DDL操作

1、修改字段备注

修改备注时不会进行锁表,无需担心锁表

2、修改字段名称、字段类型、字段长度、字段默认值以及新增字段、添加索引,删除索引

1)此类操作,需考虑表数据量大小,若数据量小于百万级别

执行数据较快,一般不影响业务

2)在百万级别以上,这类修改字段设计到表结构变化,会导致表锁定,应避免在高负载时进行此类操作,以免影响系统性能

3)百万级别以上建议用一下方式修改表字段

a、创建一个新的临时表

b、执行修改表字段操作

c、将原始数据插入临时表,并记录此时时间

b、原始表表名修改,临时表修改为原始表名

e、检查在复制数据阶段,原来的原始表是否有数据更新和插入(根据记录的时间查询),有更新则在新表中同步更新

三、数据备份及数据清理

我们都希望变更执行成功,不会有回退的时候,但为了避免回退时数据丢失难以恢复,有必要进行数据的备份处理;另外长期使用数据库,数据库中难免会有一些空间碎片,为避免存储空间浪费,需要定期进行数据清理;

1、数据备份

1)数据更新或数据删除

将需要修改或需要删除的数据,复制到临时表进行备份,备份表名最好统一格式,便于区分用途和备份时间

2)新增数据无需备份

2、数据清理

1)OPTIMIZE TABLE

OPTIMIZE TABLE 进行碎片整理,由于会锁表,应避免在高负载时进行此类操作,以免影响系统性能
在这里插入图片描述

默认会记录binlog,如果不想记录binlog,添加local参数,即 OPTIMIZE local TABLE

在这里插入图片描述

2)其他清理表方式

OPTIMIZE TABLE执行时间较长时,不可避免影响业务,此时可以参考修改表字段时的操作

a、创建一个新的临时表

b、执行修改表字段操作

c、将原始数据插入临时表,并记录此时时间

b、原始表表名修改,临时表修改为原始表名

e、检查在复制数据阶段,原来的原始表是否有数据更新和插入(根据记录的时间查询),有更新则在新表中同步更新

f、原来需要清理数据的表,进行表删除

最后

sql变更,不可能全靠sql评审规避所有问题,变更人仍需遵守规范,同时重视sql,在上生产前,充分做好测试,测试环境执行测试几乎能规避全部问题,数据写操作时,修改为查询语句,可检测数据范围,让sql在有充分把握,再去生产执行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/299108.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JuiceSSH结合内网穿透实现公网远程访问本地Linux虚拟机

文章目录 1. Linux安装cpolar2. 创建公网SSH连接地址3. JuiceSSH公网远程连接4. 固定连接SSH公网地址5. SSH固定地址连接测试 处于内网的虚拟机如何被外网访问呢?如何手机就能访问虚拟机呢? cpolarJuiceSSH 实现手机端远程连接Linux虚拟机(内网穿透,手机端连接Linux虚拟机) …

DHT11编程

实验:用数码管显示温湿度 dht11.h #ifndef _DHT11_H #define _DHT11_H #include "stm32f10x_conf.h"extern void dht11_init(void); extern void Get_Dht_Value(char *buf); #endifdht11.c #include"dht11.h" #include"bitband.h" …

Kylin-Desktop-V10-SP1-General-Release-2303-X86_64-海光版(hygon c86)镜像虚拟机安装

选择60G 自定义硬件 设置内存、cpu、网络为桥接 点击开启虚拟机 在下一步中输入用户名和密码 等待安装完成 取出安装介质:先关机,再按照下图操作 移除,并确认 再开机,等待启动成功 系统版本

04|提示工程(上):用少样本FewShotTemplate和ExampleSelector创建应景文案

04|提示工程(上):用少样本FewShotTemplate和ExampleSelector创建应景文案 当你用 print 语句打印出最终传递给大模型的提示时,一切就变得非常明了。 您是一位专业的鲜花店文案撰写员。 对于售价为 50 元的 玫瑰 &…

基于 Python 和Surprise库,新手轻松搭建推荐系统

解密基于用户的推荐系统。 1、简介 在数据时代,推荐系统是提升用户体验的重要工具。今天介绍如何使用亚马逊的电影评分数据集创建电影推荐系统。 2、数据加载与探索 首先,通过加载和探索数据集开启数据分析过程。首先导入Pandas和Numpy,这…

2024年【天津市安全员C证】找解析及天津市安全员C证模拟考试题

题库来源:安全生产模拟考试一点通公众号小程序 天津市安全员C证找解析考前必练!安全生产模拟考试一点通每个月更新天津市安全员C证模拟考试题题目及答案!多做几遍,其实通过天津市安全员C证模拟考试题库很简单。 1、【多选题】《建…

飞桨星河社区助力大模型时代开发者砥砺前行!

大模型引领AI新浪潮,助力人工智能实现从感知理解到生成创造的飞跃。飞桨星河社区,覆盖深度学习初学者、在职开发者、企业开发者、高校教师、创业者等,是国内最大的AI开发者社区,以飞桨和文心大模型为核心,集开放数据、…

疫病困扰,本文或许能帮你拨云见日

1、《伤寒论》中的大青龙,五苓散,小柴胡,麻杏甘石等就是千百年来,老祖宗给我们留下的方子,也被无数实践证明有效。 2、中西医思路不同,西医研究病毒,治疗手段就是对付病毒。而中医用中草药推动…

Scala安装

Scala安装使用 windows安装,配置环境变量 以下载Scala2.11为例,操作在Windows中安装Scala。 官网下载scala2.11:All Available Versions | The Scala Programming Language下载好后安装。双击msi包安装,记住安装的路径。配置环境变量(和配…

如何改进SEO?学会这5个策略就没问题

引言: 在当今竞争激烈的在线市场中,搜索引擎优化(SEO)对于网站的成功至关重要。通过采用正确的策略和技巧,你可以提高网站在搜索引擎结果页面中的排名,吸引更多的有针对性的流量。在本文中,我们…

优雅地使用python读取excel

python读取excel可以用pandas模块,功能比较强大 在对应的虚拟环境里面用anaconda安装(如果你的python运行环境是用anaconda配置的),如果没有添加虚拟环境,直接在终端里面pip3 install pandas安装就可以。 import pan…

Mac使用Python的tkinter显示异常解决方案

显示异常的原因&#xff1a; macOS版本>12 & python版本<3.9.8 参考文档 :https://www.python.org/download/mac/tcltk/ 如果python版本过低&#xff1a; brew upgrade python: 升级python版本 brew install python-tk: 安装最新的tk版本 python -m tkinter : 弹…