继续MySQL,今天主要内容有:子查询,数据库备份命令,数据库设计,以及一个类似京东商城的数据库小练习。
子查询
使用数据表依然是是昨天的students
- 标量子查询 子查询得到的结果 是一行一列
-- 查询班级最高身高的学生信息
select * from students where height = (select max(height) from students);
-- 查询学生的平均身高
select avg(height) from students;
-- 查询出高于平均身高的信息
select * from students where height > (select avg(height) from students);
- 列级子查询 查询的结果是一列多行
-- 查询哪些班级有学生 查找的是班级的名字
select classes.name from classes where classes.id in (select distinct cls_id from students);
-- 通过连接查询来实现
select classes.name from classes inner join students on classes.id = students.cls_id;
-- 查找哪些班级没有学生
select classes.name from classes where classes.id not in (select distinct cls_id from students);
- 行级子查询
-- 查找班级年龄最大,身高最高的学生
select * from students where (age, height) = (select max(age), max(height) from students);
- 表级子查询 子查询语句查询出来的结果是多行多列
-- select * from students;
# 错误 select * from (select * from students); -- 需要起别名
select * from (select * from students) as temp;
数据库备份
-- 数据库备份与恢复
-- 备份 将某一台主机的数据完成一个副本的备份 mysqldump 是liunx下的指令 备份成为一个.sql文件
mysqldump -uroot -p python_test_1 > ./Desktop/xx.sql
-- 恢复 通过xxx.sql 文件将数据恢复到指定的数据库
-- 1. 新创建一个数据库
-- 2. 指定某一个数据库进行恢复操作 是linux 指令 需要退出mysql交互环境
create database pythoninfo_res charset = utf8;
mysql -uroot -p pythoninfo_res < ./Desktop/xx.sql
数据库设计
-- 数据表的三范式
- 范式1:字段的原子性,即每一个字段都是不能再分的
- 范式2:必须要有主键,且每一个字段都是依赖主键的
- 范式3:表中不可以有传递依赖,如果有,需要分表,添加外键
-- E-R模型
- 1对1: 关系字段在任何表中创建都可以, 一般是创建在使用频率比较高的表
- 1对多: 将关系字段创建在多的一方
- 多对多: 创建一个中间表, 来维护多对多的关系
小练习
-- 类似京东商城
-- 数据准备
-- 创建 "京东" 数据库
create database jing_dong charset=utf8;
-- 使用 "京东" 数据库
use jing_dong;
-- 创建一个商品goods数据表
create table goods(
id int unsigned primary key auto_increment not null,
name varchar(150) not null,
cate_name varchar(40) not null,
brand_name varchar(40) not null,
price decimal(10,3) not null default 0,
is_show bit not null default 1,
is_saleoff bit not null default 0
);
插入数据
-- 向goods表中插入数据
insert into goods values(0,'r510vc 15.6英寸笔记本','笔记本','华硕','3399',default,default);
insert into goods values(0,'y400n 14.0英寸笔记本电脑','笔记本','联想','4999',default,default);
insert into goods values(0,'g150th 15.6英寸游戏本','游戏本','雷神','8499',default,default);
insert into goods values(0,'x550cc 15.6英寸笔记本','笔记本','华硕','2799',default,default);
insert into goods values(0,'x240 超极本','超级本','联想','4880',default,default);
insert into goods values(0,'u330p 13.3英寸超极本','超级本','联想','4299',default,default);
insert into goods values(0,'svp13226scb 触控超极本','超级本','索尼','7999',default,default);
insert into goods values(0,'ipad mini 7.9英寸平板电脑','平板电脑','苹果','1998',default,default);
insert into goods values(0,'ipad air 9.7英寸平板电脑','平板电脑','苹果','3388',default,default);
insert into goods values(0,'ipad mini 配备 retina 显示屏','平板电脑','苹果','2788',default,default);
insert into goods values(0,'ideacentre c340 20英寸一体电脑 ','台式机','联想','3499',default,default);
insert into goods values(0,'vostro 3800-r1206 台式电脑','台式机','戴尔','2899',default,default);
insert into goods values(0,'imac me086ch/a 21.5英寸一体电脑','台式机','苹果','9188',default,default);
insert into goods values(0,'at7-7414lp 台式电脑 linux )','台式机','宏碁','3699',default,default);
insert into goods values(0,'z220sff f4f06pa工作站','服务器/工作站','惠普','4288',default,default);
insert into goods values(0,'poweredge ii服务器','服务器/工作站','戴尔','5388',default,default);
insert into goods values(0,'mac pro专业级台式电脑','服务器/工作站','苹果','28888',default,default);
insert into goods values(0,'hmz-t3w 头戴显示设备','笔记本配件','索尼','6999',default,default);
insert into goods values(0,'商务双肩背包','笔记本配件','索尼','99',default,default);
insert into goods values(0,'x3250 m4机架式服务器','服务器/工作站','ibm','6888',default,default);
insert into goods values(0,'商务双肩背包','笔记本配件','索尼','99',default,default);
-- 一般查询
-- 求所有商品的平均价格,并且保留两位小数
select round(avg(price), 2) from goods;
-- 查询所有价格大于平均价格的商品,并且按价格降序排序
-- 标量子查询
select * from goods where price > (select avg(peice) from goods) order by price desc;
-- 查询类型cate_name为 '超级本' 的商品名称、价格
select name, price from goods where cate_name = '超级本';
-- 显示商品的种类
select cate_name from goods gruop by cate_name;
select distinct cate_name from goods;
-- 显示每种类型的商品的平均价格
select cate_name, avg(price) from goods group by cate_name;
-- 查询每种类型的商品中 最贵、最便宜、平均价、数量
select cate_name, max(price), min(price), avg(price), count(*) from goods group by cate_name;
-- 查询每种类型中最贵的商品信息
select goods.* from goods inner join (select cate_name, max(price) as max_price from goods group by cate_name) as temp on goods.cate_name = temp.cate_name and goods.price = temp.max_price;
-- 通过行级子查询也可以实现该需求
select * from goods where (cate_name, price) in (select cate_name, max(price) from goods group by cate_name);
-- 创建商品分类表
create table if not exists good_cates(
id in unsigned primary key auto_increment,
name varchar(40) not null
);
-- insert into xx表 () values (), (),...; 需要手动写比较麻烦
-- insert ... select
-- 子查询语句
-- 在sql中所有的语句都称为查询语句
-- 结构化查询语言
-- 查询到的数据的字段需要和插入数据表指定的字段一一对应
insert into goods_cates (name) select cate_name from goods group by cate_name;
-- 连接更新
-- 根据goods_cates 表 更新goods 表
-- 根据goods_cates表来更新goods表
-- update xxx inner join xx on xx = xx set col = value ;
update goods inner join goods_cates on goods.cate_name = goods_cates.name set goods.cate_name = goods_cates.id;
-- 修改表结构
alter table goods change cate_name cate_id int unsigned not null;
-- brand_name 品牌名称
-- 创建表 并且插入数据 一步到位 create ... select
-- 如果查找的数据的字段和表中的字段名不一样 此时会在表中创建一个新的名字一样的字段,将查询到的数据一一对应的自动创建的字段上面
-- 给brand_name 起别名, 或者将goods_brands表中的name 修改为brand_name
create table goods_brands (
id int unsigned primary key auto_increment,
name varchar(40) default ''
) select brand_name as name from goods group by brand_name;
--- 根据goods_brand表 来更新 goods表
update goods inner join goods_brands on goods.brand_name = goods_brands.name set goods.brand_name = goods_brands.id;
-- 修改表结构
alter table goods change brand_name brand_id int unsigned not null;
-- 获取所有的商品的完整信息
-- 连接多张表完成查询
-- 显示商品的完整信息
-- 连接多张表直接inner join 不需要and 或者 ,
select * from goods as g inner join goods_brands as b on g.brand_id = b.id inner join goods_cates as c on g.cate_id = c.id;
-- left join 左外连接查询
select * from goods as g left join goods_brands as b on g.brand_id = b.id left join goods_cates as c on g.cate_id = c.id;
-- 外键
-- 对于已经存在的表 设置外键约束--> 更新
-- 给goods表中的 brand_id 添加外键约束, goods表已经存在, 修改约束应该是用alter sql 语句
-- references: 关联或者引用
-- 添加外键约束
alter table goods add foreign key(brand_id) references goods_brands(id);
alter table goods add foreign key(cate_id) references goods_cates(id);
能否在创建表的时候就设置外键约束?
-- 在添加 cate_id外键约束的时候 必须是goods_cates表已经被创建才能够添加外键约束
-- 删除外键
-- alter table goods drop foreign key 外键约束的名字;
-- 如何获取外键约束的名字
alter table goods drop foreign key goods_ibfk_1;
alter table goods drop key brand_id;
-- 外键名称从表的创建语句中来查看
show create table goods;