数据库测试从入门到实战:SQL验证、增删改查、数据一致性与脏数据处理全攻略 大家好我是陪你系统复习的老周。前面讲了接口测试很多同学问接口返回 200 就一定对吗不一定。接口返回成功只说明请求通了数据有没有正确写进数据库、字段值对不对、关联表有没有同步更新这些才是测试的核心。今天讲测试工程师第 6 块——数据库测试从基础 SQL 到实战场景新人打基础、老人磨技巧。一、什么是数据库测试为什么重要数据库测试就是用 SQL 直接查询数据库验证业务操作后的数据是否正确。它是接口测试和功能测试的照妖镜——页面显示正常、接口返回成功都不代表数据一定对。举个真实场景用户注册接口返回 200页面提示注册成功但一查数据库发现用户表写进去了账户表没初始化用户登录后余额显示 null。这种 bug 光测接口发现不了必须查数据库。数据库测试的核心价值验证数据的正确性字段值、类型、默认值验证数据的完整性关联表、外键、级联操作验证数据的一致性多表数据是否同步、冗余字段是否一致发现脏数据异常数据、边界数据、历史遗留数据二、数据库测试基础常用 SQL 语句测试工程师不需要成为 DBA但以下 SQL 必须熟练。查询数据SELECT*FROMusersWHEREid1001;SELECTusername,email,statusFROMusersWHEREcreate_time2026-01-01LIMIT10;聚合统计SELECTCOUNT(*)FROMusersWHEREstatus1;SELECTMAX(balance),MIN(balance),AVG(balance)FROMaccounts;SELECTuser_id,COUNT(*)FROMordersGROUPBYuser_idHAVINGCOUNT(*)5;联表查询SELECTu.username,o.order_no,o.amountFROMusers uLEFTJOINorders oONu.ido.user_idWHEREu.id1001;查看表结构DESCusers;SHOWCREATETABLEusers;新人建议把这几类 SQL 练到肌肉记忆测试时直接写不用百度。三、增删改查结果怎么验证每个业务操作后都要用 SQL 验证数据库的变化。下面按 CRUD 分别说。3.1 新增操作Create测试点数据是否真的插入了COUNT 或 SELECT 验证每个字段的值是否正确特别是默认值、自动生成的字段关联表是否同步插入如注册用户同时创建账户、角色记录唯一约束是否生效重复用户名能否插入非空字段传 null 会怎样示例用户注册后验证-- 验证用户表插入SELECTid,username,email,status,create_timeFROMusersWHEREusernametest001;-- 验证账户表同步创建SELECTuser_id,balance,frozen_amountFROMaccountsWHEREuser_id(SELECTidFROMusersWHEREusernametest001);3.2 查询操作Read测试点查询条件是否正确等值、模糊、范围分页是否正确LIMIT offset, size排序是否正确ORDER BY多条件组合查询是否正确大数据量下查询性能是否走索引示例分页查询验证-- 第1页每页10条SELECT*FROMordersWHEREuser_id1001ORDERBYcreate_timeDESCLIMIT0,10;-- 第2页SELECT*FROMordersWHEREuser_id1001ORDERBYcreate_timeDESCLIMIT10,10;-- 验证总数SELECTCOUNT(*)FROMordersWHEREuser_id1001;3.3 更新操作Update测试点字段是否正确更新不该更新的字段有没有被误更新乐观锁/悲观锁是否生效并发更新更新后历史数据是否保留如果有审计表批量更新是否全部成功示例修改用户信息后验证-- 更新前记录SELECTusername,phone,update_timeFROMusersWHEREid1001;-- 执行接口更新后SELECTusername,phone,update_timeFROMusersWHEREid1001;-- 验证其他字段没变SELECTemail,status,create_timeFROMusersWHEREid1001;3.4 删除操作Delete测试点是物理删除还是逻辑删除status0 vs DELETE关联数据怎么处理级联删除/禁止删除/保留删除后能否恢复批量删除是否全部成功删除后唯一键能否复用示例删除用户后验证-- 逻辑删除验证SELECTid,username,status,deletedFROMusersWHEREid1001;-- 物理删除验证SELECTCOUNT(*)FROMusersWHEREid1001;-- 应为0-- 关联表验证SELECTCOUNT(*)FROMordersWHEREuser_id1001;四、数据一致性测试数据一致性是数据库测试的重中之重也是最容易出线上事故的地方。4.1 什么是数据不一致同一个业务事实在不同表中存储的值不一样。比如订单表状态已支付但支付表状态待支付用户表余额100但账户流水表加起来80主表删除了子表还挂着孤儿数据4.2 常见一致性测试场景场景一支付后订单状态和支付状态一致性-- 找出订单已支付但支付记录未成功的异常数据SELECTo.order_no,o.statusasorder_status,p.statusaspay_statusFROMorders oLEFTJOINpayments pONo.idp.order_idWHEREo.status3AND(p.status!2ORp.idISNULL);场景二账户余额与流水一致性-- 验证余额 初始值 所有收入 - 所有支出SELECTa.user_id,a.balance,(SELECTCOALESCE(SUM(amount),0)FROMaccount_flowWHEREuser_ida.user_idANDtype1)astotal_in,(SELECTCOALESCE(SUM(amount),0)FROMaccount_flowWHEREuser_ida.user_idANDtype2)astotal_outFROMaccounts aWHEREa.user_id1001;-- 手动验证balance 是否等于 initial total_in - total_out场景三主从表外键一致性-- 找出子表有但主表没有的孤儿数据SELECTo.*FROMorders oLEFTJOINusers uONo.user_idu.idWHEREu.idISNULL;4.3 一致性测试的实用技巧写对账 SQL把常见的一致性校验写成固定 SQL每次发版前跑一遍关注冗余字段冗余存储的字段如用户表存了订单数最容易不一致并发场景重点测同时支付、同时退款、同时修改余额事务回滚验证操作中途失败数据是否回滚到操作前状态五、脏数据与边界数据测试5.1 什么是脏数据脏数据就是不符合业务规则的数据可能是历史 bug 产生的也可能是测试遗留的。常见类型字段值超出枚举范围status99但定义只有 0/1/2关联外键不存在孤儿数据金额为负数、时间格式错误重复数据唯一约束没建或被绕过空值出现在非空字段5.2 脏数据检测 SQL-- 检测枚举值异常SELECT*FROMordersWHEREstatusNOTIN(0,1,2,3,4);-- 检测负金额SELECT*FROMaccountsWHEREbalance0;-- 检测重复数据SELECTusername,COUNT(*)FROMusersGROUPBYusernameHAVINGCOUNT(*)1;-- 检测空值SELECT*FROMusersWHEREemailISNULLORemail;5.3 边界数据测试边界类型测试值预期字符串长度最大长度、最大长度1边界内正常超出报错或截断数值范围0、负数、最大值、最大值1业务规则内正常越界报错日期时间闰年2月29、跨年、跨时区正确处理特殊字符单引号、SQL关键字、emoji正确转义存储空值null、空字符串、空格按业务规则处理特别注意单引号和反斜杠\是 SQL 注入的常见入口测试时必须验证转义是否正确。六、实战案例一个下单接口的完整数据库测试业务场景用户下单扣减库存创建订单扣减余额。测试步骤第一步操作前记录基线数据-- 记录商品库存SELECTstockFROMproductsWHEREid100;-- 记录用户余额SELECTbalanceFROMaccountsWHEREuser_id1001;-- 记录订单数SELECTCOUNT(*)FROMordersWHEREuser_id1001;第二步执行下单接口第三步操作后验证-- 验证订单创建SELECTorder_no,user_id,product_id,amount,statusFROMordersWHEREuser_id1001ORDERBYidDESCLIMIT1;-- 验证库存扣减SELECTstockFROMproductsWHEREid100;-- 应减1-- 验证余额扣减SELECTbalanceFROMaccountsWHEREuser_id1001;-- 应减订单金额-- 验证账户流水SELECT*FROMaccount_flowWHEREuser_id1001ORDERBYidDESCLIMIT1;-- 验证一致性余额变化 流水金额第四步异常场景验证库存不足时下单调库失败数据回滚余额不足时下单失败不扣库存并发下单同一商品不超卖七、给新人的建议 vs 给老人的进阶给新人先把 SELECT/WHERE/ORDER BY/LIMIT/JOIN/GROUP BY 练熟每个接口测试后都查一下数据库养成接口数据库双重验证习惯准备一份常用 SQL 模板查用户、查订单、对账随用随取学会用 DESC 和 SHOW CREATE TABLE 看表结构理解字段含义不要直接在生产库执行 UPDATE/DELETE测试环境也要先 SELECT 确认给老人的进阶学习执行计划 EXPLAIN验证测试数据查询是否走索引搭建自动化数据校验脚本发版前自动跑对账 SQL关注事务隔离级别对测试数据的影响RR vs RC学习存储过程和临时表复杂场景批量造数据关注数据库性能大数据量下接口响应时间、慢查询学习数据迁移和同步测试分库分表、主从切换后的数据一致性八、高频面试题Q接口返回成功数据库数据不对你怎么排查先确认接口参数和请求是否正确再查应用日志看 SQL 执行情况然后直接查数据库对比预期值检查是否有事务回滚、触发器、默认值、字段类型转换等问题最后看是否有并发覆盖。Q如何验证一个批量更新操作全部成功更新前后 COUNT 对比、抽样验证字段值、检查影响行数ROW_COUNT()、验证未被匹配的行是否未被误更新。Q什么是孤儿数据怎么检测子表中关联了主表已删除的记录。用 LEFT JOIN IS NULL 检测。口诀接口成功不算完数据库里查一番 增删改查逐项验关联表也要看全 一致性写对账SQL脏数据边界不能忘 先查后改是铁律生产环境别乱删。数据库测试就讲到这里。它是测试工程师的基本功也是区分点点点测试和有深度测试的关键。下一期讲Linux 与日志定位线上出问题怎么快速查日志抓包敬请关注。如果这篇对你有帮助欢迎点赞、收藏、关注咱们每周二/四/六一块测试工程师实战知识点系统进阶不迷路。#软件测试 #测试工程师 #数据库测试 #SQL #接口测试 #自动化测试 #测试实战 #MySQL