MySQL【四】---案例实战{拆分多表、外键创建等}
1.准备数据
数据准备
create database jing_dong charset = utf8mb4;
创建一个商品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(50) not null,
price decimal(10,3) not null default 0,
is_show bit not null default 1,
is_saleoff bit not null default 0);
分别表示id,名字,类别名,品牌名,价格,是否显示,是否售罄。
插入数据:
insert into goods values (0,'r510vc 15.6英寸笔记本','笔记本','华硕','3399',default,default), (0,'y400n 14.0英寸笔记本电脑','笔记本','联想','4999',default,default), (0,'g150th 15.6英寸笔记本','游戏本','雷神','8499',default,default), (0,'x550cc 15.6英寸笔记本','笔记本','华硕','2799',default,default), (0,'x240 超级本','超级本','联想','4880',default,default), (0,'u330p 13.3英寸超级本','超级本','联想','4299',default,default), (0,'svp13226scb 触控超级本','超级本','索尼','7999',default,default), (0,'ipad mini 7.9英寸平板电脑','平板电脑','苹果','1998',default,default), (0,'ipad air 9.7英寸平板电脑','平板电脑','苹果','3388',default,default), (0,'ipad mini 配备retina显示屏','平板电脑','苹果','2788',default,default), (0,'ideacentre c340 20英寸一体电脑','台式机','联想','3499',default,default), (0,'vostro 3800-r1206 台式电脑','台式机','戴尔','2899',default,default), (0,'imac me086ch/a 21.5英寸一体电脑','台式机','苹果','9188',default,default), (0,'at7-7414lp 台式电脑 linux','台式机','苹果','3699',default,default), (0,'z220sff f4f06pa工作站','服务器/工作站','惠普','4288',default,default), (0,'powereedge ii服务器','服务器/工作站','戴尔','5388',default,default), (0,'mac pro专业级台式电脑','服务器/工作站','苹果','28888',default,default), (0,'hmz-t3w 头戴显示设备','笔记本配件','索尼','6999',default,default), (0,'商务双肩背包','笔记本配件','索尼','99',default,default), (0,'x3250 m4机架式服务器','服务器/工作站','ibm','6888',default,default), (0,'商务双肩背包','笔记本配件','索尼','99',default,default);
查看数据表:

2. SQL语句实战:
1查找超级本:select * from goods where cate_name='笔记本';
select name,price from goods where cate_name='笔记本';
select name as 商品名称,price as 商品价格 from goods where cate_name='笔记本';

2查看品牌的分类:select distinct brand_name from goods;
select brand_name from goods group by brand_name;

select brand_name,group_concat(name) from goods group by brand_name;

group by功能对于后续更加强大。
求所有电脑的平均价格:
select avg(price) from goods;
求所有电脑的平均价格并保留2位小数:
select round(avg(price),2) from goods;

显示每种商品的平均价格:
select cate_name,avg(price) from goods group by cate_name;

显示每种类型的商品中,最贵、最便宜、平均价、数量:
select cate_name,max(price) as 最贵,min(price) as 最便宜,avg(price) as 平均,count(*) as 数量 from goods group by cate_name;

- 查询所有价格大于平均价格的商品,并且按价格降序排序:
select id,name,price from goods where
price > (select round(avg(price),2) as avg_price from goods) order by price desc;

- 查询每种最贵的商品的信息:
首先得到每种最贵价格电脑:
select cate_name,max(price) from goods group by cate_name;

然后将最大值表和原表关联【可以inner join 或者 left join on】

left join on方法:
select * from (select cate_name,max(price) as max_price from goods group by cate_name) as g_new
left join goods as g
on g_new.cate_name=g.cate_name and g_new.max_price=g.price;

来写一个综合的:
select * from goods
inner join(
select cate_name,max(price) as max_price,min(price) as min_price,avg(price) as avg_price,count(*) as num from goods group by cate_name) as goods_new
on goods_new.cate_name=goods.cate_name and goods_new.max_price=goods.price;

如果出现相同的价格则需要,对品牌进行排序();
select g_new.cate_name,g.name,g.price from (select cate_name,max(price) as max_price from goods group by cate_name) as g_new
left join goods as g
on g_new.cate_name=g.cate_name and g_new.max_price=g.price order by g_new.cate_name;
显示信息筛选一下:

3. 拆分为多个表(商品分类表)
所有数据都在一个表中会导致修改麻烦,
create table if not exists goods_cates(
id int unsigned primary key auto_increment,name varchar(40) not null);
if not exists 如果表存在则不建立,不存在则建立。

3.1 去重复存储---分组:
查询goods表中商品的种类
select cate_name from goods group by cate_name;


把name插入即可;
- 将分组结果写入到goods_cates数据表中
insert into goods_cates(name) select cate_name from goods group by cate_name;
**注意这里不用values
select * from goods_cates;

之后把主表中的cate_name 改成新建的goods_cates的Id
SET是SQL Server 中对已经定义的变量赋值的方式,经常与update语句一起使用。
3.2同步表数据
通过goods_cates数据表来更新goods表
update goods as g inner join goods_cates as c on g.cate_name=c.name set g.cate_name=c.id;
关联修改成功:

3.3 修改表结构
同时发现对应表类型不同

- 更改表结构:
alter table goods
change cate_name cate_id int unsigned not null,
change brand_name brand_id int unsigned not null;
写:int unsigned 保证表结构相同都是 int类型且数值范围相同,

- 设置外键
关联cate_id和表goods_cate的id
外键约束也可以在修改表时添加,但是添加外键约束的前提是:从表中外键列中的数据必须与主表中主键列中的数据一致或者是没有数据。
在修改数据表时添加外键约束的语法格式如下:
ALTER TABLE <数据表名> ADD CONSTRAINT <外键名>
FOREIGN KEY(<列名>) REFERENCES <主表名> (<列名>);
- 删除外键约束
当一个表中不需要外键约束时,就需要从表中将其删除。外键一旦删除,就会解除主表和从表间的关联关系。
删除外键约束的语法格式如下所示:
ALTER TABLE <表名> DROP FOREIGN KEY <外键约束名>;
约束如下:
alter table goods add foreign key (cate_id) references goods_cates(id);
通过cate_id关联到goods_cates中的id。
这样保证数据唯一性,插入数据不会越界。
3.4 修改brands_name品牌如上述
- 创建表和插入数据一起操作
create table goods_brands(
id int unsigned primary key auto_increment,
name varchar(40) not null) select brand_name as name from goods group by brand_name;
需要注意:brand_name as name 需要与创建一致

- 同步数据(关联)
update goods as g inner join goods_brands as b on g.brand_name=b.name
set g.brand_name=b.id;

- 修改表结构【修改名字+类型】
alter table goods change brand_name brand_id int unsigned not null;


- 添加外键
alter table goods add foreign key (brand_id) references goods_brands(id);
show create table goods;

可以看到约束(外键)
如何取消外键约束呢?
show create table goods;
alter table goods drop foreign key 外键名称;
外键名称
alter table goods drop foreign key goods_ibfk_1;

