一、为什么要学习数据库?
-
持久化数据
-
方便检索
-
存储大量数据
-
共享、安全
-
通过组合分析,获取新的数据
二、数据库的相关概念
1.DB
DB:database数据库,存储一系列有组织数据的容器
2.DBMS
DBMS:database Management System数据库管理系统,使用DBMS和维护DB
3.SQL
SQL:StructureQueryLanguage结构化查询语言,程序员用于和DBMS通信的语言
三、数据库存储数据的特点
-
数据先放在表中,表再放在库中
-
一个库可以优多张表,每张表都有自己的唯一标识名
-
一张表的设计,类似于Java中的地设计。表中字段的设计,类似于属性的设计。表中的单条记录,类似于一个对象。表中的所有记录,类似于对象的集合
四、初识MYSQL
1.MYSQL服务的启动与停止
通过管理员身份运行dos
net start 服务名
net stop 服务名
2.服务的登录和退出
通过DOS命令:
mysql -h主机名 -P端口号 -u用户名 -p密码
注意:
如果是本机,则-h主机名 可以省略。
如果端口号是3306,则-P端口号可以省略。
五、MYSQL的常见命令
-
常见命令
show databases 显示当前连接下所有数据库
show tables 显示当前库中的所有表格
show tables from 库名 显示指定库中的所有表
use 库名 打开/使用指定库
-
语法规范
不区分大小写
每条命令结尾用分号结束
注释:
单行注释有#,--
多行注释有/* */
六、DQL语言
1.基础查询
-
语法:
select 查询列表 from 表名;
-
特点:
-
查询结果是一个虚拟表
-
查询列表可以是单个字段、多个字段、常量、表达式、函数、以及以上的组合。
引申1:起别名
select 字段名 as "别名" from 表名;
select 字段名 ”别名" from 表名;
引申2:+的作用
作用:加法运算
-
如果两个操作数都是数值型,则直接做加法运算
-
如果其中一个为非数值型,则将该值强制转换为数值型,如果转换失败,则当作0.
-
如果其中一个为null,则结果直接为null
引申3:去重
select distinct 字段名 from 表名;
引申4:补充函数
select database();
select user();
select ifnull(字段名,表达式);
select concat(字符1,字符2,字符3,...,字符n);
select length(字符/字段);获取字节长度
2.条件查询
-
语法:
select 查询列表
from 表名
where 筛选条件;
-
执行顺序:
-
from字句
-
where字句
-
select字句
-
筛选条件特点:
-
按关系表达式筛选
关系运算符:> < >= <= = <>
-
按逻辑表达式筛选
逻辑运算符:and or not
-
模糊查询
-
like
功能:一般和通配符搭配使用,对字符型数据进行部分匹配查询
常见的通配符:
_任意单个字符
%任意多个字符
-
in
功能:查询某字段的值是否属于指定的列表之内。
-
between and
功能:判断某个字段的值是否在指定的区间。
-
is null / is not null
-
3.排序查询
-
语法:
select 查询列表
from 表名
where 筛选条件
order by 排序列表
-
执行顺序:
-
from字句
-
where字句
-
select字句
-
order by字句
-
特点:
-
排序列表可以是单个字段、多个字段、表达式、函数、列数、以及以上的组合。
-
升序,通过asc,默认是升序。
降序,通过desc。
4.常见函数
-
字符函数
1、concat 拼接字符
2、length 获取字节长度
3、 char_length 获取字符个数
4、substring 截取字串
substring(str,起始索引,截取的长度)
注意:起始索引从1开始
5、 instr(str1,substr) 获取substr在str第一次出现的位置
6、trim 去前后指定的字符,默认是去空格
trim('x' from 'xx字符xx')
7、 lpad/rpad 左填充/右填充
lpad('字符',数字,‘填充的字符‘)
8、upper/lower 变大写/变小写
9、strcmp(str1,str2) 比较两个字符大小
10、left/right 截取字串
left('字符’,长度)从左到右截取字串长度为指定长度的字串。
-
数学函数
1、abs 绝对值
2、ceil 向上取整 返回>=该参数的最小整数
ceil(-1.02) = -1
ceil(1.02) = 2
3、floor 向下取整 返回<=该参数的最大整数
floor(-1.02) = -2
floor(1.02) = 1
4、round 四舍五入
round(1.02) = 1
5、truncate 截断
truncate(1.07,1) = 1.0
6、mod 取余
-
日期函数
1、NOW() 当前日期包含时间
2、curdate ()当前日期不包含时间
3、curtime() 当前时间
4、datediff (data1,data2) 获取时间差,返回时间差天数
datediff('2020-10-16',‘2020-10-15) = 1
5、data_format() 将日期转换为指定格式的字符串
6、str_to_date(str, 格式) 按指定格式解析字符串为日期类型
7、year() 获取年
8、month() 获取月
-
流程控制语句
1、if函数
if(100 > 9, '好',’坏') = 好
2、case函数
情况1:类似于switch语句,可以实现等值判断
case 表达式
when 值1 then 结果1
when 值2 then 结果2
...
else 结果n
end
情况2:类似于多重if语句,实现区间判断。
case
when 条件1 then 结果1
when 条件2 then 结果2
...
else 结果n
end
5.分组函数
说明:分组函数往往用于实现将一组数据进行统计计算,最终得到一个值。又称为聚合函数或统计函数。
-
sum(字段名):求和
-
avg(字段名):求平均数
-
max(字段名):求最大值
-
min(字段名):求最小值
-
count(字段名):计算非空字段值的个数
补充:
count(*)统计结果集的行数。
搭配distinct实现去重统计。
6.分组查询
当需要分组查询时需要使用group by 字句
-
语法:
select 查询列表
from 表名
where 筛选条件
group by 分组列表
having 筛选条件
order by 排序列表;
-
执行顺序:
-
from字句
-
where字句
-
group by字句
-
having子句
-
select字句
-
order by字句
-
特点:
-
查询列表往往是分组函数和被分组的字段
-
分组查询中的筛选分为两类
筛选 筛选的基表 使用的关键字 分组前筛选 原始表 where 分组后筛选 分组后的结果集 having 分组函数做条件,只可能放在having后面。
7.内连接
等值连接
-
SQL92语法:
select 查询列表
from 表名1 as 别名1,表名2 as 别名2,...,表名n as 别名n
where 等值连接的连接条件
group by 分组列表
having 分组后筛选
order by 排序列表
-
特点:
-
为了解决多表中的字段重名问题,往往为表起别名,提高语义性
-
表的顺序无要求
-
SQL99语法:
select 查询列表
from 表名1 as 别名1
[inner] join 表名2 on 连接条件
where 筛选条件
group by 分组列表
having 分组后筛选
order by 排序列表
8.外连接
-
说明:查询结果为主表中所有的记录,如果从表有匹配项,则显示匹配项,如果没有,则显示null
-
应用场景:一般用于查询主表中有但从表没有的记录
-
特点:
-
外连接分主从表,两表的顺序不能任意调换
-
左连接的话,left join左边为主表
右连接的话,right join右边为主表
-
外连接的查询结果=内连接的查询结果+主表有但从表没有的记录
-
语法:
select 查询列表
from 表1 别名
left|right [outer] join 表2 别名
on 连接条件
where 筛选条件;
9.子查询
-
说明:当一个查询语句中又嵌套了另一个完整的select语句,则被嵌套的select语句被称为子查询或内查询,外面的select语句称为主查询或外查询。
-
分类:
按子查询出现的位置进行分类
-
select后面
要求:子查询的结果为单行单列(标量子查询)
-
from后面
要求:子查询的结果可以为多行多列
-
where或having后面
要求:子查询的结果必须为单列
单行子查询
多行子查询
-
exists后面
要求:子查询结果必须为单列(相关子查询)
-
特点:
-
子查询放在条件中,要求必须放在条件的右侧
-
子查询一般放在小括号中
-
子查询的执行优先于主查询
-
单行子查询对应了单行操作符:> < >= <= = <>
多行子查询对应了多行操作符:any/some all in
in:判断某字段是否在指定列表内
any/some:判断某字段的值是否满足其中任意一个
all:判断某字段的值是否满足里面所有的值
10.分页查询
-
应用场景:当页面上的数据,一页显示不全,则需要分页显示。分页查询的sql命令请求数据库服务器—>服务器响应查询到的多条数据—>前台页面
-
语法:
select 查询列表
from 表1 别名
join 表2 别名
on 连接条件
where 筛选条件
group by 分组
having 分组后筛选
order by 排序列表
limit 起始条目索引,显示的条目数
-
执行顺序:
-
from字句
-
join字句
-
on字句
-
where字句
-
group by字句
-
having字句
-
select字句
-
order by字句
-
limit字句
-
特点:
-
起始条目索引如果不写,默认是0
-
limit后面支持两个参数
参数1:显示的起始条目索引
参数2:条目数
-
公式:
假如要显示的页数是page,每页显示的条目数为size
select *
from 表
limit (page-1)*size,size
11.联合查询
-
说明:当查询结果来自多张表,但多张表之间没有关联,这个时候往往使用联合查询,也叫union查询
-
语法:
select 查询列表 from 表1 where 筛选条件
union/union all
select 查询列表 from 表2 where 筛选条件
-
特点:
-
多条待联合的查询语句的查询列数必须一致,查询类型、字段意义最好一致
-
union自动去重
-
union all不去重
七、DDL语言
-
说明:数据定义语言,用于对数据库和表的管理和操作
一、库的管理
-
创建数据库
create database 库名;
create database if not exists 库名;
-
删除数据库
drop database 库名;
drop database if exists 库名;
二、表的管理
一、创建表
-
语法:
create table [if not exists] 表名(
字段名 字段类型 【字段约束】,
字段名 字段类型 【字段约束】,
字段名 字段类型 【字段约束】
);
-
常见约束:
说明:用于限制表中字段的数据,从而进一步保证数据表的数据是一致性的、准确的、可靠的。
not null 非空:用于限制该字段为必填项
default 默认: 用于限制该字段没有显示插入值,则直接显式默认值
primary key 主键:用于限制该字段的值不能重复,且不能为null,一个表只能由一个主键
unique 唯一:用于限制该字段的值不能重复
字段是否可以为空 | 一个表可以有几个 | |
---|---|---|
主键 | 否 | 一个 |
唯一 | 是 | 多个 |
check 检查:用于限制该字段的值必须满足指定条件。MYSQL不支持该语法。
foreign key 外键:用于限制两个表的关系,要求外键列的值来自于主表的关联列
定义外键的语句:constraint 外键名 foreign key (外键字段名) references 从表(主键字段名)
二、修改表
-
语法:
修改表名:
alter table 表名 rename to 新表名
添加新字段:alter table 表名 add column 新字段名 新字段类型 【字段约束】;
修改字段类型或约束:alter table 表名 modify column 字段名 新字段类型 【新字段约束】;
修改字段名:alter table 表名 change column 旧字段名 新字段名 新字段类型 【新字段约束】;
删除字段:alter table 表名 drop column 字段名;
三、删除表
drop table if exists 表名;
四、复制表
仅仅复制表结构,没有包含数据:
create table 新表名 like 旧表名;
复制表结构+数据:
create table 新表名 子查询;
三、常见类型
整型:tinyint、smallint、int、bigint
浮点型:float(m,n)、double(m,n)、decimal(m,n)。精度从低到高排序。
字符型:char(n)可选,默认是1,固定长度的字符,效率高,适合长度固定的字段
varchar(n)n必选,不能省略,长度可变的字符,效率较低,适合存储长度变化较大的字段
text:保存较长文本
日期型:date:只能保存日期
time:只能保存时间
datetime:保存日期+时间 所占字节空间:8,能表示的日期范围较大
timestamp:保存日期+时间 所占字节空间4,能表示的日期范围较小
八、DML语言
说明:DML:数据操作语言,对表中的数据进行增删改
一、数据的插入
-
语法:
插入单行:insert into 表名(字段名1,字段名2,...) values(值1,值2,...);
插入多行:insert into 表名(字段名1,字段名2,...) values(值1,值2,...),(值1,值2,...),(值1,值2,...)...;
-
特点:
-
字段和值列表一一对应,包含类型、约束等必须匹配
-
数值型的值,不用单引号。非数值型的值,必须使用单引号
-
字段顺序无要求
二、数据的修改
1.修改单表的记录
-
语法:
update 表名
set 列=新值,列=新值,...
where 筛选条件
2.修改多表的记录
-
sql92语法:
update 表1 别名,表2 别名
set 列=值,...
where 连接条件
and 筛选条件
-
sql99语法
update 表1 别名
inner|left|right join表2 别名
on 连接条件
set 列=值,...
where 筛选条件
三、数据的删除
-
delete语句:
delete from 表名 where 筛选条件
-
truncate语句:
truncate table 表名;
delete和truncate的区别:
-
delete可以添加where条件,truncate不能添加where条件,一次性清除所有数据
-
truncate效率较高
-
如果删除带自增长列的表,使用delete删除后,重新插入数据,记录从断点处开始。使用truncate删除后,重新插入数据,记录从1开始
-
delete删除数据,会返回受影响的行数,truncate删除数据,不返回影响的行数
-
delete删除数据,可以支持事物回滚,truncate删除数据,不支持事务回滚
九、事务
事务:一个事务是由一条或者多条sql语句构成,这一条或者多条sql语句要么全部执行成功,要么全部执行失败。
事务的四大特性
-
原子性:事务中所有操作都是不可再分割的原子单位。事务中所有操作要么全部执行成功,要么全部执行失败。
-
一致性:事务执行后,数据库状态于其他业务规则保持一致。
-
隔离性:隔离性是指在并发操作中,不同事务之间应该隔离开来,使每个并发中的事务不会互相干扰。
-
持久性:一旦事务提交成功,事务中的所有数据操作都必须被持久化到数据库中。
事务的隔离级别
概念:多个事务时间是隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题。
存在的问题
-
脏读:一个未提交事务读取到另一个未提交事务的数据
-
不可重复读:一个未提交事务先读取了原本的数据,然后又读取到到另一提交事务修改的数据
-
幻读:一个未提交事务先读取了原本的数据,然后又读取了另一提交事务添加的数据
隔离级别
-
read uncommitted:读未提交
-
产生的问题:脏读、不可重复读、幻读
-
-
read uncommitted:读已提交(Oracle默认)
-
产生的问题:不可重复读、幻读
-
-
repeatable read:可重复读(MYSQL默认)
-
产生的问题:幻读
-
-
serializable:串行化
-
可以解决所有的问题
-
注意:隔离级别从小到大,安全性越来越高,但是效率越来越低
十、三大范式
第一范式(1NF)
第一范式(1NF):字段具有原子性,不可再分。所有关系型数据库系统都满足第一范式,数据库表中的字段都是单一属性的,不可再分。
存在的问题:
-
存在非常严重的数据冗余
-
数据添加存在问题
-
数据删除存在问题
第二范式(2NF)
第二范式(2NF):在第一范式的基础上,非主属性必须完全依赖于主码(在1NF基础上消除非主属性对主码的部分函数依赖)
-
函数依赖:A——>B,如果通过A属性(属性组)的值,可以确定唯一B属性的值。则称B依赖于A
-
完全函数依赖:A——>B,如果A是一个属性组,且B属性值的确定需要依赖于A属性组中的所有属性值
-
部分函数依赖:A——>B,如果A是一个属性组,且B属性值的确定只需要依赖于A属性组中的部分属性值
-
传递函数依赖:A——B,B——>C,如果通过A属性(属性组)的值,可以确定唯一B属性的值,再通过B属性(属性组)的值,可以确定唯一C属性的值,则称C传递函数依赖于A
-
码:如果在一张表中,一个属性(属性组),被其他所有属性所完全依赖,则称这个属性(属性组)为该表的码
第三范式(3NF)
满足第三范式(3NF)在2NF的基础上,任何非主属性不依赖于其他非主属性(在2NF的基础上消除传递依赖) 所以第三范式具有如下特征: 1,每一列只有一个值 2,每一行都能区分。 3,每一个表都不包含其他表已经包含的非主关键字信息。
-