学于黑马和传智播客联合做的教学项目 感谢

黑马官网

传智播客官网

微信搜索"艺术行者",关注并回复关键词"软件测试"获取视频和教程资料!

b站在线视频

软件测试为什么要学习数据库知识

测试工程师的目的是找出软件的不足,并告诉开发工程师,出现问题的环境,操作步骤和输入输出的数据。而优秀的测试工程师,当测出问题后,还可以告诉开发团队,问题的原因和解决方案。

这就要求测试工程师除了会测试,还需要知道开发相关的知识,其中非常重要的就是数据库,因为绝大多数的软件都跟数据紧密相关,比如微博、论坛、新闻、商城等,这些软件都在不停的操作数据,而它们的数据大部分都是存储在数据库中,开发人员的一大部分工作就是在搬迁数据:把数据库中的数据显示到软件中;把用户输入的数据保存到数据库中。

测试工程师在测试软件的过程中,不仅需要在界面上操作,还需要检查数据库中的数据是否正确。从而在软件出问题时,能够定位问题的原因。

比如测试注册登录功能,在输入了注册信息后,提示注册成功,但是使用刚才注册的信息登录不成功。这时需要检查数据库中是否保存了正确的注册信息,如果数据库中没有保存数据,那么使用刚才注册的账号肯定登录不了,这样就能定位问题:注册时,没有把数据存储起来。

数据库知识点

1 基本概念

  • 数据库是什么
  • RDBMS
  • SQL
  • MySQL

此部分为理论知识,需要了解

1 数据库是什么

数据存储

1、人工管理阶段

  • 结绳记事
  • 甲骨

人工管理阶段,数据都是靠人工进行整理和保存,使用起来很不方便。不便于查询、共享、保存。

2、文件系统阶段

  • 磁盘

文件系统阶段,将数据存储在磁盘上,数据都是以文件的形式出现,通过文件系统管理。相对于人工管理方便的多,但是在查询数据内容时,还不是很方便

3、数据库系统阶段

  • 数据库

数据库是指长期存储在计算机内、有组织的数据集合。简而言之,数据库就是一个存储数据的地方。表示数据库中存储数据的基本单位,数据按照分类存储到不同的表中,能够非常高效的查询其中的数据。

2 关系型数据库管理系统(RDBMS)

Relational Database Management System

关系型数据库系统

通过表来表示关系

  • 当前主要使用两种类型的数据库:关系型数据库、非关系型数据库,我们主要学习主流的关系型数据库

  • 所谓的关系型数据库RDBMS,是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数据库中的数据

  • 查看数据库排名:https://db-engines.com/en/ranking

  • 关系型数据库的主要产品:

    • oracle:在以前的大型项目中使用,银行,电信等项目
    • mysql:web时代使用最广泛的关系型数据库
    • ms sql server:在微软的项目中使用
    • sqlite:轻量级数据库,主要应用在移动平台

关系型数据库核心元素

  • 数据行(一条记录)
  • 数据列(字段)
  • 数据表(数据行的集合)
  • 数据库(数据表的集合,一个数据库中能够有 n 多个数据表)

3 SQL

Structured Query Language

结构化查询语言

在数据库中进行操作的语言,称为sql,结构化查询语言,当前关系型数据库都支持使用sql语言进行操作,也就是说可以通过 sql 操作 oracle,sql server,mysql,sqlite 等等所有的关系型的数据库

  • sql语言主要分为:

    • DQL:数据查询语言,用于对数据进行查询,如select
    • DML:数据操作语言,对数据进行增加、修改、删除,如insert、udpate、delete
    • TPL:事务处理语言,对事务进行处理,包括begin transaction、commit、rollback
    • DCL:数据控制语言,进行授权与权限回收,如grant、revoke
    • DDL:数据定义语言,进行数据库、表的管理等,如create、drop
    • CCL:指针控制语言,通过控制指针完成表的操作,如declare cursor
  • 对于测试工程师来讲,重点是数据的查询,需要熟练编写DQL,其它语言如TPL、DCL、CCL了解即可
  • SQL 是一门特殊的语言,专门用来操作关系数据库
  • 不区分大小写

4 MySQL 简介

MySQL官方网站:https://www.mysql.com/

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,后来被Sun公司收购,Sun公司后来又被Oracle公司收购,目前属于Oracle旗下产品

特点

  • 使用C和C++编写,并使用了多种编译器进行测试,保证源代码的可移植性
  • 支持多种操作系统,如Linux、Windows、AIX、FreeBSD、HP-UX、MacOS、NovellNetware、OpenBSD、OS/2 Wrap、Solaris等
  • 为多种编程语言提供了API,如C、C++、Python、Java、Perl、PHP、Eiffel、Ruby等
  • 支持多线程,充分利用CPU资源
  • 优化的SQL查询算法,有效地提高查询速度
  • 提供多语言支持,常见的编码如GB2312、BIG5、UTF8
  • 提供TCP/IP、ODBC和JDBC等多种数据库连接途径
  • 提供用于管理、检查、优化数据库操作的管理工具
  • 大型的数据库。可以处理拥有上千万条记录的大型数据库
  • 支持多种存储引擎
  • MySQL 软件采用了双授权政策,它分为社区版和商业版,由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型网站的开发都选择MySQL作为网站数据库
  • MySQL使用标准的SQL数据语言形式
  • Mysql是可以定制的,采用了GPL协议,你可以修改源码来开发自己的Mysql系统
  • 在线DDL更改功能
  • 复制全局事务标识
  • 复制无崩溃从机
  • 复制多线程从机
  • 开源 免费 使用范围广 支持多平台
  • 是学习数据库开发的首选

