目前来说如果我们要进行数据存储,有几种方式:
我们可以使用集合等方式将数据保存在内存中,但是数据不能持久化保存,断电/程序退出,数据就清除了
我们还可以将数据保存在普通文件中,可以持久化保存,但是查找,增加,修改,删除数据比较麻烦,效率低
所以我们需要一个既可以持久化保存数据又可以方便操作的地方来存储数据,这就是我们接下来要给大家介绍的数据库
数据库(DataBase,DB):指长期保存在计算机的存储设备(硬盘)上,按照一定规则组织起来,可以被各种用户或应用共享的数据集合. 还是以文件的方式存在服务器的电脑上的。
说白了就是数据的仓库, 用来持久化保存数据的.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UyScQSrI-1688052496498)(img/1571057856327.png)]
为什么要学习数据库?
把数据保存到文件, 内存里面 ,都要一些缺点. 保存到数据库里面解决这些缺点.
什么数据库?
数据的仓库, 用来持久化保存数据的
常见的关系型数据库?
MySQL
Oracle
数据库是用来存储数据的,那么到底通过什么样的方式来存的. 结构是怎么样的呢?
数据库管理程序(DBMS)可以管理多个数据库,一般开发人员会针对每一个应用创建一个数据库。为保存应用中实体的数据,一般会在数据库创建多个表,以保存程序中实体的数据。
数据库管理系统、数据库和表的关系如图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7sl115lD-1688052496500)(img/tu_16.png)]
1.一般情况下,一个系统(软件,项目) 就设计一个数据库; eg: jd项目, 设计一个jd的数据库
2.一个数据库里面有多(>=1)张表. 一个实体(java类)对应一张表
3.一张表里面有多条(>=1)记录, 一个对象对应一条记录
我们要使用MySql数据库,就需要先安装. 如果第一次安装失败了,就需要卸载,再安装.
具体参考文档: 资料\01_MySql安装与卸载\MySql安装图解.docx
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jcsh19wn-1688052496501)(img/1555490978511.png)]
具体参考文档: 资料\01_MySql安装与卸载\MySql卸载手册.doc
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2L0ZBv6h-1688052496501)(img/1555490988722.png)]
安装需要注意的地方: 安装路径不要有空格和中文,对着文档装
卸载需要注意的地方
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ISNe59hL-1688052496502)(img/1535849477078.png)]
我们刚刚把数据库安装成功了,下面就需要进行数据库的启动,登录和退出
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wc5c0uVi-1688052496503)(img/tu_9.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VCnpZBKi-1688052496503)(img/tu_10.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2WpUEdnF-1688052496505)(img/tu_11.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wfrfBwzj-1688052496505)(img/tu_12.png)]
MySql是一个需要账户名密码登录的数据库,登陆后使用,它提供了一个默认的root账号,使用安装时设置的密码即可登录.
mysql -u 用户名 -p #然后再输入密码.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6hodNgJ8-1688052496506)(img/1555917393832.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gs4qseJC-1688052496506)(img/1555917404051.png)]
连接
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rlC2aj4j-1688052496514)(img/1555917461553.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JiLvBvBI-1688052496514)(img/1555917516520.png)]
输入: quit或exit
mysql -u root -p
再输入密码
mysql -uroot -p密码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JmTxxwjB-1688052496515)(img/tu_17.png)]
我们把Sql介绍完成了, 那下面就通过DDL操作数据库
create database 数据库名 [character set 字符集][collate 校对规则] 注: []意思是可选的意思
字符集(charset):是一套符号和编码。
创建一个day18_1的数据库(默认字符集)
create database day18_1;
创建一个day18_2的数据库,指定字符集为gbk(了解)
create database day18_2 character set gbk;
show databases;
show create database 数据库名;
-- 查看数据库
-- 语法: show databases; 查询所有的数据库
show databases
-- 语法: show create database 数据库名; 查看数据库的定义结构【了解】
show create database day18_1
show create database day18_2
drop database 数据库名;
-- 需求: 删除day18_2数据库
drop database day18_2
alter database 数据库名 character set 字符集;
-- 需求: 把day18_2数据库的字符集修改为utf8
alter database day18_2 character set utf8
注意:
use 数据库名; //注意: 在创建表之前一定要指定数据库. use 数据库名
-- 语法: use 数据库名; 选中数据库
use day18_1
-- 语法: select database(); 查看当前选中(正在使用)的数据库
select database();
create database 数据库的名字;
drop database 数据库的名字;
use 数据库的名字; -- 切换到某个数据库
select database(); -- 查看正在使用哪个数据库
我们第四章已经把数据库的CRUD讲解完了,下面我们就学习创建表
create table 表名(
列名 类型 [约束],
列名 类型 [约束],
...
列名 类型 [约束]
);
列: 字段
行: 记录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-65FY8NwK-1688052496516)(img/tu_4.png)]
整型 一般使用int 或者bigint
浮点/双精度型
字符串
一般使用varchar(n) 节省空间; 如果长度(eg:身份证)是固定的话 可以使用char(n) 性能高一点
关于大文件
日期
类型小结
约束 | 约束关键字 |
---|---|
主键 | primary key |
唯一 | unique |
非空 | not null |
约束种类:
not null: 非空 ; eg: username varchar(40) not null username这个列不能有null值
unique:唯一约束, 后面的数据不能和前面重复; eg: cardNo char(18) unique; cardNo 列里面不可以有重复数据
primary key;主键约束(非空+唯一); 一般用在表的id列上面. 一张表基本上都有id列的, id列作为唯一标识的
id int primary key auto_increment; id不需要我们自己维护了, 插入数据的时候直接插入null, 自动的增长进行填充进去, 避免重复了.
注意:
id列:
-- 需求: 创建一张学生表(含有id字段,姓名字段,性别字段. id为主键自动增长)
-- 创建表之前需要选中数据库
use day18_1
create table student(
id int primary key auto_increment,
name varchar(40) ,
sex varchar(13) not null
);
create table 表名(
列 类型 【约束】,
列 类型 【约束】
);
我们把表创建好了, 下面就来介绍查看表
show tables;
语法
desc 表名;
练习:
-- 语法: show tables; 查看所有的表
show tables
-- 语法: desc 表名; 查看表的定义结构
desc student
我们表创建好了, 如果要增加一列,要删除一列呢? 那下面就来讲解修改表
-- 修改表
-- 语法: alter table 表名 add 列名 类型 约束; 增加列
-- 需求:为学生表增加一个成绩列
alter table student add score double;
-- 语法: alter table 表名 modify 列名 新类型 新约束; 修改列的类型约束
-- 需求: 修改name的类型和约束
alter table student modify name varchar(40) not null;
-- 语法: alter table 表名 change 旧列名 新列名 类型 约束; 修改列的名称,类型,约束
-- 需求: 修改sex列名为gender
alter table student change sex gender varchar(13) not null;
-- 语法: alter table 表名 drop 列名; 删除列
-- 需求: 删除score
alter table student drop score;
-- 语法: rename table 旧表名 to 新表名; 修改表名
rename table student to stu;
表创建好了, 我们还可以删除。 掌握表的删除
语法
drop table 表名;
练习
-- 删除表
-- drop table 表名;
-- 需求: 删除stu表
drop table stu;
drop table 表名;
create table product(
pid int primary key auto_increment, //只有设置了auto_increment id列才可以赋值为null
pname varchar(40),
price double,
num int
);
准备一张表
-- 创建一张商品表(商品id,商品名称,商品价格,商品数量)
create table product(
id int primary key auto_increment,
pname varchar(100),
price double,
num int
)
方式一: 插入指定列, 如果没有把这个列进行列出来, 以null进行自动赋值了.
eg: 只想插入pname, price , insert into t_product(pname, price) values(‘mac’,18000);
insert into 表(列,列..) values(值,值..);
insert into product(pname,price) values('Mac',18888);
注意: 如果没有插入了列设置了非空约束, 会报错的
insert into 表 values(值,值....);
eg:
insert into product values(null,'苹果电脑',18000.0,10);
insert into product values(null,'华为5G手机',30000,20);
insert into product values(null,'小米手机',1800,30);
insert into product values(null,'iPhonex',8000,10);
insert into product values(null,'苹果电脑',8000,100);
insert into product values(null,'iPhone7',6000,200);
insert into product values(null,'iPhone6s',4000,1000);
insert into product values(null,'iPhone6',3500,100);
insert into product values(null,'iPhone5s',3000,100);
insert into product values(null,'方便面',4.5,1000);
insert into product values(null,'咖啡',11,200);
insert into product values(null,'矿泉水',3,500);
命令行插入中文数据报错:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Pumob3KZ-1688052496517)(img/tu_3.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X3MrAGzn-1688052496517)(img/1535858746067.png)]
语法
insert into 表名(列,列) value(值,值)
insert into 表名 values(值,值,值....)
注意
我们数据插入成功了, 还可以对已有的数据进行更新。
update 表名 set 列 =值, 列 =值 [where 条件]
-- 更新记录
-- 语法: update 表名 set 列 =值, 列 =值 [where 条件]
-- 需求:修改商品所有的价格为5000
update product set price = 5000;
-- 需求: 修改id为2的商品数量和价格
update product set price = 8000,num = 20 where id = 2;
-- 将商品名是Mac的价格修改为18000元
update product set price = 18000 where pname = 'Mac'
-- 将商品名是Mac的价格修改为17000,数量修改为5
update product set price = 17000,num = 5 where pname = 'Mac'
-- 将商品名是方便面的商品的价格在原有基础上增加2元
update product set price = price + 2 where pname = '方便面'
update 表名 set 列 = 值, 列=值, 列=值 [where 条件]
delete from 表 [where 条件]
truncate table 表;
-- 删除记录
-- 语法一: delete from 表名 [where 条件]
-- 删除表中名称为’Mac’的记录
delete from product where pname = 'Mac'
-- 删除价格小于5001的商品记录
delete from product where price < 5001
-- 删除表中的所有记录
delete from product
-- 语法二: truncate table 表名;
truncate table product
delete from 表 【where 条件】
delete 和truncate区别【面试题】
工作里面的删除
工作里面一般使用逻辑删除用的多
我们上面讲解了对数据的增删改, 下面就来重点讲解数据的简单查询.
select [*] [列名 ,列名] [列名 as 别名 ...] [distinct 字段] from 表名 [where 条件]
注意点: 去重针对某列, distinct前面不能先出现列名
注意
-- 基本查询语法: select [*][列名,列名][distinct 列名] from 表名 [where 条件]
-- 查询所有的列语法 : select * from 表名
-- 需求: 查询product表中的所有数据
select * from product;
-- 查询某张表特定列 : select 列名,类名,... from 表名
-- 需求: 查询product表中的pname,price字段的值
select pname,price from product
-- 去重查询 : select distinct 列名 from 表名
-- 需求: 查询price字段,去重 单个字段去重
select distinct price from product
-- 需求: 查询pname,price字段,同时去重 多个字段去重
select distinct pname,price from product
-- 注意: distinct前面不能有字段名
select id,distinct price from product -- 报错
-- 别名查询
-- 对字段取别名: select 字段 as 别名,字段 as 别名,... from 表名 注意: as可以省略 一般都会省略
select pname as 商品名称,num as 商品数量 from product
select pname 商品名称,num 商品数量 from product
-- 对表取别名:select 表1别名.字段名,... from 表1 as 表1别名 明天讲解,今天先感受 注意: as可以省略 一般都会省略
select p.pname,p.num from product as p;
select p.pname,p.num from product p;
-- 运算查询(+,-,*,/等) null和其他数据进行运算得到是null
-- 需求: 计算每个商品的总价(单价*数量)
select price ,num from product
select price * num from product
select price * num 总价 from product
select price * ifnull(num,0) 总价 from product
select ... from 表 where 条件
//取出表中的每条数据,满足条件的记录就返回,不满足条件的记录不返回
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-raMp2QLl-1688052496518)(img/tu_2.png)]
eg: where price between 1000 and 3000 相当于 1000<=price<=3000
-- 查询id为1,3,5,7的
select * from t_product where id = 1
select * from t_product where id = 3
select * from t_product where id = 5
select * from t_product where id = 7
select * from t_product where id in(1,3,5,7)
name like '张%' --查询姓张的用户, 名字的字数没有限制
name like '张_' --查询姓张的用户 并且名字是两个字的
where 条件1 and 条件2 and 条件3
where 条件1 or 条件2 or 条件3
查询商品价格>3000的商品
查询id=1的商品
查询id<>1的商品
查询价格在3000到6000之间的商品
查询id在1,5,7,15范围内的商品
查询商品名以iPho开头的商品(iPhone系列)
查询商品价格大于3000并且数量大于20的商品 (条件 and 条件 and…)
查询id=1或者价格小于3000的商品
-- 查询商品价格>3000的商品
select * from product where price > 3000
-- 查询id=1的商品
select * from product where id = 1
-- 查询id<>1的商品
select * from product where id <> 1
select * from product where id != 1
-- 查询价格在3000到6000之间的商品
select * from product where price between 3000 and 6000
select * from product where price >= 3000 and price <= 6000
-- 查询id在1,5,7,15范围内的商品
select * from product where id in(1,5,7,15)
-- 查询商品名以iPho开头的商品(iPhone系列)
select * from product where pname like 'iPho%'
-- 查询商品价格大于3000并且数量大于20的商品 (条件 and 条件 and...)
select * from product where price > 3000 and num > 20
-- 查询id=1或者价格小于3000的商品
select * from product where id = 1 or price < 3000
select [*],[列名,列名],[列名 as 别名],[distinct 列名],[列(+,-..)] from 表名 [where 条件]
有时候我们需要对查询出来的结果排序显示,那么就可以通过ORDER BY
子句将查询出的结果进行排序。排序可以根据一个字段排,也可以根据多个字段排序,排序只是对查询的结果集排序,并不会影响表中数据的顺序。
# 创建学生表(有sid,学生姓名,学生性别,学生年龄,分数列,其中sid为主键自动增长)
CREATE TABLE student(
sid INT PRIMARY KEY auto_increment,
sname VARCHAR(40),
sex VARCHAR(10),
age INT,
score DOUBLE
);
INSERT INTO student VALUES(null,'zs','男',18,98.5);
INSERT INTO student VALUES(null,'ls','女',18,96.5);
INSERT INTO student VALUES(null,'ww','男',15,50.5);
INSERT INTO student VALUES(null,'zl','女',20,98.5);
INSERT INTO student VALUES(null,'tq','男',18,60.5);
INSERT INTO student VALUES(null,'wb','男',38,98.5);
INSERT INTO student VALUES(null,'小丽','男',18,100);
INSERT INTO student VALUES(null,'小红','女',28,28);
INSERT INTO student VALUES(null,'小强','男',21,95);
SELECT 字段名 FROM 表名 [WHERE 条件] ORDER BY 字段名 [ASC|DESC]; //ASC: 升序,默认值; DESC: 降序
select * from student order by score desc;
SELECT 字段名 FROM 表名 WHERE 字段=值 ORDER BY 字段名1 [ASC|DESC], 字段名2 [ASC|DESC];
select * from student order by score desc ,age desc;
order by 列 asc/desc, 列 asc/desc;
asc: 升序【默认值】 order by 列;
desc: 降序
应用场景
商城里面 根据价格, 销量, 上架时间, 评论数…
社交里面 根据距离排序
之前我们做的查询都是横向查询,它们都是根据条件一行一行的进行判断,而使用聚合函数查询是纵向查询,它是对一列的值进行计算,然后返回一个结果值。聚合函数会忽略空值NULL
聚合函数 | 作用 |
---|---|
max(列名) | 求这一列的最大值 |
min(列名) | 求这一列的最小值 |
avg(列名) | 求这一列的平均值 |
count(列名) | 统计这一列有多少条记录 |
sum(列名) | 对这一列求总和 |
SELECT 聚合函数(列名) FROM 表名 [where 条件];
-- 求出学生表里面的最高分数
SELECT MAX(score) FROM student
-- 求出学生表里面的最低分数
SELECT MIN(score) FROM student
-- 求出学生表里面的分数的总和(忽略null值)
SELECT SUM(score) FROM student
-- 求出学生表里面的平均分
SELECT AVG(score) FROM student
-- 统计学生的总人数 (忽略null)
SELECT COUNT(sid) FROM student
SELECT COUNT(*) FROM student
注意: 聚合函数会忽略空值NULL
我们发现对于NULL的记录不会统计,建议如果统计个数则不要使用有可能为null的列,但如果需要把NULL也统计进去呢?我们可以通过 IFNULL(列名,默认值) 函数来解决这个问题. 如果列不为空,返回这列的值。如果为NULL,则返回默认值。
-- 注意: 聚合函数会忽略null
-- 准备添加2条数据
INSERT INTO student VALUES(null,'小明','男',21,null);
INSERT INTO student VALUES(null,'小黑','男',22,98);
-- 需求: 统计所有学生的总分数
select sum(score) from student -- 结果: 824 忽略null
-- 需求:统计学生的总人数 (忽略null)
select count(score) from student -- 结果: 10个 忽略null
-- 求出学生表里面的平均分
select avg(score) from student -- 结果: 82.4 忽略null 问题:实际开发不能忽略null
select avg(ifnull(score,0)) from student -- 结果: 74.9090909090909
-- 扩展:
-- 假设: 统计所有同学的age+score
select sum(age+score) from student -- 结果: 1040
select sum(age) + sum(score) from student -- 结果: 1061
select 聚合函数(列) from 表名;
聚合函数
注意事项
分组查询是指使用 GROUP BY语句对查询信息进行分组
GROUP BY怎么分组的? 将分组字段结果中相同内容作为一组,如按性别将学生分成两组
GROUP BY将分组字段结果中相同内容作为一组,并且返回每组的第一条数据,所以单独分组没什么用处。分组的目的就是为了统计,一般分组会跟聚合函数一起使用
SELECT 字段1,字段2... FROM 表名 [where 条件] GROUP BY 列 [HAVING 条件];
-- 根据性别分组, 统计每一组学生的总人数
SELECT sex, count(*) FROM student GROUP BY sex
SELECT sex, count(*) FROM student GROUP BY sex HAVING count(*) > 5
-- 练习复杂: 统计sid为8之前的的, 根据性别分组, 每一组学生的总人数 > 2的(分组后筛选)
select sex,count(*) from student where sid < 8 group by sex having count(*) > 2
where 条件 group by 列 [having 条件]
注意事项
根据某一列进行分组, 将分组字段结果中相同内容作为一组; 有几组 返回的记录就有几条
单独分组 没有意义, 返回每一组的第一条记录
分组的目的一般为了做统计使用, 所以经常和聚合函数一起使用
在分组里面, 如果select后面的列没有出现在group by后面 展示这个组的这个列的第一个数据
where和having的区别【面试】
子名 | 作用 |
---|---|
where 子句 | 1) 对查询结果进行分组前,将不符合where条件的行去掉,即在分组之前过滤数据,即先过滤再分组。2) where后面不可以使用聚合函数 |
having字句 | 1) having 子句的作用是筛选满足条件的组,即在分组之后过滤数据,即先分组再过滤。2) having后面可以使用聚合函数 |
LIMIT是限制的意思,所以LIMIT的作用就是限制查询记录的条数. 经常用来做分页查询
select ... from .... limit a ,b.
LIMIT a,b; |
---|
a起始行数,从0开始计数,如果省略,默认就是0; a=(当前页码-1)*b; |
b: 返回的行数 |
eg: 分页查询学生, 每一页查询4条
b=4; a=(当前页码-1)*b;
-- 需求: 分页查询学生, 每一页查询4条
select * from student limit 0,4; -- 第1页
select * from student limit 4,4; -- 第2页
select * from student limit 8,4; -- 第3页
-- 【a=(当前页码-1)*b,b】
limit a,b;
a:从哪里开始查询, 从0开始计数 【a=(当前页码-1)*b】
b: 一页查询的数量【固定的,自定义的】
应用场景
如果数据库里面的数据量特别大, 我们不建议一次查询出来. 为了提升性能和用户体验, 使用分页
select...from...
select...from...where...
select...from...where...order by...
select...from...where...group by...
select...from...where...limit a,b
select...from...where...group by...having....order by...limit
- 能够理解数据库的概念
存储数据的仓库,特点:可以持久化保存,并且可以通过sql语句进行方便的增删查改
- 能够安装MySql数据库
略
- 能够使用SQL语句操作数据库
创建: create database 数据库名;
删除: drop database 数据库名;
查看: show databases; show create database 数据库名;
修改: alter database 数据库名 character set 字符集;
其他: use 数据库名;
- 能够使用SQL语句操作表结构
创建:
create table 表名(
字段名 类型 约束,
...
字段名 类型 约束
);
类型: int,double,varchar(长度),date\datetime
约束:
主键: primary key auto_increment
非空: not null
唯一: unique
删除: drop table 表名;
查询: show tables; desc 表名;
修改:
alter table 表名 add 列名 类型 约束;
alter table 表名 modify 列名 类型 约束;
alter table 表名 change 旧列名 新列名 类型 约束;
rename table 旧表名 to 新表名;
- 能够使用SQL语句进行数据的添加修改和删除的操作
添加: insert into 表名(字段,字段) values(值,值);
insert into 表名 values(值,值,...);
删除:
delete from 表名 where 条件;
truncate table 表名;
修改:
update 表名 set 字段=值,... where 条件
- 能够使用SQL语句进行条件查询数据
select ... from 表名 where 条件
- 能够使用SQL语句进行排序
select ... from 表名 order by 字段 [asc,desc]
- 能够使用聚合函数
max(),min(),sum(),avg(),count() ifnull()
- 能够使用SQL语句进行分组查询
select ... from 表名 group by 字段 having 条件
- 能够使用SQL语句进行分页查询
select ... from 表名 limit a ,b
查询总结: select...from...where...group by...having....order by...limit