测试工程师面试-数据库相关

2022/4/25 2:42:32

本文主要是介绍测试工程师面试-数据库相关,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

记录一下在测试相关的面试中被问到的一些和数据库相关的物体,可能因为是测试岗来着

问的问题都是蛮基础的,哪怕是我简历里面写了redis熟练掌握,但也是没有遇到过有问的。

 

3 4 ①内连接查询 (只显示符合条件的数据)

查询学生表和成绩表所有信息

select * from student inner join sc  on student.sid = sc.sid;

②左外连接查询 (左边表中的数据优先全部显示)

  • 查询学生表和成绩表所有信息

select * from student left join sc  on student.sid = sc.sid;

③右外连接查询 (右边表中的数据优先全部显示)

  • 查询学生表和成绩表所有信息

select * from student right join sc  on student.sid = sc.sid;

④全连接查询(显示左右表中全部数据)

全连接查询:是在内连接的基础上增加 左右两边没有显示的数据 注意: mysql并不支持全连接 full JOIN 关键字 注意: 但是mysql 提供了 UNION 关键字.使用 UNION 可以间接实现 full JOIN 功能 1 2 3 select * from student left join sc on student.sid = sc.sid UNION select * from student right join sc on student.sid = sc.sid;

4.数据库锁

1.具体的锁

行级锁 行级锁是一种排他锁,防止其他事务修改此行;在使用以下语句时,Oracle 会自动应用行级锁:

INSERT、UPDATE、DELETE、SELECT … FOR UPDATE [OF columns] [WAIT n | NOWAIT]; SELECT … FOR UPDATE 语句允许用户一次锁定多条记录进行更新 使用 COMMIT 或 ROLLBACK 语句释放锁。 表级锁 表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大部分 MySQL 引擎支持。最常使 用的 MYISAM 与 INNODB 都支持表级锁定。表级锁定分为表共享读锁(共享锁)与表独占写锁 (排他锁)。

页级锁 页级锁是 MySQL 中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但冲突多,行级 冲突少,但速度慢。所以取了折衷的页级,一次锁定相邻的一组记录。BDB 支持页级锁

MySQL这3种锁的特性可大致归纳如下: 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低; 行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高; 页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。 适用:从锁的角度来说,表级锁更适合于以查询为主,只有少量按索引条件更新数据的应用,如Web应用;而行级锁则更适合于有大量按索引条件并发更新少量不同数据,同时又有并发查询的应用,如一些在线事务处理(OLTP)系统。 ———————————————— 版权声明:本文为CSDN博主「项三城」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/andyjinhui/article/details/121647368

2.数据库并发策略

并发控制一般采用三种方法,分别是乐观锁和悲观锁以及时间戳。

乐观锁

乐观锁认为一个用户读数据的时候,别人不会去写自己所读的数据;悲观锁就刚好相反,觉得自 己读数据库的时候,别人可能刚好在写自己刚读的数据,其实就是持一种比较保守的态度;时间 戳就是不加锁,通过时间戳来控制并发出现的问题。

悲观锁

悲观锁就是在读取数据的时候,为了不让别人修改自己读取的数据,就会先对自己读取的数据加 锁,只有自己把数据读完了,才允许别人修改那部分数据,或者反过来说,就是自己修改某条数 据的时候,不允许别人读取该数据,只有等自己的整个事务提交了,才释放自己加上的锁,才允 许其他用户访问那部分数据。

时间戳

时间戳就是在数据库表中单独加一列时间戳,比如“TimeStamp”,每次读出来的时候,把该字 段也读出来,当写回去的时候,把该字段加 1,提交之前 ,跟数据库的该字段比较一次,如果比数 据库的值大的话,就允许保存,否则不允许保存,这种处理方法虽然不使用数据库系统提供的锁 机制,但是这种方法可以大大提高数据库处理的并发量,以上悲观锁所说的加“锁”,其实分为几种锁,分别是:排它锁(写锁)和共享锁(读锁)。

3.基于 Redis 分布式锁

获取锁的时候,使用 setnx(SETNX key val:当且仅当 key 不存在时,set 一个 key 为 val 的字符串,返回 1;若 key 存在,则什么都不做,返回 0)加锁,锁的 value 值为一个随机生成的UUID,在释放锁的时候进行判断。并使用 expire 命令为锁添 加一个超时时间,超过该时间则自动释放锁。