2 SQL语言

1 数据类型与约束

为了更加准确的存储数据,保证数据的正确有效,需要合理的使用数据类型和约束来限制数据的存储。

常用数据类型

  • 整数:int,有符号范围(-2147483648 ~2147483647),无符号范围(0 ~ 4294967295)
  • 小数:decimal,如decimal(5,2)表示共存5位数,小数占2位,整数占3位
  • 字符串:varchar,范围(0~65533),如varchar(3)表示最多存3个字符,一个中文或一个字母都占一个字符
  • 日期时间: datetime,范围(1000-01-01 00:00:00 ~ 9999-12-31 23:59:59),如'2020-01-01 12:29:59'

约束

  • 主键(primary key):物理上存储的顺序
  • 非空(not null):此字段不允许填写空值
  • 惟一(unique):此字段的值不允许重复
  • 默认值(default):当不填写此值时会使用默认值,如果填写时以填写为准
  • 外键(foreign key):维护两个表之间的关联关系

2 数据表操作

创建表

create table 表名(
字段名 类型 约束,
字段名 类型 约束
...
)

例:创建学生表,字段要求如下:姓名(长度为10),年龄,身高(保留小数点2位)

create table students(
id int unsigned primary key auto_increment,
name varchar(20),
age int unsigned,
height decimal(5, 2)
)

删除表

格式一:
drop table 表名
格式而:
drop table if exists 表名

例:删除学生表

drop table students

drop table if exists students

3 数据操作-增删改查

简单查询

select * from 表名
例:查询所有学生数据
select * from students

添加数据

添加一行数据

格式一:所有字段设置值,值的顺序与表中字段的顺序对应
说明:主键列是自动增长,插入时需要占位,通常使用 0 或者 default 或者 null 来占位,插入成功后以实际数据为准
insert into 表名 values(...)

例:插入一个学生,设置所有字段的信息

insert into students values(0, '亚瑟', 22, 177.56 )
格式二:部分字段设置值,值的顺序与给出的字段顺序对应
insert into 表名(字段1,...) values(值1,...)

例:插入一个学生,只设置姓名

insert into students(name) values('老夫子')

添加多行数据

方式一:写多条insert语句,语句之间用英文分号隔开

insert into students(name) values('hello');
insert into students(name) values('world');
insert into students values(0,'world2',23,167.56)

方式二:写一条insert语句,设置多条数据,数据之间用英文逗号隔开

格式一:insert into 表名 values(...),(...)...
例:插入多个学生,设置所有字段的信息
insert into students values(0,'亚瑟3',23,167.56),(0,'亚瑟4',23,167.56)
格式二:insert into 表名(列1,...) values(值1,...),(值1,...)...
例:插入多个学生,只设置姓名
insert into students(name) values('老夫子5'),('老夫子6')

修改

格式:update 表名 set 列1=值1,列2=值2... where 条件

例:修改id为5的学生数据,姓名改为hello,年龄改为20

update students set name='hello',age=20 where id=5

删除

格式:delete from 表名 where 条件

例:删除id为6的学生数据

delete from students where id=6

逻辑删除:对于重要的数据,不能轻易执行delete语句进行删除,一旦删除,数据无法恢复,这时可以进行逻辑删除。

1、给表添加字段,代表数据是否删除,一般起名isdelete,0代表未删除,1代表删除,默认值为0

2、当要删除某条数据时,只需要设置这条数据的isdelete字段为1

3、以后在查询数据时,只查询出isdelete为0的数据

例:
1. 给学生表添加字段(isdelete),默认值为0,如果表中已经有数据,需要把所有数据的isdelete字段更新为0
update students set isdelete=0
2. 删除id为1的学生
update students set isdelete=1 where id=1
3. 查询未删除的数据
select * from students where isdelete=0

4 数据操作-查询

查询所有字段

select * from 表名
例:
select * from students

查询指定字段

在select后面的列名部分,可以使用as为列起别名,这个别名出现在结果集中
select 列1,列2,... from 表名
-- 表名.字段名
select students.name,students.age from students
-- 可以通过as给表起别名
select s.name,s.age from students as s
-- 如果视单表查询 可以省略表名
select name,age from students
-- 使用as给字段起别名
select studentNo as 学号,name as 名字,sex as 性别 from students

消除重复行

在select后面列前使用distinct可以消除重复的行
select distinct 列1,... from 表名;
例:
select distinct sex from students;

