一、本文背景
今天继续更新我的博文,前面讲了测试人员需要具备的技能,本文就讲讲作为测试人员,需要会那些数据库知识。为什么测试需要会一定的数据库知识呢?个人观点而论,一般在测试环境进行测试时,需要提前准备一些测试数据,需要使用SQL往数据库里增加一些数据;另外就是迭代中新增了某些功能字段之类的,或者变更了数据信息啥的,就需要到数据库上查询看看结果。
二、数据库和sql简单说明
1、数据库简单说明:
因个人知识储备有限,简单说明一下,欢迎补充:
数据库是长期存储在计算机内、有组织性的集合。
用下面这张图来展示数据库扮演的一个角色:
数据库又分为关系型数据库和非关系型数据库,不过我接触的都是关系型数据库,就说关系型数据库。
关系型数据库的核心就是用表存储信息。然后我们常见的有oracle、mysql、microsoft sql server。
用一张表简单说明关系型数据库的核心:
2、sql简单说明:
SQL是一种用于操作数据库的语言,也是结构化的语言。
SQL是用于所有数据库的基本语言。
根据ANSI(美国国家标准协会),SQL是操作关系数据库管理系统的标准语言。
它的设计允许管理RDBMS中的数据,例如MYSQL。
SQL语言还用于控制数据访问以及数据库模式的创建和修改。
MySQL是一种RDBMS,它允许保持数据库中存在的数据。
MySQL提供对数据库的多用户访问。
核心区别:SQL是一种查询语言,而MYSQL是数据库软件
三、数据库工具
mysql也是分为服务端和客户端的,服务端只能通过命令进行操作,而客户端就是可视化界面的,看得见的。
测试一般还不用安装服务端的,服务端安装起来也比较麻烦,使用客户端的就足够进行数据的增删改查了。
常用的客户端可视化工具有: phpMyAdmin 对应网址: http://www.phpmyadmin.net/ MySQLDumper 对应网址:http://www.mysqldumper.de/en/ Navicat 对应网址:http://www.navicat.com/(目前使用) MySQL GUI Tools 对应网址:http://dev.mysql.com/downloads/gui-tools/ MySQL ODBC Connector 对应网址http://dev.mysql.com/downloads/connector/odbc/ SQLyog 对应网址:http://sqlyog.en.softonic.com/ https://www.webyog.com/product/sqlyog)
我平时使用比较多的就是Navicat,就医Navicat举例:
首先,下载并打开Navicat:
点击连接,选择mysql:
填写新建连接内容:
连接成功后,会显示一个新的灰色连接,双击打开,此时代表连接上了,变成绿色:
圈中的数据库内容不可随意修改,会影响大mysql服务端,导致重装mysql
在右侧空白处单击鼠标右键,选择“新建数据库”:
在新建数据库下填写“字符集”和“排序规则”。字符集和排序都选择选择utf-8,点击确定
双击打开新建的数据库,就可以对数据库进行操作了:
新建查询就可以输入SQL语句进行查询了:
选中要操作的数据库,选择“新建查询”,然后在编辑框里面就可以输入sql语句了。
四、常用SQL语句
1、常见的数据类型和约束:
MySQL数据库的数据类型主要是分为数值型,日期时间型以及字符串型这三个大类。
比较常用的几组:
整数型的 tinyint 和 bigint
小数型的 decimal
日期时间类型 datetime 和 timestamp
字符串型是 char 和 varchar
浮点 double 和 float
————————————————————————
简单提一下约束:
约束其实就是一种限制,用于修饰表中的列. 通过这种限制来保证表中数据的正确性、有效性和完整性。
约束类型:
约束名 约束关键字
主键 primary key
非空 not null 被修饰的这个字段必须设置值,不能是NULL
唯一 unique 在这张表中这个字段的值不能重复
外键 foreign key ... references
默认 default 往表中添加数据时,如果不指定这个字段的数据,就使用默认值
2、sql语句:
创建表:
基本格式:
create table 表名(
字段名 类型 约束,
字段名 类型 约束
……
)
如:创建一个学生表,只有姓名和年龄字段:
运行就会得到下面这张表:
下面是更详细的创建表的sql代码:
create table student(
id int unsigned primary key auto_increment,
name varchar(10),
age int unsigned,
height decimal(5,2)
)
注:
int类型默认是有符号的,如果想要无符号就加上unsigned;
primary key代表主键;
auto_increment代表自动递增。这里的id号就会自动递增,且不会重复(如果中途删除id为10的内容,再递增就是11,不再有10了。)
“id int unsigned primary key auto_inorement”这个基本上就是固定格式,一般都把id置位主键。
最后的“height decimal(5,2)”,说明身高的类型是小数类型的,共五位数,小数点后面2位数。
删除表:
drop table 表名
或:
drop table if exists 表名 (一般在创建一个新表之前都会跟上这条语句,在这个基础上在新建表)
注:**多条sql语句之间必须在上一条sql语句末尾加上英文的分号
增删改查语句:
新增:
1、添加数据:
insert into 表名 values(……)
括号里面的内容必须与表格当中的字段的顺序和类型一模一样,不能空着。
如果是id对应的内容可以填写0或者null或者default,它们都代表自动递增。
然后日期时间和字符串类型都需要单引号引起来。
如:
添加数据的几种方法:
insert into 表名(属性,属性) values(值,值)
insert into 表名(name) values(‘鲁班’)————————————单个的添加数据
insert into 表名(name,age) values(‘鲁班’,30)
insert into 表名(name) values(‘小乔’,‘大乔’,‘孙膑’)
修改:
格式:update 表名 set 列1=值1,列2=值2,……where 条件
如:
updata student set age=10 where id =5
将id=5的那一行的age值置位10.
updata student set name=’狄仁杰’,age=22,height=16.0 where age=20
将age=20的所有数据的名字置为“狄仁杰”,age置为22,身高置为16.0.
删除:
格式:delete from 表名 where 条件
如:
delete from 表名 where id=12
删除id=12那行的数据
逻辑删除:
这里补充一个逻辑删除:
逻辑删除:对于重要的数据,不能轻易的执行delete,一旦删除,就不容易再找回,这时就可以进行逻辑删除。
添加字段:isdelete,代表是否被删除。
isdelete=0 未被删除(默认为0)
isdelete=1 被删除(形式上的被删除,实际上并未被删除)
1、先给表添加一个字段: update 表名 set isdetele=0
2、将删除id=1的所有数据删除: update 表名 set isdelete=1 where id=1
3、查询未被删除的数据:select * from 表名 where isdelete=0
查询:
查询所有字段:
select * from 表名
查询部分:
select name,age from 表名
还可以表名后面跟where进行条件查询:
select * from 表名 where 条件
select * from student where age>20
查询student表中年龄大于20的信息
select name from student where sex='女'
查询student表中性别为女的学生姓名
select name,sex from student where name!='张三'
查询student表中学生姓名不为张三的学生姓名和性别信息
查询时结合逻辑运算符进行多条件查询:
逻辑运算包括与、或、非,以实例说明:
与:————and
select * from student where age>20 and name!='张三'
查询student表中年龄大于20并且名字不是张三的学生信息
或:————or
select * from student where class='1班' or class='2班'
查询student表中班级是1班或者是2班的学生信息
非:————not / !
select * from student where class!='1班'
也可以是:
select * from student where not class='1班'
消除重复行:
有一次面试,被面试官问到消除重复行怎么消除,可以记一下
select distinct sex from students
去除students表中sex的重复行
select distinct class,sex from students
去除students表中的class和sex的重复行
模糊查询:
关键字:like
%表示任意一个或者多个任意的字符;
_表示一个字符。
1、查询姓孙的学生:
select *from student1 where name like '孙%'
2、查询姓孙的且名只有一个字的学生:
select *from student1 where name like '孙_'
3、查询名字中带乔字的学生:
select *from student1 where name like '%乔'
4、查询姓名含白的学生:
select *from student1 where name like '%白%'
5、查询学生姓名为两个字的学生:
select *from student1 where name like '__'
范围查询:
范围查询主要针对某一个字段有多种情况
1、查询学生是1班或者2班或者4班的:
select *from student1 where class in('1班','2班','3班')
2、查询年龄在9~13的学生:
select *from student1 where age between 9 and 13
3、如果要查询年龄不在9~13岁之间的学生呢?
select *from student1 where not age between 9 and 13
在响应条件字段之前加上not
4、查询student1表中班级是空的信息
select *from student1 where class is null
查询student1表中班级不是空的信息
select *from student1 where class is not null
或
select *from student1 where not class is null
注:**没有=null这种写法,写法错误
排序:
格式:
select *from 表名 order by 列1 asc/desc
(asc是正序(由小到大),desc是倒序(由大到小))
1、现在对学生的年龄按照正序排序:
select *from student1 order by age asc
2、但是当年龄出现一样的时候,我们如何采取另一种方式排序呢?
这时候选择当出现年龄一样的时候我们就选择班级正序排序:
select *from student1 order by age,class asc
3、如果现在要求对学生们排序,按照姓名首字母的正序排序应该如何排序呢?
select *from student1 order by convert(name using gbk)
gbk是专门的中文编码。
聚合函数:
聚合函数是为了快速统计数据; count(*)表示计算行总数,括号写*是最好的,也也可以写列名,但是写列名可能不够精准,造成漏算(不会算null的个数)。
max(列)表示求此列的最大值;
min(列)表示求此列的最小值;
sum(列)表示求此列的和。
1、现在查询学生的总数是多少?
select count(*)from student1
2、查询女生的最大年龄:
select max(age) from student1 where sex='女'
3、查询男生的平均年龄:
select avg(age) from student1 where sex='男'
分组查询+分组过滤查询:
分组的关键字:group by
1、现在对学生表下的学生按照班级进行分组:
select *from student1 group by class
2、现在要求查询各性别的人数(男生多少人?女生是多少人?)
select count(*)from student1 group by sex
3、查询各个班级学生的平均年龄、最大年龄和最小年龄:
select class,max(age),avg(age) from student1 group by class
按照多个字段来分组,多个字段的值一摸一样的时候,被分为一组。
对学生表按照班级和姓名进行分组:
select class,sex count(*) from student1 group by class,sex
分组过滤:
关键字:having
having,其实having和where的作用是一样的,也是起到过滤的作用,但是也有区别,而且在面试中也被问到过,这里我就不做过多总结,可以参考学习一下这位优秀博主的笔记:https://www.cnblogs.com/yymn/p/17727016.html
1、查询男生的总数:
select sex,count(*)from student1 group by sex having sex=’男’
2、查询1班以外,其他班学生的平均年龄、最大年龄和最小年龄
select class,avg(age),max(age),min(age) from student1 group by class having class !='1班'
或者:
select class,avg(age),max(age),min(age) from student1 where class!='1班' group by class
分页:
当获取的数据量很大时,在一页中查看是一件非常麻烦的事
格式:select *from 表名 limit start,count
表示的是:从start开始,获取count条数据,而start索引是从0开始的。
1、查询前3行学生的信息:select *from student1 limit 0,3
说明(这里的0代表的是第一条的位置,若limit后面只写1个数字,就代表它把其实位置省略了
,limit n,从第一行开始取n行显示。)
多表等值连接查询:
多表等值连接的原理就是:
先将所有的多表之间的内容连接在一起,然后在过滤掉错误的内容,留下匹配正确的数据构成新表。
多表连接我们都以以下三个表作为例子讲解(student,course,score)
单表和多表的区别:
单表:select *from student
多表:select *from student,score,course
比如,现在我们要连接student和score,这两个表,分析可以看到,这两个表他们具有共同的字段stuno,这就是关键所在,多表连接就是通过多表的相同关键字段连接在一起的。
对student和score两表进行连接:
select *from student,score where student.stuno=score.stuno
但是这种连接方式有一个缺点,就是会造成生成临时表占用内存,消耗资源。
结果:
内连接:
内连接的好处就是不会生成临时表,连接时先判断条件,只符合条件的才会连接一起再被放到结果表中。
现在将student表和score表连接起来:
select *from student as stu
inner join score as sc on stu.stuno=sc.stuno
现在求:查询课程信息及课程的成绩
分析:课程信息和课程的成绩他们相关联的就是课程号,所以,把具有课程号的两张表相连接起来。select *from score,course
where score.courseno=course.courseno
或者:
select *from course
inner join score on score.courseno=course.courseno
三表连接:
三表连接就需要两两表相连之间具有连接关联。
现在对student、score、course三表进行三表连接:
法1:select *from student,score,course
where student.stuno=score.stuno and score.courseno=course.courseno
法2:select *from student
inner join score on score.stuno=student.stuno
inner join course on course.courseno=score.courseno
结果:
要求查询鲁班的成绩,要求显示姓名、课程号、成绩
从表分析,可知,要知道姓名要查学生表,课程号要查课程表,成绩要查成绩表。
先三表合一:
select student.name,course.courseno,score.score from student
inner join score on student.stuno=score.stuno
inner join course on course.courseno=score.courseno
where student.name='鲁班'
或者:
select student.name,course.courseno,score.score from student,course,score
where student.stuno=score.stuno and score.courseno=course.courseno
and student.name='鲁班'
结果:
左连接+右连接:
在join之前的表叫做左表,join之后的表叫做右表。left左连接就是把左边表里的所有信息都显示出来,与右表中找到交集的地方就全部显示出来,右表中找不到的地方就全部以null显示。
格式:
select *from 表1
left join 表2 on 表1.列=表2.列
要求:查询所有学生的成绩,包括没有成绩的学生:
score在这里做右表,题干要求显示学生信息包括没有成绩的学生,那么student(左表)就要全部显示出来,故用left。
select *from student
left join score on score.stuno=student.stuno
也可以用右表,即右连接:
select *from score
right join student on student.stuno=score.stuno
查询所有课程的成绩,包括没有成绩的课程,包括学生信息。
select *from scroe
right join course on course.courseno=score.courseno
left join student on student.stuno=score.stuno
左连接结果:
右连接结果:
自关联:
自关联,就是自己多次查自己,然后自己再连接自己。一般用于带有层次关系中。
如:这里我们来查询四川省下面的各市、区、县(明显的层次关系)
先建立一个表用来存储数据:
create table areas(
id int unsigned primary key auto_increment,
aid int(10),
diqu varchar(10),
pid int(10)
)
插入数据:
insert into areas(id,aid,diqu,pid) values(0,1,'四川省',null);
insert into areas(id,aid,diqu,pid) values(0,2,'绵阳市',1);
insert into areas(id,aid,diqu,pid) values(0,3,'成都市',1);
insert into areas(id,aid,diqu,pid) values(0,4,'泸州市',1);
insert into areas(id,aid,diqu,pid) values(0,5,'自贡市',1);
insert into areas(id,aid,diqu,pid) values(0,6,'三台县',2);
insert into areas(id,aid,diqu,pid) values(0,7,'游仙区',2);
insert into areas(id,aid,diqu,pid) values(0,8,'梓潼县',2);
insert into areas(id,aid,diqu,pid) values(0,9,'武侯区',3);
insert into areas(id,aid,diqu,pid) values(0,10,'郫都区',3);
insert into areas(id,aid,diqu,pid) values(0,11,'新都区',3);
insert into areas(id,aid,diqu,pid) values(0,12,'锦江区',3);
insert into areas(id,aid,diqu,pid) values(0,13,'贡井区',5);
insert into areas(id,aid,diqu,pid) values(0,14,'荣县',5);
insert into areas(id,aid,diqu,pid) values(0,15,'泸县',4);
insert into areas(id,aid,diqu,pid) values(0,16,'合江县',4);
创建表结果:
进行自关联查询:
查询四川省下所有的市区县:
select *from areas as sheng, areas as shi,areas as qu
where sheng.aid=shi.pid and qu.pid=shi.aid
and sheng.diqu='四川省'
或者:用内连接进行查询
select *from areas as sheng
inner join areas as shi on sheng.aid=shi.pid
inner join areas as qu on shi.aid=qu.pid
结果:
查询四川省下的所有市:
select *from areas as sheng,areas as shi
where sheng.aid=shi.pid and sheng.diqu=’四川省’
结果:
标准子查询:
还是以这三个表为例:student、course、score
先查询年龄最小学生的年龄是多少?
select min(age) from student
然后,查询年龄在15岁的学生的所有信息?
select *from student where age=12
合并起来就是子查询了:
select *from student where age=(select min(age) from student)
其实这里所谓的子查询就是:在查询语句中嵌套查询语句。
又如:
查询大于平均年龄的学生的信息:
select *from student where age>(select avg(age) from student student)
查询李白的成绩,其他信息不显示,只显示李白的成绩:
select score from score where stuno=(select stuno from student where name='李白')
现在要求查询李白的成绩,同时显示出姓名和成绩:
select name,score from student
inner join score on score.stuno=student.stuno
where student.name=’李白’
表级子查询:
表级子查询实际上就是将子查询的结果当做一个表来提供给主查询进行查询。 如:
查询语文和数学的课程成绩
select *from score
inner join (select *from course where name='语文' or name='数学') as sc on sc.courseno=score.courseno
原本join后面应该接一个表的,在这里将(select *from course where name='语文' or name='数学')当做一个表。
1、查询学生的平均年龄,并保留两位小数。
select round(avg(age),2)from student
注:round()函数是来求保留小数的,后面的2就代表保留两位小数。(后面在介绍常用函数)
2、查询大于等于平均年龄的学生,并按照年龄大小降序排序。(一直平均年龄为15)
select name,age from (select name,age from student where age>=(select avg(age) from student)) as c order by age desc
或者:select *from student where age>=(select round(avg(age),2) from student) order by age desc
表级查询之间的关键字:
现在要求显示年龄在18~22岁的学生全部信息:
(1):select *from student where age in(18,19,20,21,22)
(2):select *from student where age =any(select age from student where age between 18 and 22)
(3):select *from student where age =some(select age from student where age between 18 and 22)
注:>any 大于里面任意的一个……
其中some和any都可以搭配=、>、<、!=符号使用,但是in不能搭配这些符号使用,但是in前面可以使用not。all一般都只搭配大于、小于符号使用,all总体使用的不频繁。
本文结合自身经历仅涉及到测试人员常用到的SQL语句,因篇幅较长,耗时较短,可能涉及错误,欢迎指正。数据库其余相关知识后面学习好了再笔记。
——————————————————————————————————————————
本文完结!