获取锁的时候调用 setnx,如果返回 0,则该锁正在被别人使用,返回 1 则成功获取锁。 还设置一个获取的超时时间,若超过这个时间则放弃获取锁。

释放锁的时候,通过 UUID 判断是不是该锁,若是该锁,则执行 delete 进行锁释放。 ———————————————— 版权声明:本文为CSDN博主「Django姜戈」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/programmer_union/article/details/117356077

5.数据库三范式

1、第一范式(确保每列保持原子性)

第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式。

第一范式的合理遵循需要根据系统的实际需求来定。比如某些数据库系统中需要用到“地址”这个属性,本来直接将“地址”属性设计成一个数据库表的字段就行。但是如果系统经常会访问“地址”属性中的“城市”部分,那么就非要将“地址”这个属性重新拆分为省份、城市、详细地址等多个部分进行存储,这样在对地址中某一部分操作的时候将非常方便。这样设计才算满足了数据库的第一范式。

上表所示的用户信息遵循了第一范式的要求,这样在对用户使用城市进行分类的时候就非常方便,也提高了数据库的性能。

 

2、第二范式(确保表中的每列都和主键相关)

第二范式在第一范式的基础之上更进一层。第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。

比如要设计一个订单信息表,因为订单中可能会有多种商品,所以要将订单编号和商品编号作为数据库表的联合主键。

订单信息表

这样就产生一个问题:这个表中是以订单编号和商品编号作为联合主键。这样在该表中商品名称、单位、商品价格等信息不与该表的主键相关,而仅仅是与商品编号相关。所以在这里违反了第二范式的设计原则。

而如果把这个订单信息表进行拆分,把商品信息分离到另一个表中,把订单项目表也分离到另一个表中,就非常完美了。

这样设计,在很大程度上减小了数据库的冗余。如果要获取订单的商品信息,使用商品编号到商品信息表中查询即可。

 

3、第三范式(确保每列都和主键列直接相关,而不是间接相关)

第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。

比如在设计一个订单数据表的时候,可以将客户编号作为一个外键和订单表建立相应的关系。而不可以在订单表中添加关于客户其它信息(比如姓名、所属公司等)的字段。如下面这两个表所示的设计就是一个满足第三范式的数据库表。

6.数据语言

  • 数据查询语言(DQL):是由SELECT子句,FROM子句,WHERE子句组成的查询块

  • 数据操纵语言(DML): SELECT(查询) INSERT(插入) UPDATE(更新) DELETE(删除)

  • 数据定义语言(DDL):CREATE(创建数据库或表或索引)ALTER(修改表或者数据库)DROP(删除表或索引)

  • 数据控制语言(DCL):GRANT(赋予用户权限) REVOKE(收回权限) DENY(禁止权限)

  • 事务控制语言(TCL):SAVEPOINT (设置保存点)ROLLBACK (回滚) COMMIT(提交)

7.sql的执行顺序

aql语句的执行过程是:

1、from 子句组装来自不同数据源的数据;

2、where 子句基于指定的条件对记录行进行筛选;

3、group by 子句将数据划分为多个分组;

4、使用聚集函数进行计算;

5、使用 having 子句筛选分组;

6、计算所有的表达式;

7、select 的字段;

8、使用 order by 对结果集进行排序。

8.mysql中change和modify的区别

总结就是--- change改大(名字),modify改小(类型)

之前看过一篇博客,说是modify 是修改微小的操作,而change是 修改和原来幅度比较大的,我觉得很正确

先举几个例子:

将 数据表 deptment 中 name字段的数据类型 由varchar(22) 修改成varchar(30):

 alter table    deptment    modify     name VARCHAR(30);  

这儿只是修改了字段的属性。比较微小,同样的操作,看一下change 是改变多大的


将数据表 department 中的 location字段名 改为loc,数据类型修改成 varchar(30):

alter table deptment change location loc varchar(30);

这而不仅修改了数据类型,关键改名字,只要改名字 肯定要用change 你想想 改一个名子 会牵扯到很多东西,而只改一个数据类型则会牵扯的很小,这儿就能看出 change修改的范围和力度要比modify 大。

用的时候,一定要注意:

修改数据类型,修改字段位置 ---用modify

修改名字 --就用change ———————————————— 版权声明:本文为CSDN博主「小曹男孩」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_36057860/article/details/79512394



这篇关于测试工程师面试-数据库相关的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程