条件

使用where子句对表中的数据筛选,符号条件的数据会出现在结果集中

语法如下:

select 字段1,字段2... from 表名 where 条件;
例:
select * from students where id=1;

where后面支持多种运算符,进行条件的处理

  • 比较运算
  • 逻辑运算
  • 模糊查询
  • 范围查询
  • 空判断

比较运算符

  • 等于:=
  • 大于:>
  • 大于等于:>=
  • 小于:<
  • 小于等于:<=
  • 不等于:!=或<>

例1: 查询hello的年龄

select age from students where name='hello'

例2:查询20岁以下的学生

select * from students where age<20

例3:查询家乡不在北京的学生

select * from students where hometown!='北京'

逻辑运算符

  • and
  • or
  • not

例1:查询年龄小于20的女同学

select * from students where age<20 and sex='女'

例2:查询女学生或'1班'的学生

select * from students where sex='女' or class='1班'

例3:查询非天津的学生

select * from students where not hometown='天津'

模糊查询

  • 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 '%白%'

范围查询

in表示在一个非连续的范围内

例1: 查询家乡是北京或上海或广东的学生

select * from students where hometown in ('北京','上海','广东')

between ... and ...表示在一个连续的范围

select * from students where age between 18 and 20

空判断

例1: 查询没有填写身份证的学生

select * from students where card is null

例2: 查询填写了身份证的学生

select * from students where card is not null

排序

语法:

select * from 表名 order by 列1 asc/desc, 列2 asc/desc,...
  • 将行数据按照列1进行排序,如果某些行列1的值相同时,则按照列2排序,以此类推
  • 默认按照列值从小到大排列
  • asc从小到大排列,即升序
  • desc从大到小排序,即降序

例1: 查询所有学生信息,按年龄从小到大排序

select * from students order by age

例2:查询所有学生信息,按年龄从大到小排序,年龄相同时,再按学号从小到大排序

select * from students order by age desc, studentNo

聚合函数

  • 为了快速得到统计数据,经常会用到如下5个聚合函数
  • count(*)表示计算总行数,括号中写星与列名,结果是相同的
  • 聚合函数不能在 where 中使用

例1:查询学生总数

select count(*) from students;

max(列)表示求此列的最大值

例2:查询女生的最大年龄

select max(age) from students where sex='女';

min(列)表示求此列的最小值

例3:查询1班的最小年龄

select min(age) from students;

sum(列)表示求此列的和

例4:查询北京学生的年龄总和

select sum(age) from students where hometown='北京';

avg(列)表示求此列的平均值

例5:查询女生的平均年龄

select avg(age) from students where sex='女'

分组

  • 按照字段分组,表示此字段相同的数据会被放到一个组中
  • 分组后,分组的依据列会显示在结果集中,其他列不会显示在结果集中
  • 可以对分组后的数据进行统计,做聚合运算

语法:

select 列1,列2,集合... from 表名 group by 列1,列2...

例1:查询各种性别的人数

select sex, count(*) from students group by sex

例2:查询各种年龄的人数

select age,count(*) from students group by age

分组后的数据筛选

语法:

select 列1,列2,聚合... from 表名
group by 列1,列2,列3...
having 列1,...聚合...

havaing后面的条件运算符与where的相同

例1: 查询男生总人数

select count(*) from students where sex='男'

select sex,count(*) from students group by sex having sex=‘男’

对比where与having

where是对from后面指定的表进行数据筛选,属于对原始数据的筛选

having是对group by的结果进行筛选

获取部分行

当数据量过大时,在一页中查看数据是一件非常麻烦的事情

语法:

select * from 表名 limit start,count
# 从start开始,获取count条数据
# tart索引从0开始

例1:查询前3行学生信息

select * from student limit 0,3

分页

已知:每页显示m条数据,求:显示第n页的数据

select * from students limit (n-1)*m,m

求总页数

  • 查询总条数p1
  • 使用p1除以m得到p2
  • 如果整除则p2为总数页
  • 如果不整除则p2+1为总页数

连接查询

  • 当查询结果的列来源于多张表时,需要将多张表连接成一个大的数据集,再选择合适的列返回

  • 等值连接查询:查询的结果为两个表匹配到的数据

![image-20200712131310624](/Users/XinxingWang/Library/Application Support/typora-user-images/image-20200712131310624.png)

  • 左链接查询:查询的结果为两个表匹配到的数据加左表特有的数据,对于右表中不存在的数据使用null填充

![image-20200712131449582](/Users/XinxingWang/Library/Application Support/typora-user-images/image-20200712131449582.png)

  • 右链接查询:查询的结果为两个表匹配到的数据加右表特有的数据,对于左表中不存在的数据使用null填充

![image-20200712131553738](/Users/XinxingWang/Library/Application Support/typora-user-images/image-20200712131553738.png)

等值连接

方式一

select * from 表1,表2, where 表1.列=表2.列

方式二(又称内连接)

select * from 表1
inner join 表2 on 表1.列=表2.列

