4.数据库面试

七言 2025-8-1 10 8/1

[TOC]

数据库面试题

1. 你在测试过程中使用数据库的场景是什么?

  • 考点:
    • 1.是否了解数据库的相关知识
    • 2.是否有在日常的测试工作中使用数据库来辅助测试结果的验证
  • 在做功能测试的过程中,除了检查页面,app功能正常外,还需要查询存数据库的数据是否符合预期。然后有时候还会修改数据库中的测试数据来验证一些测试用例,比如把已注销的用户状态改为未注销,这样就可以重复利用这个数据了。再就是一些新的业务模块需要测试的时候,我们会根据数据库的表结构和业务规则,提前构造很多测试数据用来做测试,效率呢比通过前端界面逐条添加要高很多。如果是测试报表模块,我们会根据报表的业务规则写对应的sql语句去数据库查询,从而验证报表展示的结果数据是否正确

2. 主键、外键和索引的区别?

*

  1. 定义
    • 主键:唯一标识一条记录,不能有重复的,不允许为空
    • 外键:表的外键是另一条表的主键,外键可以有重复的,可以是空值
    • 索引:该字段没有重复值,但可以有一个空值
  2. 作用
    • 主键:用来保证数据完整性
    • 外键:用来和其他表建立联系用的
    • 索引:提高查询排序的速度
  3. 个数
    • 主键:只能有一个
    • 外键:一个表可以有多个外键
    • 索引:一个表可以有多个索引

3. 你说下drop、delete、truncata三者的区别?

  • 都表示删除,但是三者有一些区别
  • delete用来删除表的全部或者一部分数据行,执行delete之后,用户需要提交(commit)或者回滚(rollback)来执行删除或者撤销删除。会触发这个表上所有的delete触发器
  • truncate删除表中的所有数据,这个操作不能回滚也不能触发表上的触发器,truncate比deleta更快,占用的空间更小
  • drop命令从数据库中删除表,所有的数据行,索引和权限也都会被删除。也不能回滚

4. 列举几种表连接的方式,有什么区别?

  • 左连接(left join on):左边为主表,表数据全部显示,右边为匹配表,匹配表的不匹配部分不显示
  • 右连接(right join on):右边为主表,表数据全部显示,左边为匹配表,匹配表的不匹配部分不显示
  • 内连接(inner join on):只有两个元素(左表和右表)表相匹配的才能在结果集中显示
  • 全外连接(full outer join on,mysql中使用union):连接中的不匹配的数据全部会显示出来,能够从两张内容不一致的表里,获取全部的信息。左表和右表都不做限制,所有的记录都显示,两表不足的地方用null填充(左外+右外-重复)
  • 交叉连接(cross join):返回结果集合中的数据行数等于第一表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数

5. 数据库中having和where的区别?

  • having可以单独使用,单独使用的情况下和where的功能类似,只不过having筛选的字段必须在select子句中出现。大多数情况下having是用在group by之后,对分组后的结果进行进一步筛选
  • where是用在group by分组之前,是根据条件从表中筛选出数据
  • 如果同时使用having和where,他们的顺序是,先where然后跟group by最后是having

6. SQL中的select语句的执行顺序是怎样的?

  • 关键字顺序:

    select...distinct...from...join...on...where...group by...having......order by...limit...
  • (1)select *或者字段---要查询的字段(2)distinct---后面加字段,根据字段去重(3)from---查询字段所属的数据表(4)where---查询条件,指定条件对查询记录进行筛选(5)group by---将数据划分为多个分组(6)having---对分组后的结果进行筛选(7)order by---对筛选后的结果进行排序,默认升序,DESC降序(8)limt---取出指定行的记录,limit有两个参数,第一个参数表示从第几行数据开始查,第二个参数表示查几条数据,“limit 3,2”表示从第四行数据开始,取两条数据

  • select语句的执行顺序:

    from 确定在哪张表查询; where 设置过滤条件,过滤出符合条件的内容; group by 对过滤后的数据按字段分组; having 再进一步对分组后的数据过滤; select 查找数据; distinct 去重; order by 对去重后的数据按要求排序; limit 限制显示或打印数据的条数。

7. SQL中常用的聚合函数都有哪些?

  • max():最大值
  • min():最小值
  • avg():平均值
  • sum():求和
  • count():统计总数

8. 用一条SQL语句查询出每门课都大于80分的学生姓名。表scores如下:

