前言
先前讲了软件主要是前端的用户界面和后端的服务端数据库占主要,那么学习数据库的基础知识就非常有必要。我们至少需要知道什么是数据库,能够了解不同类型的数据库及名称,知道关系型数据库的核心要素,能够通过工具去连接mysql数据库进行操作,最后也要具备一定的sql查询语句执行能力。
其实软件测试在数据库中要做的最基本的就会死对数据进行校验查询,至于数据的清除和准备一般交由研发根据需求出发设计,而性能测试则要结合后续的JMeter工具才可展开。
还是一样,在记录学习内容的过程中,如果有出现知识点错误或者概念表述不准确的,麻烦各位大佬指正,谢谢!
1.数据库简介
1.1数据库存储阶段发展
第一个阶段:人工管理阶段,方式:结绳/甲骨文/纸,特点:不方便管理和查询
第二个阶段:文件系统阶段,方式:各种文件,特点:查询不方便
第三个阶段:数据库阶段,方式:有组织的数据集合,特点:方便维护管理和查询
数据库:是指长期存储在计算机内,有组织的数据集合。简而言之,数据库就是一个存储数据的地方。
1.2数据库分类 - 关系型数据库(重点)
RDMS:(Relational Database Management System)关系型数据库系统。
将数据见的关系以数据库表的形式加以表达,并将数据存储在表格中, 以便于查询。
常用关系型数据库:
Oracle:在大型项目中使用,例如:银行/电信等项目
MySQL:Web项目中使用最广泛的关系型数据库
Microsoft SQL Server:在微软的项目中使用
SQLite:轻量级数据库,主要应用在移动平台
大家肯定会好奇,什么是关系型数据库?他是一种以表格形式展示(是不是像在Excel表格里设计的)的数据库,如下图:
1.3数据库分类 - 非关系型数据库(知道)
NoSQL(not only sql) 非关系型数据库
常见非关系型数据库:
Redis
Mongodb
Hbase
那么非关系型行数据库呢,它是以 键-值对(大家是不是觉得像json文件格式) 方式展示,如下图:
1.4关系型数据库核心要素(重点)
核心要素(结合Excel表格来理解):
数据行(一条记录) --相当于Excel表格中的一行数据
数据列(字段) -- 相当于Excel表格中的一列数据
数据表(数据行的集合) -- Excel表格中某个表
数据库(数据表的集合,一个数据库中能够有n 多个数据表) -- 相当于所有表的集合
:
SQL的分类:SQL是一个结构化的查询语言,通过SQL能够对数据库进行相关的操作
DQL:数据查询语言,用于对数据进行查询,例如:select
DML:数据操作语言,对数据进行增加/修改/删除,例如:insert/updata/delete
TPL:事务处理语言,对食物进行处理,例如:begin transaction/commit/rollback
DCL:数据控制语言,进行授权与权限回收,例如:grant/revoke
DDL:数据定义语言,进行数据库/表的管理等,例如:create/drop
CCL:指针控制语言,通过控制指针完成表的操作,例如:declare cursor
2.MySQL
2.1MySQL简介(了解)
mysql是oracle公司的产品
社区版开源免费,商业版本收费
特点:
1.可移植性好
2.支持多操作系统
3.支持多种编程语言
4.开源/社区版免费
5.支持多线程
6.优化SQL查询算法
7.多种数据库连接方式
8.支持多语言编码格式
2.2MySQL组成和命令连接数据库(了解)
MySQL组成:
MySQL服务器:存储数据并解析编译后的SQL语句,将执行结果返回给客户端
MySQL客户端:下发用户要执行的SQL语句,并显示服务器返回的执行结果
很显然,我们是使用者是只能通过客户端来进行操作,让语句交由服务器再返回处理结果让我们看到,因此我们就需要在客户端上对服务器进行连接来下发执行命令的操作。
MySQL连接 - 命令行模式
注意:
MySQL服务器安装完成之后,默认就已经安装了命令行客户端
在连接MySQL服务器之前需要知道MySQL服务器的IP地址及对应的端口(默认3306)
Windows服务器可以通过ipconfig查看ip地址,Linux中可以通过ifconfig查看IP地址,通过netstat -anptu | grep 3306来确认mysql数据库服务是否开启,这个在上一篇学习博客里的Linux指令里面有讲过。
连接命令:mysql -h host -u 用户名 -p 密码 -P 端口号
说明:host表示服务器的IP地址或者域名,不填则表示为本机。 -P端口号 不加时则表示默认3306端口
当然了,这个命令看起来就很麻烦,本来我们软件测试就是能把复杂问题简单化处理就是最好的,如果能用工具来解决为什么还要用代码呢?我们很显然是有更合适的工具,并且是可视化。
2.3MySQL连接 -- 工具连接
说明:MySQL客户端工具有很多种,navicat用的比较多,还有mysql worbench
这里的数据库是我用centos系统模拟的,这里直接去连接服务器即可。
2.Navicat操作数据库(多以截图详细按步操作)
2.1数据库的操作
我们经常听到对数据库的操作就是”增删改查“,严格来讲其实并不是对于数据“库”的操作,而是后面对数据库中数据表里的数据。那么对于navicat来说对数据“库”具体是哪些操作呢?,如下图所示,便是按照操作步骤按部就班来执行数据库的操作
在navicat中新建数据库操作截图:
在navicat中编辑或者修改数据库操作截图和刷新:
2.2数据表的操作
新建表的操作:
修改/删除表的操作:
2.3通过navicat操作数据
一般就是新增数据/修改数据/删除数据这三个常用的操作。看下图在navicat里的操作验证:
2.4数据类型与约束
如果大学就是相关专业出身的同学或者朋友,可能对于数据类型比较敏感,因为在基础的编程语言最开始初始化的过程里数据的类型就是很重要的。那么我们常见的数据类型有哪些呢?
2.4.1数据类型
有如下图所示的数据类型:int(整型),如名词所示就是整数;decimal(小数),整数后带小数的,而小数类型就是示例中的decimal(5,2)括号中前者表示数字中总共几位后者表示小数的位数,就像这里是2位小数和3位整数;这里面的varchar其实就是(字符串),一般字符串就是字母符号或者中文;而datetime(时间日期)比较少用到,格式就如表里所示。
2.4.2数据约束
这里的数据约束其实就是上面提到过的以表格形式存在的关系型数据库中的一种定义,这个定义就是为了限制表里的数据,通过对表里数据的形式规定能够让它们更加的准确和可靠。我尽量通过简单明了的语言来描述清楚常见的约束。
常见的约束有以下:
主键(primary key):物理上存储的顺序
当把某个字段设定为主键之后,该字段的值 必须唯一,且不能为空
针对主键的字段,可以设定 自动自增,自动在原来最大的ID值上加1
非空:此字段不允许填写空值
空(Null) 和 ‘ ’ 空字符是不一样的
唯一(unique):此字段的值不允许重复
主键只能有1个
唯一的字段可以是多个,例如下面的t_book表,id是唯一对应的主键,它只有一个,不会有多个id。但是唯一键有很多,例如title/read。
默认值(default):当不填写此值时会使用默认值,如果填写时以填写为准
外键(foreign key):维护两个表之间的关联关系
2.4.3数据库的备份和还原
我们对一个文件执行修改编辑的操作之后,都会进行保存备份,防止上一版本的修改遗失。 而数据库的存储也是一样的,我们在navicat工具当中能够可视化的去找到转储SQL文件的命令,如下图所示:
在点击这个结构和数据之后,能够让你自己选择你想把文件保存的路径,之后保存成功会有以下的弹窗:
那么,当我们想要对数据库进行还原的时候(也就是把上面保存下来的数据库导入)该怎么做呢?
首先,如果要还原的数据库不存在(被误删)时,需要我们去先创建一个数据库 。这时候,我们手动把数据库中的表删除(模拟表数据误删)
上面说了数据库里的表数据被误删后,我们选择通过重新导入整个数据库的数据将数据库中的表数据还原。之后对表中的数据进行刷新即可显示原来的数据。
3.命令行客户端
3.1命令行操作数据库
前置条件:
需要先使用命令行去连接数据库: mysql - u root -p 123456
常见数据库操作命令:
查看所有数据库:show databases;
使用数据库:use 数据库名;
查看当前使用数据库:select database();
创建数据库:create database 数据库名 charset = utf8; (这里不是utf-8)
删除数据库: drop database 数据库名;
先用命令行去连接数据库,然后使用对应的数据库操作命令来进行操作,比如查看数据库 show databases; 这样的语句也是比较好理解,database数据库,这里要改成复数的形式。再查看当前使用的数据库,有编程功底的人就会知道要用方法(),那么再配合上类似数据库的关键词语句就是 select database();创建和删除的区别除了关键词不同一个是create 一个是 drop之外,在创建数据库的时候新建的数据库名 后面还需要跟上 charset =utf8,也就是对格式的限制。
底下的图示就是查看数据库后显示出来的数据内容。
3.2命令行操作数据库表
前置条件:
操作数据表之前要先通过use打开对应的数据库
常见数据表操作命令:
查看当前数据库所有的表:show tables;
查看表结构:desc 表名
查看表的创建语句:show create table 表名;
4.SQL语句
因为我们不需要去用专门的SQL软件去执行SQL语句,我们可以在navicat上面就能够很好的使用简易的SQL语法语句。
如下图,我们在数据库表里右键通过新建查询就能模拟出来执行数据库语句的环境
4.1数据库表操作(知道即可)
因为,我们作为测试人员其实不怎么会去动到数据库表,多是对表中的数据进行操作,该部分对于表操作的知识点知道即可。
首先,我们还是和上面学习navicat一样的流程,先来学习SQL语句对数据库表的操作,如下图所示:同样是create table 表名();的格式来进行创建
通过创建一个学生表的形式,我们就可以比较直观的体会到对数据库表的SQL语句执行了。
首先,根据我们上面说过的依赖型的数据库是类似Excel表格那样的形式,然后再利用下面建立SQL数据库表的语句即可生成这样的表。
同理,删除的操作命令和上面在终端里执行的语句是相似的,使用drop table students;
或者使用 drop table if exists students;完整的创建和删除表的SQL语句,我在下面的截图里写出来了:
4.2数据操作(重点)
4.2.1简单查询
select * from 表名;
select * from students ;
还记得 这个 * 的意思吗,前面Linux语句里有提到过的,通配符代表0个或多个字符,在数据库里则是代表所有的字段及其记录,也就是说这个表里所有的信息都会出来,这也是一条最基本的查询语句,后续我们很多有细节的查询语句会由这条语句演变出来。记得; 一定要加上
4.2.2添加一行数据(重点)
说明:前面提到过的主键自增长,可以用0或null代替
方式1:insert into 表名 values(...)
ex: insert into students values (0,'亚瑟',22,177,56)
方式2:insert into 表名(字段1,字段2,...) value(值1,值2,...)
ex:insert into students (name,age) values ('老夫子',22)
4.2.3添加多行数据
方式1:写多条insert语句,多条语句之间用英文分号分隔
方式2:通过一条insert 语句插入多条数据,数据间用逗号分隔
4.2.4修改数据 (知道)
update 表名 set 字段名1 = 值1, 字段名2 = 值2... ... where 条件
例子:修改id为 5 的数据,将名称设为测试人, 年龄设为 24
在这里id=5 就是条件
update students set name = '测试人',age = 22 where id = 5
注意:修改数据时一定要加条件,否则修改的是所有记录的值
4.2.5删除数据(知道)
delete from 表名 where 条件 (物理删除对应的数据)
注意:此方法为无力删除,工作中大部分使用逻辑删除
逻辑删除是指通过设定一个字段来表示当前记录已经删除
is_delete 字段来表示,1代表删除,0表示未删除,例如下图:
当然,SQL语句方法多,还有其他的删除数据的方式如下图说的truncate和drop,均是对表里的数据直接操作,不过drop的效率明显会比较高,就像前面说的新建表和删除表那样事包括对数据和表结构一起删除的。而truncate则是清空表里的数据。
4.3数据查询操作(重点)
4.3.1数据准备
这里,找了一些网上的数据来为了我们后面能够进行数据查询做准备,直接使用下面的语句相当于去新建一个表。
按上面的语句执行后,就有如下可视化的表数据内容出现。
4.3.2查询基本操作
查询部分字段的值
select 字段1,字段2... from 表名 (查询的为一部分的字段的信息)
例如去查询学生表中的姓名/性别/年龄的数据
select name,sex,age from students;
取别名(知道即可)--为后面表的关联查询做铺垫
select 别名.字段名1, 别名.字段名2 ...... from 表名 as 别名
例如:select s.name, s.sex from students as s;
去重
select distinct 字段名1,字段名2... from 表名
例如:根据学生的性别去重
select distinct sex from students;
4.4条件查询(重点)
语法格式:select 字段名1 , 字段名2... from 表名 where 条件
例如:select name , age from students where id =5 ;
4.4.1条件查询:比较运算符
比较运算符,其实就是常见的大于小于等于之类的比如(>)(<=)(!=) !=之间不能有空格
例子1:查询20岁以下的学生
select * from students where age < 20;
例子2:查询家乡不在北京的学生
select * from students where hometown != '北京';
例子3:查询学号是'007'的学生的身份证号
select * from students where studentNo = '007' ;
4.4.2条件查询:逻辑运算符
逻辑运算符,这里的就是常见的“且或非”:
and(且,同时符合对应的条件)
or(或,符合其中的一个条件)
not(非,不符合该条件)
例子1:查询年龄等于18的女生的记录(and)
select * from students where age =18 and sex ='女';
例子2:查询女学生或者是1班的学生
select * from students where sex='女' or class ='1班';
例子3:查询非天津学生
select * from students where hometown !='天津';
select * from students where not hometown = '天津';
4.4.3条件查询:模糊查询
模糊查询关键字:like
%:匹配任意个字符
_:匹配任意单个字符
一般LIKE关键字只用来匹配字段类型为字符串的
例子1: 查询姓孙的学生
select * from students where name like '孙%';
例子2: 查询姓孙且名字是一个字的学生
select * from students where name like '孙_';
例子3:查询姓名以‘乔’结尾的学生
select * from students where name like '%乔';
例子4:查询姓名中包含‘白’的学生
select * from students where name like '%白%';
例子5:查询姓名为两个字的学生
select * from students where name like '__';
例子6:查询姓王且年龄大于20的学生
select * from students where name like '王%' and age > 20;
例子7:查询学号以1结尾的学生
select * from students where studentNo like '%1';
4.4.4条件查询:范围查询
in:查询非连续范围内的数据
例子1:查询家乡为北京或上海或广东的学生
select * from students where hometown in (‘北京’,'广东','上海')
或者 select * from students where hometown='北京' or hometown='上海' or hometown ='广东';
between... and:查询连续范围内的数据(用来数值型字段中)有包含边界值
例子:查询年龄在18到20之间的学生
select * from students where age between 18 and 20;
或者 select * from students where age >=18 and age <= 20
例子:查询年龄为18或19或22的女生
select * from student where age in (18,19,22) and sex ='女';
例子:查询年龄在20到25以外的学生
select * from students age not between 20 and 25;
4.4.5条件查询:为空判断
null 和 ' ' 空字符串不一样
空判断:is null
例子:查询学生身份证为空的信息
select * from students where card is null;
非空判断: is not null
例子:查询出学生身份证不为空的信息
select * from students where card is not null;
4.5排序
语法格式:select * from 表名 order by 字段1 asc | desc,字段2 asc | desc.......
字段的排序规则默认为升顺排列(从小到大)
asc:表示从小到大排序(升序)
desc:表示从大到小排序(降序)
例子1:查询所有学生信息,按年龄从小到大排序
select * from students order by age;
例子2:查询所有学生信息,按年龄从大到小排序,年龄相同时,再按学号从小到大排序
select * from students order by age desc ,studentNo asc;
4.6聚合和分组
4.6.1聚合函数介绍
使用聚合函数方便进行数据统计,但是聚合函数不能在where中使用
常见的聚合函数有:
count():查询总记录数
max(字段名):查询最大值
min(字段名):查询最小值
sum(字段名):求和
avg(字段名):求平均数
4.6.2聚合函数
count(*):求表的总的记录数(这里的记录数就是上面说的行数,有几行就是几条记录,顺便回忆一下字段指的是id,name,age,sex这样的名称)
select count(*) from students; 如果在navicat里对上面建立的数据表中的数据进行新建查询结果运行后的结果就是12。
换成 select count (name) from students; 最后的运算结果也是12.
max(字段名):查询对应字段的最大值
例如查询女生的最大年龄:(这里女生就可以作为条件查询)
select max(age) from students where sex ='女';
min(字段名):查询对应字段的最小值
例如查询男生的最小年龄:
select min(age) from students where sex = '男';
sum(字段名):查询对应字段的值的总和
例如 查询北京学生的年龄总和
select sum(age) from students where hometown = '北京';
avg(字段名):查询对应字段的值的平均数
例如 查询女生的平均年龄
select avg(age) from students where sex = '女';
聚合函数综合案例
例1:查询二班有多少人
select count(*) from students where class ='2班';
例2:查询3班年龄小于18岁的有多少人
select count(*) from students where age < 18 and class = '3班';
4.6.4分组查询(知道)
分组的目的是对每一组的数据进行统计(使用聚合函数) 首先这个字段的参数要有多个
语法格式:
select 字段名1,字段名2,聚合函数... from 表名 group by 字段名1,字段名2 ...
例子1:查询各种性别的个数
select sex count(*) from students group by sex;
例子2:查询各个班级的人数
select class count (*) from students group by count;
例子3:查询各个班级中不同性别的人数
select class,sex,count(*) from students group by class,sex;
学会使用聚合函数对数据进行分组处理后,还能再对分组后的数据进行筛选,将分组后的数据当成是一个表数据,然后再通过having 条件 来对 当前的表数据进行筛选。
语法格式:
select 字段名1,字段名2,聚合函数... from 表名 group by 字段名1,字段名2...
having 条件
这里的having条件,运算符跟where 条件运算符是一样的
在having后面可以使用聚合函数
例子:查询男生总人数
select count(*) from students where sex ='男';
select sex,count(*) from students group by sex having sex = '男';
例子:查询所有班级中不同性别的记录数大于1的信息
select sex,class count(*) from students group by sex,class having count(*) > 1;
这里将所有的数据按照性别和班级进行分组具体图示可见上面,使用关键词having进行条件查询显示出上述分组中大于2的记录数。
对于where和having的区别:
where是对 from 后面指定的表进行数据筛选,属于对原始数据的筛选
having 是对 group by 的结果 进行筛选
having 后面的条件中可以用聚合函数,where 后面不可以
4.6.5分页查询(知道)
语法格式:
select * from limit start , count
这里的start 表示的 是开始的记录,索引是从0开始。 0 表示第一条记录
count 表示的是 从 start 开始, 查询多少条记录
不如分组重要,了解即可
例子:查询前3行的学生信息
select * from limit 0 , 3;
select * from limit 3;
分页查询实现:
select * from students limit (n-1)*m, m ;
n表示的是页数
n =1,2,3,4
m表示的是每页显示的记录数
m = 3
(n-1)*m,m是公式,并不是语法格式,不能直接写在SQL语句中,需要替换为具体的数字
4.7连接查询(重要)
4.7.1连接查询概述
内连接:连接两个表时,取的是两个表中都存在的数据。(取交集)
左连接:连接两个表时,取的是左表中特有的数据,对于右表中不存在的数据,用null来填充。
右连接:连接两个表时,取的是右表中特有的数据,对于左表中不存在的数据,用null来填充。
内连接:连接两个表时,取的是两个表中都存在的数据(交集),如下图:
左连接:连接两个表时,取的是左表中特有的数据,对于右表中不存在的数据,用null来填充
右连接,连接两个表时,取的是右表中特有的数据,对于左表中不存在的数据,用null来填充
4.7.2 内连接(重点)
语法格式: 关键字inner join 和 on
select * from 表名1 inner join 表名2 on 表名1.列 = 表名2.列;
查询的是两个表的交集的数据
表1的列与 表2的列一定是存在关联关系
内连接连接时可以连接多个表
回忆上面说到的给表取别名的用法
select 别名.字段名1, 别名.字段名2 ...... from 表名 as 别名
让表.列这样的组合更简洁,结合起来语法格式如下:
select * from 表名1 别名1 inner join 表名2 别名2 on 别名1.字段 = 别名2.字段;
例如查询学生信息及学生的成绩,一般信息会在自己的表里然后信息和学生成绩存在关联,即可以使用内连接,下面的语句就是将students表取别名为stu,scores表取别名为sc,找到关联的字段studentNo(在表关联取别名之时可以不用写as)
select * from students as stu inner join scores as sc on stu.studentNo = sc.studentNo;
也可以内连接关联多个表:前提是关联的每个表里都有对应的字段名是共同的,例如查询学生信息及学生的课程对应的成绩:
select * from students stu inner join scores sc on stu.studentNo = sc.studentNo
综合例子:查询男生中最高成绩,要求显示姓名,课程名,成绩
select student.name,courses.name,score.score from students stu
inner join scores sc on stu.studentsNo = sc.studentsNo
inner join coureses co on sc.courseNo = co.courseNo
where sex = '男' //查询男生的条件
order by sc.score desc // 从小到大排序
limit 0,1 // 按页分组
4.7.3左连接(知道即可)
语法格式:
select * from 表1 left join 表2 on 表1.列 = 表2.列
左连接查询的是左表特有的数据,对于右表中不存在的数据用null来填充
案例:
查询所有学生的成绩,包括没有成绩的学生
select * from student as stu left join scores sc on stu.studentNo = sc.studentNo
4.7.4右连接(知道)
语法格式:
select * from 表1 right join 表2 on 表1.列 = 表2.列
右连接查询的是右表特有的数据,对于左表中不存在的数据用null来填充
例子还是可以举上面说的查询所有学生的成绩,包括没有成绩的学生,那么这时候我们的左表就换成了scores分数表,右表是学生信息表
4.8自关联
4.8.1自关联的数据准备
下图为自关联的数据准备,自关联的应用场景类似像省市区的信息,都不会分开放在不同的表里面进行存储,而是放在同一个表当中
4.8.2自关联实现
要通过自关联进行查询时,当前自关联的表当中一定会存在两个相关联的字段
自关联要用别名(所以先前在连接查询那里我基本写的语句都是带着别名的)
语法格式:
select * from 表名 as 别名1 inner join 表名 as 别名2 on 别名1.列 = 别名2.列
案例:
查询出河南省所有的市
select * from areas as a1 inner join areas as a2 on a1.aid = a2.pid where a1.atitle=‘河南省’;
查询洛阳市所有的区的信息
select * from areas as 1 inner join areas as a2 on a1.aid= a2.pid where a1.attile='洛阳市';
4.8.3子查询
将一条SQL查询的语句嵌入在其他的SQL语句中,被嵌入的SQL语句称之为子查询,其他的SQL称之为主查询
子查询select语句,要么是充当条件,要么充当数据源
子查询语句是一条完整的select语句,且可以单独执行
另外,子查询特有的关键字主要是in 和 all,in后面的括号里跟的是查询的条件,例如下面的案例查询学生的成绩,这里对学生的限定是有条件的,一个是18岁且在学生表中,故在查找成绩表之后就会有一条子查询。当然像上面说的子查询语句一般是充当条件的,所以当我们第一条查询学生成绩的条件是根据学生表和成绩表中关联的studentNo字段进行条件的联动,后面括号内的子查询就是充当数据源作为主查询的条件。
案例:查询18岁的学生的成绩,要求显示成绩(列子查询)
select studentNo from students where age =18;
select score from scores where studentNo in (select studentNo from students where age=18);
子查询属于是比较细化的查询,一般多用于程序员自查过程,而我们通过navicat的远程连接也能很直接的进行查找,在有需要的时候再进行细化语句的调用即可,掌握上面其他查询形式即可应对基本的数据库数据的“增删改查”。
5.总结
经过对navicat和数据库基本的增删改查语句的学习,大体上会对数据库的整体有个了解了,再结合先前说过的Linux系统的相关知识点,会发现都是针对关键字进行记忆,而关键字都是由单词直译而来让人好理解其作用,不论是SQL的语句或者是数据库的命令都是依据一定的逻辑,当然除了要眼熟这些最最最常见的指令,还是要靠多敲多应用才会更加得心应手。
一篇博客并不能很细致的描绘所有在测试需要的东西,好多细节部分以及会用到的东西并没有提到或者体现出来,如果在实践当中碰到了,要不断的去养成记录的习惯,这才是我们学习的作用和目的。