例1:查询学生信息及学生的成绩

select
*
from
students stu,
scores sc
where
stu.studentNo = sc.studentNo -------------------------------- select
*
from
students stu
inner join scores sc on stu.studentNo = sc.studentNo

例2:查询课程信息及课程的成绩

select
*
from
courses cs,
scores sc
where
cs.courseNo = sc.courseNo
----------------------------
select
*
from
course cs
inner join scores sc on cs.courseNo = sc.courseNo

例3:查询学生信息及学生的课程对应的成绩

select
*
from
students stu,
courses cs,
scores sc
where
stu.studentNo = sc.studentno
and
cs.courseNo = sc.courseNo
----------------------------
select
*
from
student stu
inner join scores sc on stu.studentNo = sc.studentNo
inner join courses cs on cs.courseNo = sc.courseNo

例4: 查询hello的成绩,要求显示姓名、课程号、成绩

select
stu.name,
stu.courseNo,
sc.score
from
students stu,
scores sc
where
stu.studentNo = sc.studentNo
and stu.name = 'hello'
--------------------------------
select
stu.name,
stu.courseNo,
sc.score
from
students stu
inner join scores sc on stu.studentNo = sc.studentNo
where
stu.name = 'hello'

例5: 查询hello的数据库成绩,要求显示姓名、课程名、成绩

select
stu.name,
stu.courseNo,
sc.score
from
students stu,
scores sc
courses cs
where
stu.studentNo = sc.studentNo
and sc.courseNo = cs.courseNo
and stu.name = 'hello'
amd cs.name = '数据库'
--------------------------------
select
stu.name,
stu.courseNo,
sc.score
from
students stu
inner join scores sc on stu.studentNo = sc.studentNo
inner join courses cs on sc.courseNo = cs.courseNo
where
stu.name = 'hello' and cs.name = '数据库'

例6:查询所有学生的数据库成绩,要求显示姓名、课程名、成绩

select
stu.name
cs.name
sc.score
from
students stu,
scores sc,
courses cs
where
stu.studentNo = sc.studentNo
and sc.courseNo = cs.courseNo
and cs.name = '数据库'
---------------------------------
select
stu.name
cs.name
sc.score
from
students stu
inner join scores sc on stu.studentNo = sc.studentNo
inner join courses cs on sc.courseNo = cs.courseNo
where
cs.name = '数据库'

例7: 查询男生中最高成绩,要求显示姓名、课程名、成绩··

select
stu.name
cs.name
sc.score
from
students stu,
scores sc,
courses cs
where
stu.studentNo = sc.studentNo
and sc.courseNo = cs.courseNo
and stu.sex = '男'
order by
sc.score desc
limit 1
----------------------------------
select
stu.name
cs.name
sc.score
from
students stu
inner join scores sc on stu.studentNo = sc.studentNo
inner join courses cs on sc.courseNo = cs.courseNo
where
stu.sex = '男'
order by
sc.score desc
limit 1

左连接

select * from 表1
left join 表2 on 表1.列=表2.列

例1: 查询所有学生的成绩,包括没有成绩的学生

select *
from
students stu
left join scores sc on stu.studentNo = sc.studentNo

例2: 查询所有学生的成绩,包括没有成绩的学生,需要显示课程名

select *
from
students stu
left join scores sc on stu.studentNo = sc.studentNo
left join courses cs on cs.courseNo = sc.courseNo

右连接

select * from 表1
right join 表2 on 表1.列=表2.列

例1:查询所有课程的成绩,包括没有成绩的课程

select *
from
scores sc
right join courses cs on cs.courseNo = sc.courseNo

例2:查询所有课程的成绩,包括没有成绩的课程,包括学生信息

select *
from
scores sc
right join courses cs on cs.courseNo = sc.courseNo
left join students stu on stu.studentNo = sc.studentNo

自关联

设计省信息的表结构provinces

  • id
  • title

设计市信息的表结构citys

  • id
  • ctitile
  • proid

citys表的proid表示城市所属的省,对应着provinces表的id值。

问题:能不能将两个表合成一张表呢?

思考:观察两张表发现,citys表比provinces表多一个列proid,其它列的类型都是一样的

意义:存储的都是地区信息,而且每种信息的数据量有限,没必要增加一个新表,或者将来还要存储区、乡镇信息,都增加新表的开销太大

答案:不使用上述两个表,直接定义一个表areas,结构如下

  • aid ------ 省/市id
  • atitle ------- 省/市的名称
  • pid ------- 省id(如果该area表示的是省,则为null)

例如:

表数据

('410000', '河南省', NULL),
('410100', '郑州市', '410000'),
('410300', '洛阳市', '410000'),
('410500', '安阳市', '410000')

因为省没有所属的省份,所以可以填写为null。

城市所属的省份pid,填写省所对应的编号aid。

这就是自关联,表中的某一列,关联了这个表中的另外一列,但是它们的业务逻辑含义是不一样的,城市信息的pid引用的是省信息的aid。