name courese score
张三 语文 81
张三 数学 75
李四 语文 76
李四 数学 90
王五 数学 100
王五 英语 90
  • 学生的最大分数大于80,那么就可以查询出每门课都大于80分的学生姓名

    select name,min(score) 
    from scores 
    group by name 
    having min(score)>80

9. 用一条SQL语句查询两门以上不及格课程的同学的学号以及其平均成绩,并按成绩排序。表结构如下:

  • Student表:
id studentname
1 张三
2 张三
3 李四
  • student_score表:
id couresename score
1 语文 78
1 数学 50
2 语文 56
2 数学 58
3 语文 78
3 数学 47
    select S.id,S.studentname,avg(C.score) 
    from student as S,student_score as C 
    where S.id = C.id and C.score < 60 
    group by C.id having count(*) > 1

10. 为管理岗位业务培训信息,建立3个表

  • S(S#,SN,SD,SA)S#,SN,SD,SA分别代表学号、学员姓名、所属单位、学员年龄

  • C(C#,CN)C#,CN分别代表课程编号、课程名称

  • SC(S#,C#,G)S#,C#,G分别代表学号、所选修的课程编号、学习成绩

  • 要求实现如下5个处理:

  • 1.使用标准SQL嵌套查询语句查询选修课程名称为"税收基础"的学员学号和姓名

    select S#,SN 
    from S 
    where S# in(
        select S# from SC where SC.C# = (
            select C# from C where CN = '税收基础'))
  • 2.使用标准SQL嵌套语句查询选修课程编号为"C2"的学员姓名和所属单位

    select SN,SD 
    from S 
    where S# =(
        select S# from SC where SC.C# in (
            select C# from C where C# = 'c2'))
  • 3.使用标准SQL嵌套语句查询不选修课程编号为"C5的"学员姓名和所属单位

    select SN,SD
    from S
    where S# not in(
        selse S# from SCwhere C# = 'C5')
  • 4.使用标准SQL嵌套语句查询选修全部课程的学员姓名和所属单位

    select SN,SD 
    from S 
    where S# in(
        select S# from SC 
            right join C on SC.C# = C.C# 
            group by S# having count(*) = count(S#))
  • 5.查询选修了课程的学员人数

    select 学员人数 = count(S#) 
    from SC
  • 6.查询选修课程超过5门的学员学号和所属单位

    select S#,SD
    from S
    where S# in(
        select S# from SC
        group by S# having count(distinct C#) > 5) 

11. 已知关系模式:使用SQL查询语句

  • S(SNO,SNAME)学生关系表。SNO为学号,SNAME为姓名

  • C(CNO,CNAME,CTEACHER)课程关系表。CNO为课程号,CNAME为课程名,CTEACHER为任课教师

  • SC(SNO,CNO,SCGRADE)选课关系表。SCGRADE为成绩

  • 实现以下5个处理:

  • 1.找出没有选修过“李明”老师讲授课程的所有学生姓名

    select SNAME as 学生姓名
    from S
    where not exists(
        seletct * from SC,C where SC.CNO=C.CNO and CTEACHER= '李明' and SC.SNO=S.SNO)
    
    select SNAME as 学生姓名
    from S
    where SNO not in(
        select SNO from SC,C where SC.CNO=C.CNO and CTEACHER='李明')
  • 2.列出有二门以上(含两门)不及格课程的学生姓名及其平均成绩

    select S.SNO as 学生学号,S.SNAME as 学生姓名,avg(SC.SCGRADE) as 平均成绩
    from S,SC
    where SC.SNO=S.SNO and SC.SNO in(
        select SC.SNO from SC where SC.SCGRADE < 60 group by SC.SNO having count(*)>=2)
        group by S.SNO,S.SNAME
  • 3.列出既学过“1”号课程,又学过“2”号课程的所有学生姓名

    select S.SNO as 学生学号,S.SNAME as 学生姓名
    from S
    where SNO in(
        select SNO from C where CNO in('01','02')
        group by SNO having count(distinct CNO)=2 )
  • 4.列出“1”号课成绩比“2”号课成绩高的所有学生的学号及其“1”号课和“2”号课的成绩

    select sc1.SNO as 学生学号,sc1.scgrade as no1grade,sc2.scgrade as no2grade
    from SC as sc1,C as c1,SC as sc2,C as c2
    where sc1.cno=c1.cno and c1.cno='01' and sc2.cno=c2.cno and c2.cno='02' and no1scgrade > no2scgrade 
    group by sc1.sno
  • 5.列出'1'号课成绩比'2'号课成绩高的所有学生的学号

    select sc1.sno as 学生学号
    from SC as sc1,C as c1,SC as sc2,C as c2
    where sc1.cno=c1.cno and c1.cno='01' and sc2.cno=c2.cno and c2.cno='02' and sc1.scgrade > sc2.scgrade
    group by sc1.sno

12.redis了解嘛?如何做缓存应用测试?

  • 1.redis是基于内存的键值存储数据库,读写速度快,支持持久化,数据不会因服务重启丢失
  • 2.我们可以通过一些基础命令来进行redis数据的查询:
KEYS user:*  # 查找所有以 "user:" 开头的键

DEL user:123  # 删除键 "user:123"

EXISTS user:123`  # 检查键 "user:123" 是否存在

SET name "Alice"  # 设置键 "name" 的值为 "Alice"

GET name  # 获取键 "name" 的值

APPEND greeting " World"  # 向键 "greeting" 的值追加 " World"
  • 3.工作流:客户端(浏览器、APP、第三方系统、小程序)--1.请求查询数据-->JAVA应用程序--->2.查询redis是否有数据--->有数据返回对应结果给客户端---没有数据返回为空---JAVA应用程序查询数据库--->查询到数据进行返回给JAVA应用程序--->应用程序会把数据库查询出来的数据塞入redis缓存
  • 4.缓存写入测试:检查数据是否正确写入redis,验证写入的键值对是否符合预期
  • 5.缓存读取测试:检查数据是否能够从redis正确读取,验证读取的数据是否与写入的数据一致
  • 6.缓存失效测试:检查缓存是不是按照设定的Time To Live生存时间自动失效,验证手动删除缓存后,是否能够重新加载数据
  • 7.缓存更新测试:检查缓存数据在数据库更新后是否能够同步进行更新
  • 8.测试缓存在高并发请求下的处理能力,使用工具(如redis-benchmark)模拟大量并发请求,检查Redis的内存使用情况,确保没有内存泄漏
  • 9.模拟多个客户端同时更新缓存和数据库,检查是否出现数据不一致
  • 10.模拟 Redis 服务宕机,检查系统是否能够降级到直接访问数据库。 验证 Redis 重启后,数据是否能够恢复
  • 11.模拟网络中断,检查系统是否能够正确处理连接失败的情况,
  • 12.测试数据一致性:分布式环境测试,Redis集群或主从复制,确保数据在多个节点之间保持一致。
    • 在主节点写入数据:SET mykey "Hello"
    • 在从节点读取数据,验证是否同步:GET mykey # 应该返回 "Hello"

13.redis和SQL数据库数据不一致怎么测试?

  • 一般来说开发都会针对这种情况做一个双写(先往数据库写一份再往redis写一份)和定时同步(比如每半个小时同步一次)、异步更新缓存

  • 1.首先先了解redis和sql数据库间的同步机制: * 是定时同步(如每隔几分钟同步一次)? * 是实时同步(如通过消息队列或触发器)? * 是手动同步(如通过脚本或任务)?

  • 2.再进行测试用例的设计:

    • 插入数据测试:在SQL数据库中插入一条记录,检查Redis中是否同步。
    • 更新数据测试:更新SQL数据库中的记录,检查Redis中是否同步
    • 删除数据测试:删除SQL数据库中的记录,检查Redis中是否同步
    • 并发操作测试:模拟高并发场景,测试数据一致性(缓存雪崩:如果缓存失效,会导致高并发请求怼到数据库)
  • 3.手动验证数据:使用sql查询工具进行数据查询SELECT * FROM users WHERE id = 1;

  • 再使用redis-cli检查数据:GET user:1

  • 4.设置监控系统,配置报警规则,当数据不一致时及时通知开发人员

  • 5.最后根据测试结果,优化数据同步机制

14.redis测试中常见的一些问题?

  • 1.数据更新的空白期---某个时间节点,数据时有时无
  • 2.某些接口直接返回空---查询某个接口,没有东西返回(key失效,key过期)
  • 3.需要构造假验证码,假账号,获取token(在redis里直接写入)
- THE END -

七言

8月01日16:36

最后修改:2025年8月1日
0

非特殊说明,本博所有文章均为博主原创。

共有 0 条评论