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 ...
随机推荐
- Mac 安装 cnpm
npm set registry https://registry.npm.taobao.org npm set disturl https://npm.taobao.org/dist npm cac ...
- Flink异步IO
本文讲解 Flink 用于访问外部数据存储的异步 I/O API. 对于不熟悉异步或者事件驱动编程的用户,建议先储备一些关于 Future 和事件驱动编程的知识. 对于异步 I/O 操作的需求 在与外 ...
- redis管道技术pipeline二——api
package spring.redis; import org.springframework.beans.factory.InitializingBean; import org.springfr ...
- freeswitch的distributor模块
概述 freeswitch 是一款简单好用的VOIP开源软交换平台. 当呼叫是同一个入中继,但是有多条出中继时,需要对出中继做负载均衡,mod_distributor模块可以完成对应的配置和路由. m ...
- java项目实战-spring-基本用法01-day24
目录 1. spring 简单介绍 2. IOC/DI --控制反转--是啥 3. 实现 3. 如果 对象的 属性为引用数据类型 如何 实例化对象 4 如何用注解的方式 以少量的代码实现对象的创建于获 ...
- 常见的IE布局兼容问题
(1) div 中内容在IE和火狐中居中问题: (2)高度的问题,div出现重叠 (3)浮动引发的问题如外围DIV无法框住内部元素: (4)IE浮动margin产生双倍距离-display:inli ...
- Linux-远程连接-ssh
- Go-获取文件MD5值
获取文件的MD5值 crypto/md5 encoding/hex package filetools import ( "crypto/md5" "encoding/h ...
- [转帖][java] GC (Allocation Failure)日志分析
日前查看某个程序的日志,发现一直在报GC相关的信息,不确定这样的信息是代表正确还是不正确,所以正好借此机会再复习下GC相关的内容: 以其中一行为例来解读下日志信息: [GC (Allocation F ...
- [转帖]细说ASCII、GB2312/GBK/GB18030、Unicode、UTF-8/UTF-16/UTF-32编码
参考: <编码标准-GB2312 GBK GB18030> <字符编码笔记:ASCII,Unicode 和 UTF-8> <字体编辑用中日韩汉字Unicode编码表> ...