在这个表中,结构不变,可以添加区县、乡镇街道、村社区等信息。

例1:查询河南省的所有城市

select
*
from
areas as p
inner join areas as c on c.pid=p.aid
where
p.atitle='河北省';

例2:查询郑州市的所有区县

select
*
from
areas as c
inner join areas as a on a.pid=c.aid
where
c.atitle='郑州市';

例3: 查询河南省的所有区县

select *
from
areas as p
left join areas as c on c.pid=p.aid
left join areas as a on a.pid=c.aid
where
p.atitle='河南省'

子查询

在一个 select 语句中,嵌入了另外一个 select 语句, 那么被嵌入的 select 语句称之为子查询语句。

主查询

主要查询的对象,第一条 select 语句。

主查询和子查询的关系

  • 子查询是嵌入到主查询中
  • 子查询是辅助主查询的,要么充当条件,要么充当数据源
  • 子查询是可以独立存在的语句,是一条完整的select语句

子查询分类

  • 标量子查询: 子查询返回的结果是一个数据(一行一列)
  • 列子查询: 返回的结果是一列(一列多行)
  • 行子查询: 返回的结果是一行(一行多列)
  • 表级子查询: 返回的结果是多行多列

标量子查询

例1:查询班级学生的平均年龄

方式一:
select avg(age) from students ------ 得到结果21.4167
select * from students where age > 21.4167
方式二:
select * from students where age > (select avg(age) from students)

例2: 查询hello的成绩,要求显示成绩

方式一:
select studentNo from students where name = 'hello' ------ 得到结果001
select * from scores where studentNo = '001'
方式二:
select * from scores where studentNo = (select studentNo from students where name = 'hello')

列级子查询

例3:查询18岁的学生的成绩,要求显示成绩

select * from scores where studentNo in (select studentNo from students where age=18)

行级子查询

例4:查询男生中年龄最大的学生信息

select * from students where (sex,age) = (select sex,age from students where sex='男' order by age desc limit 1)

表级子查询

例5:查询数据库和系统测试的课程成绩

select *
from
scores s
inner join
(select * from courses where name in ('数据库', '系统测试')) c
on s.courseNo = c.courseNo

子查询中特定关键字使用

  • in 范围

    • 格式:主查询where条件in(列子查询)
  • any | some 任意一个

    • 格式: 主查询 where 列 = any (列子查询)
    • 在条件查询的结果中匹配任意一个即可,等价于 in
  • all

    • 格式: 主查询 where 列 = all(列子查询) : 等于里面所有
    • 格式: 主查询 where 列 <> all(列子查询) : 不等一其中所有

5 查询演练

求所有电脑产品的平均价格,并且保留两位小数

select round(avg(price),2) as avg_price from goods;

查询所有价格大于平均价格的商品,并且按价格降序排序

select id,name,price from goods
where price > (select round(avg(price),2) as avg_price from goods)
order by price desc;

查询类型为'超极本'的商品价格

select price from goods where cate = '超级本';

查询价格大于或等于"超级本"价格的商品,并且按价格降序排列

select id,name,price from goos
where price = any(select price from goods where cate = '超级本')
order by price desc;

= any 或 = some 等价于 in

!=all 等价于 not in

数据分表

查询goods表的所有记录,并且按"类别"分组

select cate from goods group by cate;

将分组结果写入到goods_cates数据表

insert into goods_cates (cate_name) select cate from goods group by cate;

通过goods_cates数据表来更新goods表

update goods as g inner join goods_cates as c on g.cate = c.cate_name
set cate = cate_id;

通过create...select来创建数据表并且同时写入记录,一步到位

create table goods_brands (
brand_id int unsigned primary key auto_increment,
brand_name varchar(40)) select brand_name from goods group by brand_name;

通过goods_brands数据表来更新goods数据表

update goods as g inner join goods_brands as b on g.brand_name = b.brand_name
set g.brand_name = b.brand_id;

3 高级

本节课程学习MySQL数据库的高级操作,不需要熟练操作,这部分内容作为了解,对于未来的软件测试工作是加分项

1 数据库设计

E-R模型

E-R模型的基本元素是:实体、联系和属性

  • E表示entry,实体:一个数据对象,描述具有相同特征的事物
  • R表示relationship,联系:表示一个或多个实体之间的关联关系,关系的类型包括包括一对一、一对多、多对多
  • 属性:实体的某一特性称为属性

关系也是一种数据,需要通过一个字段存储在表中

1、实体A对实体B为1对1,则在表A或表B中创建一个字段,存储另一个表的主键值

![image-20200713110743588](/Users/XinxingWang/Library/Application Support/typora-user-images/image-20200713110743588.png)

2、实体A对实体B为1对多:在表B中创建一个字段,存储表A的主键值

![image-20200713110814942](/Users/XinxingWang/Library/Application Support/typora-user-images/image-20200713110814942.png)

3、实体A对实体B为多对多:新建一张表C,这个表只有两个字段,一个用于存储A的主键值,一个用于存储B的主键值