在实际开发中,很少使用外键约束,会极大的降低表更新效率;
mysql存储在硬盘上,性能比较差,cpu>内存>固态>机械硬盘:
MySQL【四】---案例实战{拆分多表、外键创建等}的更多相关文章
- Oracle系统表外键的更名
正在看的ORACLE教程是:Oracle系统表外键的更名. Oracle中表的外键是保证系统参照完整性的手段,而参照完整性是指分布在两个表中的列所满足的具有主从性质的约束关系.外键涉及到两个表,其中一 ...
- sql查询指定表外键约束
//////////////////查询指定表外键约束select a.name as 约束名, object_name(b.parent_object_id) as 外键表, d.name as 外 ...
- 13)django-ORM(连表一对多,外键创建,创建数据,3种查询)
一对多需要使用外键 一:外键创建ForeignKey b=models.ForeignKey(to="Business",to_field=("id"))#dj ...
- SQL语句添加表外键
ALTER TABLE 表名 ADD CONSTRAINT FK_ID FOREIGN KEY(外键列) REFERENCES 外键表(外键表主键)
- rest framework 序列化之depth遇到用户表外键的尴尬情况
rest framework 序列化之depth遇到用户表外键的尴尬情况 问题:ModelSerializer序列化使用depth=1直接扩表把用户表所有信息查询出来的情况 class xxxSeri ...
- 【Django drf】 序列化类常用字段类和字段参数 定制序列化字段的两种方式 关系表外键字段的反序列化保存 序列化类继承ModelSerializer 反序列化数据校验源码分析
目录 序列化类常用字段类和字段参数 常用字段类 常用字段参数 选项参数 通用参数 序列化类高级用法之source source填写类中字段 source填写模型类中方法 source支持跨表查询 定制 ...
- MySQL数据库(3)- 完整性约束、外键的变种、单表查询
一.完整性约束 在创建表时候,约束条件和数据类型的宽度都是可选参数. 作用:用于保证数据的完整性和一致性. 1.not null(不可空)与default 示例一:插入一个空值,如下: mysql&g ...
- MySQL数据库(4)_MySQL数据库外键约束、表查询
一.外键约束 创建外键 --- 每一个班主任会对应多个学生 , 而每个学生只能对应一个班主任 ----主表 CREATE TABLE ClassCharger( id TINYINT PRIMARY ...
- mysql概要(十四)索引(补充:外键级联操作)
[ ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ][ ON UPDATE { NO ACTION | CASCADE | SE ...
- mysql 删除表 外键出错
MySQL库中有俩表,table1和table2,相互关联,在删除表的时候出错: Cannot delete or update a parent row: a foreign key constra ...
随机推荐
- 一个IT老码农的创业和生活(一)抑郁和自杀
2019年2月18日,离我的38周岁生日还差两个月,我的编程培训班"源栈"开张了. 在此之前,从我2002年大学毕业,6年时间,我先后做过英语教师.实习律师.公司法务.装修公司 ...
- 深挖 Rundll32.exe 的多种“滥用方式”以及其“独特”之处
恶意软件作者通常会编写恶意软件模仿合法的Windows进程.因此,我们可能会看到恶意软件伪装成svchost.exe.rundll32.exe或lsass.exe进程,攻击者利用的就是大多数Windo ...
- JS 实现 HashMap
HashMap代码(这种实现方式是错误的,错误原因:代码中_map._length变量是HashMap的所有实例共用的): /** * HashMap * 2021年09月09日 */ (functi ...
- springboot 整合 ehcahe后,实现缓存数据 应用关闭时序列化(磁盘持久化),重启再加载
ehcache使用很长时间了,但是却没有用到缓存数据序列化(C#中是这么个说法)与再加载.这次因为业务中需要对缓存数据进行临时存储并再加载使用,实现该功能的方式多种多样.既然ehcache有磁盘保存机 ...
- Codeforces Round #653 (Div. 3) 题解
记第一场CF赛,完成3道题 代码更新(降低时间复杂度和修改写法):21.1.23 A题 Required Remainder 题意:给你 x.y.n 求最大的k (k<=n) 使得k%x==y ...
- K8s 网关选型血泪史
Sealos 公有云几乎打爆了市面上所有主流的开源网关,本文可以给大家很好的避坑,在网关选型方面做一些参考. Sealos Cloud 的复杂场景 Sealos 公有云上线以来,用户呈爆发式增长,目前 ...
- Python实现PowerPoint(PPT/PPTX)到PDF的批量转换
如果需要处理大量的PPT转PDF的工作,一个个打开并另存为PDF是非常费时的做法.我们可以利用Python编程语言的强大的工具来自动化这个过程,使得批量转换变得简单而高效.本文将介绍如何使用Pytho ...
- 万字血书Vue-Vue进阶
Vue进阶 生命周期 组件运行的过程 组件的生命周期是:组件从创建->运行(渲染)->销毁的整个过程,是一个时间段 如何监听组件的不同时刻 vue框架为组件内置了不同时刻的生命周期函数,是 ...
- 文心一言 VS 讯飞星火 VS chatgpt (185)-- 算法导论14.1 2题
二.用go语言,对于图 14-1中的红黑树 T 和关键字 x.key 为35的结点x,说明执行 OS-RANK(T,x) 的过程. 文心一言: 在红黑树中,OS-RANK(T, x) 是一个操作,用于 ...
- Mongo-文档主键-ObjectId
文档主键 文档主键时 _id,如果插入文档时,没有传入则自动生产ObjectId 作为文档主键 文档主键要求在集合中唯一 文档主键可以时另一个文档,被当作字符串对象处理 ObjectId对象 获取文档 ...