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 ...
随机推荐
- 【Django drf】认证类 权限类 频率类 过滤类 排序类 分页类
目录 认证类 前期准备 自定义认证类 配置认证类 全局配置 局部禁用 认证组件使用步骤 基于类中方法的认证(了解) 权限类 前期准备 重写has_permission() 添加权限不足信息 权限组件使 ...
- Java 剑指offer(16) 打印1到最大的n位数
题目 输入数字n,按顺序打印出从1最大的n位十进制数.比如输入3,则打印出1.2.3一直到最大的3位数即999. 思路 陷阱: n过大时是大数问题,不能简单用int或者long数据输出,需要采用字符串 ...
- 如何使不定宽高的div在父元素中水平垂直居中
1.flex布局 <div class="box"> <div class="mask"> <!-- 内容 --> < ...
- 对于 CDN 的多元理解
这是二狗子为数不多的创业故事. 那时二狗子还是一名高中生,学校是封闭式管理.由于二狗子总忍不住上课吃零食,他便每周一都会背着一麻袋零食来上学. 这上课吃零食行为,不知不觉诱惑到了周围的同学.大家纷纷向 ...
- VL02N、VL09交货单相关增强
一.业务需求 当前台操作过账发货或冲销时,需要将数据实时同步到第三方系统,因此需要开发增强 在用户出口MV50AFZ1->userexit_save_document中加入接口逻辑即可 定期更文 ...
- HDU - 1560:DNA sequence ( 迭代加深搜索基础题 )
Problem Description The twenty-first century is a biology-technology developing century. We know tha ...
- 问题--VSCODE编写C含scanf无终端跳出
1.问题 在VSCODE中编写C程序,用到scanf输入时,发现无终端输入数据 2.解决方法 在设置里搜索RunInTerminal,勾选该选项即可
- 小程序:Now you can provide attr `wx:key` for a `wx:for` to improve performance. 的解决方案
在wx:for后面添加wx:key="key" 可消除警告 <view wx:for="{{thisWeekMovies}}" wx:for-index= ...
- web - 解决 formdata 打印空对象
获取单个值可以使用formData对象.get();而直接打印是看不到的.因为外界访问不到,你使用append方法后,对应的键值对就已经添加到表单里面了,你在控制台看到的是FormData原型,存储的 ...
- 让vs支持wsl调试
WSL安装 wsl --install -d Ubuntu 等一会提示输入用户名,不用管它,直接关闭,下次打开wsl,会以无密码的root用户打开 wsl卸载 wsl --unregister Ubu ...