![image-20200713111000609](/Users/XinxingWang/Library/Application Support/typora-user-images/image-20200713111000609.png)

2 命令行连接服务端

mysql -uroot -p

数据库

查看所有数据库
show databases;
使用数据库
use 数据库名;
查看当前使用的数据库
select database();
创建数据库
create database 数据库名 charset=utf8;
例:
create database test charset=utf8;
删除数据库
drop database 数据库名
drop database test;

数据表

看当前数据库中所有表
show tables;
查看表结构
desc 表名;
查看表的创建语句
show create table 表名;
例:
show create table students;

备份

运行myslqdump命令
mysqldump -uroot -p 数据库名 > test.sql
# 按提示输入mysql的密码

恢复

先创建新的数据库
mysql -uroot -p 新数据库名 < test.sql
# 按提示输入mysql的密码

3 内置函数

字符串函数

拼接字符串concat(str1,str2...)

select concat(12,34,'ab');

包含字符个数length(str)

select length('abc');

截取字符串

  • left(str,len)返回字符串str的左端len个字符
  • right(str,len)返回字符串str的右端len个字符
  • substring(str,pos,len)返回字符串str的位置pos起len个字符
select substring('abc123',2,3);

去除空格

  • ltrim(str)返回删除了左空格的字符串str
  • rtrim(str)返回删除了右空格的字符串str
select ltrim('  bar  ');

大小写转换

  • lower(str)
  • upper(str)
select lower('aBcD');

数学函数

求四舍五入值round(n,d),n表示原数,d表示小数位置,默认为0

select round(1.6);

求x的y次幂pow(x,y)

select pow(2,3);

获取圆周率PI()

select PI();

随机数rand(),值为0-1.0的浮点数

select rand();

日期时间函数

当前日期current_date()

select current_date();

当前时间current_time()

select current_time();

当前日期时间now()

select now();

日期格式化data_format(date,format)

%Y 获取年,返回完整年份
%y 获取年,返回简写年份
%m 获取月,返回月份
%d 获取日,返回天值
%H 获取时,返回24进制的小时数
%h 获取时,返回12进制的小时数
%i 获取分,返回分钟数
%s 获取秒,返回秒数

例:将使用-拼接的日期转换为使用空格拼接

select data_format('2016-12-21', '%Y %m %d');

流程控制

case语法:等值判断

说明:当值等于某个比较值的时候,对应的结果会被返回;如果所有的比较值都不相等则返回else的结果;如果没有else并且所有比较值都不相等则返回null

case 值 when 比较值1 then 结果1 when 比较值2 then 结果2 ... else 结果 end
例:select case 1 when 1 then 'one' when 2 then 'two' else 'zero' end as result;

自定义函数

语法

delimiter $$
create function 函数名称(参数列表) returns 返回类型
begin
sql语句
end
$$
delimiter ;

说明:

delimiter用于设置分割符,默认为分号

在“sql语句”部分编写的语句需要以分号结尾,此时回车会直接执行,所以要创建存储过程前需要指定其它符号作为分割符,此处使用//,也可以使用其它字符

示例:

创建函数my_trim,用于删除字符串左右两侧的空格

delimiter $$
create function my_trim(str varchar(100)) returns varchar(100)
begin
return ltrim(rtrim(str))
end
$$
delimiter ;

使用自定义函数

select '   abc   ', my_trim('   abc   ')

4 存储过程

存储过程,也翻译为存储程序,是一条或者多条SQL语句的集合

创建

语法

delimiter //
create procedure 存储过程名称(参数列表)
begin
aql语句
end
//
delimiter ;

说明:

delimiter用于设置分割符,默认为分号

在“sql语句”部分编写的语句需要以分号结尾,此时回车会直接执行,所以要创建存储过程前需要指定其它符号作为分割符,此处使用//,也可以使用其它字符

示例:

创建查询过程,查询学生信息

delimiter //
create procedure proc_stu()
begin
select * from students;
end
//
delimiter ;

调用

语法

call 存储过程(参数列表)

调用存储过程proc_stu
call proc_stu();
  • 存储过程和函数都是为了可重复的执行操作数据库的 sql 语句的集合
  • 存储过程和函数都是一次编译,就会被缓存起来,下次使用就直接命中缓存中已经编译好的 sql,不需要重复编译
  • 减少网络交互,减少网络访问流量

5 视图

对于复杂的查询,在多个地方被使用,如果需求发生了改变,需要更改sql语句,则需要在多个地方进行修改,维护起来非常麻烦

解决:定义视图

视图本质就是对查询的封装

定义视图,建议以v_开头

create view 视图名称 as select语句;

例:创建视图,查询学生对应的成绩信息

create view v_stu_score_course as
select
stu.*,cs.courseNo,cs.name courseName,sc,score
from
students stu
inner join scores sc on stu.studentNo = sc.studentNo
inner join courses cs on cs.courseNo = sc.courseNo

查看视图:查看表会将所有的视图也列出来

show tables;

删除视图

drop view 视图名称;
例:
drop view v_stu_score_course;

使用:

视图的用途就是查询

select * from v_stu_score_course;

6 事务

为什么要有事务

  • 事务广泛的运用于订单系统、银行系统等多种场景

  • 例如:A用户和B用户是银行的储户,现在A要给B转账500元,那么需要做以下几件事:

      1. 检查A的账户余额>500元;
      2. A 账户中扣除500元;
      3. B 账户中增加500元;
  • 正常的流程走下来,A账户扣了500,B账户加了500,皆大欢喜。那如果A账户扣了钱之后,系统出故障了呢?A白白损失了500,而B也没有收到本该属于他的500。以上的案例中,隐藏着一个前提条件:A扣钱和B加钱,要么同时成功,要么同时失败。事务的需求就在于此

  • 所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。例如,银行转帐工作:从一个帐号扣款并使另一个帐号增款,这两个操作要么都执行,要么都不执行。所以,应该把他们看成一个事务。事务是数据库维护数据一致性的单位,在每个事务结束时,都能保持数据一致性

事务命令

要求:表的引擎类型必须是innodb类型才可以使用事务,这是mysql表的默认引擎

查看表的创建语句,可以看到engine=innodb

show create table students;

修改数据的命令会触发事务,包括insert、update、delete

开启事务,命令如下:

开启事务后执行修改命令,变更会维护到本地缓存中,而不维护到物理表中

begin

提交事务,命令如下:

将缓存中的数据变更维护到物理表中

commit;

回滚事务,命令如下:

放弃缓存中变更的数据

rollback;

7 索引

思考:在图书馆中是如何找到一本书的?

一般的应用系统对比数据库的读写比例在10:1左右,而且插入操作和更新操作很少出现性能问题,遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,所以查询语句的优化显然是重中之重

当数据库中数据量很大时,查找数据会变得很慢

优化方案:索引

语法

查看索引

show index from 表名;

创建索引

方式一:建表时创建索引
create table create_index(
id int primary key,
name varchar(10) unique,
age int,
key (age)
);
方式二:对于已经存在的表,添加索引
如果指定字段是字符串,需要指定长度,建议长度与定义字段时的长度一致
字段类型如果不是字符串,可以不填写长度部分
create index 索引名称 on 表名(字段名称(长度))
例:
create index age_index on create_index(age);
create index name_index on create_index(name(10));

删除索引

drop index 索引名称 on 表名;

缺点

  • 虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE,因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件
  • 但是,在互联网应用中,查询的语句远远大于增删改的语句,甚至可以占到80%~90%,所以也不要太在意,只是在大数据导入时,可以先删除索引,再批量插入数据,最后再添加索引121黑

8 外键foreign key

如果一个实体的某个字段指向另一个实体的主键,就称为外键。被指向的实体,称之为主实体(主表),也叫父实体(父表)。负责指向的实体,称之为从实体(从表),也叫子实体(子表)

对关系字段进行约束,当为从表中的关系字段填写值时,会到关联的主表中查询此值是否存在,如果存在则填写成功,如果不存在则填写失败并报错

语法

查看外键

show create table 表名

设置外键约束

方式一:创建数据表的时候设置外键约束
create table class(
id int unsigned primary key auto_increment,
name varchar(30)
); create table stu(
name varchar(10),
class_id int unsigned,
foreign key(class_id) references class(id)
); foreign key(自己的字段) references 主表(主表字段) 方式二:对于已经存在的数据表设置外键约束
alter table 从表名 add foreign key(从表字段) references 主表名(主表字段);
alter table stu add foreign key(class_id) references class(id);

删除外键

-- 需要先获取外键约束名称
show create table stu;
-- 获取名称之后就可以根据名称来删除外键约束
alter table 表名 drop foreign key 外键名称
alter table stu drop foreign key stu_ibfk_1;

在实际开发中,很少会使用到外键约束,会极大的降低表更新的效率

9 修改密码

使用root登录,修改mysql数据库的user表

  • 使用password()函数进行密码加密
  • 注意修改完成后需要刷新权限
use mysql;

update user set password=password('新密码') where user='用户名';

例:
update user set password=password('123') where user='root'; 刷新权限:flush privileges;

忘记 root 账户密码怎么办

1、配置mysql登录时不需要密码,修改配置文件

  • Centos中:配置文件位置为/data/server/mysql/my.cnf
  • Windows中:配置文件位置为C:\Program Files (x86)\MySQL\MySQL Server 5.1\my.ini

修改,找到mysqld,在它的下一行,添加skip-grant-tables

[mysqlId]
skip-grant-tables

2、重启mysql,免密码登录,修改mysql数据库的user表

use mysql;

update user set password=password('新密码') where user='用户名';

例:
update user set password=password('123') where user='root'; 刷新权限:flush privileges;

3、还原配置文件,把刚才添加的skip-grant-tables删除,重启

05_MySQL数据库的更多相关文章

  1. JSP应用开发 -------- 电纸书(未完待续)

    http://www.educity.cn/jiaocheng/j9415.html JSP程序员常用的技术   第1章 JSP及其相关技术导航 [本章专家知识导学] JSP是一种编程语言,也是一种动 ...

  2. nodejs进阶(6)—连接MySQL数据库

    1. 建库连库 连接MySQL数据库需要安装支持 npm install mysql 我们需要提前安装按mysql sever端 建一个数据库mydb1 mysql> CREATE DATABA ...

  3. GreenDao 数据库:使用Raw文件夹下的数据库文件以及数据库升级

    一.使用Raw文件夹下的数据库文件 在使用GreenDao框架时,数据库和数据表都是根据生成的框架代码来自动创建的,从生成的DaoMaster中的OpenHelper类可以看出: public sta ...

  4. ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第二章:利用模型类创建视图、控制器和数据库

    在这一章中,我们将直接进入项目,并且为产品和分类添加一些基本的模型类.我们将在Entity Framework的代码优先模式下,利用这些模型类创建一个数据库.我们还将学习如何在代码中创建数据库上下文类 ...

  5. Java MyBatis 插入数据库返回主键

    最近在搞一个电商系统中由于业务需求,需要在插入一条产品信息后返回产品Id,刚开始遇到一些坑,这里做下笔记,以防今后忘记. 类似下面这段代码一样获取插入后的主键 User user = new User ...

  6. 在SQL2008查找某数据库中的列是否存在某个值

    在SQL2008查找某数据库中的列是否存在某个值 --SQL2008查找某数据库中的列是否存在某个值 create proc spFind_Column_In_DB ( @type int,--类型: ...

  7. 分享一个SQLSERVER脚本(计算数据库中各个表的数据量和每行记录所占用空间)

    分享一个SQLSERVER脚本(计算数据库中各个表的数据量和每行记录所占用空间) 很多时候我们都需要计算数据库中各个表的数据量和每行记录所占用空间 这里共享一个脚本 CREATE TABLE #tab ...

  8. SQL Server2014 SP2新增的数据库克隆功能

    SQL Server2014 SP2新增的数据库克隆功能 创建测试库 --创建测试数据库 create database testtest use testtest go --创建表 )) --插入数 ...

  9. 数据库优化案例——————某市中心医院HIS系统

    记得在自己学习数据库知识的时候特别喜欢看案例,因为优化的手段是容易掌握的,但是整体的优化思想是很难学会的.这也是为什么自己特别喜欢看案例,今天也开始分享自己做的优化案例. 最近一直很忙,博客产出也少的 ...

随机推荐

  1. spring bean post processor

    相关文章 Spring 整体架构 编译Spring5.2.0源码 Spring-资源加载 Spring 容器的初始化 Spring-AliasRegistry Spring 获取单例流程(一) Spr ...

  2. 键盘鼠标(PS2)模拟器驱动及Demo

    详情 KeyboardMouseSimulateDriver 问题描述: 鼠标相对移动存在不正确性,绝对移动没正确性. 基于于Thinkpad E460上的开发及测试. 不支持HID设备.

  3. PHPstorm快捷键的学习

    1.Ctrl + 空格 当输入代码时,PHPstorm 会自动出现联想选项. 但是,如果在输入时联想时错过了选择,我们要想让他再一次出现联想,通常采用的方法是在先前的输入后面再输入字符,这时联想又会出 ...

  4. css3增加的的属性值position:stricky

    position:sticky sticky 英文字面意思是粘,粘贴.这是一个结合了 position:relative 和 position:fixed 两种定位功能于一体的特殊定位,适用于一些特殊 ...

  5. java NIO 原理解析之学习笔记

    关键抽象 1.Buffer缓冲区 NIO数据传递模型,是一个连续的内存区域.所有数据传递均通过buffer类处理:NIO提供了字符串.整形.字节.堆等多种缓冲区. 2.Channel(通道) NIO把 ...

  6. 【js】栈方法和队列方法

    栈方法:后进先出,推入(push)和弹出(pop):push("**")返回数组长度,pop()返回弹出的项. var colors = new Array(); // 创建一个数 ...

  7. day49 数据库终章

    目录 一.pymysql补充 二.数据库补充 1 视图(了解) 2 触发器(了解) 3 事务 4 存储过程(了解) 5 函数 6 流程控制 7 索引 8 b+树 9 聚集索引(primary key) ...

  8. display:inline-block 什么时候不会显示间隙?

    移除空格 使用margin负值 使用font-size:0 letter-spacing word-spacing

  9. 基于html5拖拽api实现列表的拖拽排序

    基于html5拖拽api实现列表的拖拽排序 html代码: <ul ondrop="drop_handler(event);" ondragover="dragov ...

  10. JVM 专题十八:垃圾回收(二)垃圾回收相关算法

    1. 标记阶段 1.1 引用计数算法 1.1.1 对象存活判断 在堆里存放着几乎所有的Java对象实例,在GC执行垃圾回收之前,首先需要区分出内存中哪些是存活对象,哪些是已经死亡的对象.只有被标记为己 ...