MySQL用法实战 #电商数据库 #拆表 #表的设计规范 #军规

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_44925501/article/details/102755145

一、创建一个电商数据库

1)创建数据库数据表

create database shop charset=utf8;
use shop;

--we need id,商品name,分类cate,品牌brand,价格price,是否显示,是否卖光
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
);

2)插入数据

  • test.sql文件上传在附件。用命令行导入。mysql>. 路径/test.sql
  • 不想下载的,可以复制下方代码。

insert into goods values(0,‘r510vc 15.6英寸笔记本’,‘笔记本’,‘华硕’,‘3399’,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英寸平板电脑’,‘平板电脑’,‘苹果’,‘1999’,default,default);
insert into goods values(0,‘iPad air 9.7英寸平板电脑’,‘平板电脑’,‘苹果’,‘3388’,default,default);
insert into goods values(0,‘iPad mini 配置 retine 显示屏’,‘平板电脑’,‘苹果’,‘2788’,default,default);
insert into goods values(0,‘ideacentre c3340 20英寸一体电脑’,‘台式机’,‘联想’,‘3499’,default,default);
insert into goods values(0,‘vostro 3800-r1206 台式电脑’,‘台式机’,‘戴尔’,‘2899’,default,default);
insert into goods values(0,‘15.6 寸电脑屏保护膜’,‘电脑配件’,‘爱戴尔’,‘29’,default,default);
insert into goods values(0,‘优雅 复古 无线鼠标键盘’,‘电脑配件’,‘雷蛇’,‘299’,default,default);
insert into goods values(0,‘15寸 4K 液晶显示屏’,‘电脑配件’,‘索尼’,‘1899’,default,default);
insert into goods values(0,‘限量款 LOL 鼠标垫’,‘电脑配件’,‘唯爱’,‘29’,default,default);
在这里插入图片描述
default表示: 这个地方就填默认值

如果乱码,可以用set character_set_results=utf8;其中编码格式按照实际需要选择(哪个不乱选哪个。终端上方,右键,属性,可以看到编码。)。

3)练习各类sql 语句

  1. 找到所有平板电脑及显示价格

select name as ‘品名’,price as ‘价格’ from goods where cate_name=‘平板电脑’;
在这里插入图片描述

  1. 找到所有商品种类

select distinct cate_name as ‘商品种类’ from goods;
在这里插入图片描述

  • 第二种方法

select cate_name as ‘商品种类’ from goods group by cate_name;
在这里插入图片描述

  1. 展示每个种类下所有商品

select cate_name as ‘商品种类’,group_concat(name) from goods group by cate_name;
在这里插入图片描述

  1. 求所有产品的平均价格,并且保留两位小数。

select round(avg(price),2) from goods;
在这里插入图片描述

  1. 求每种商品的平均价格

select cate_name as ‘商品种类’,round(avg(price),2) from goods group by cate_name;
在这里插入图片描述

  1. 查询每种商品中最贵的,最便宜的,平均的,以及数量

select cate_name as ‘商品种类’,max(price),min(price),avg(price),count(price) from goods group by cate_name;
在这里插入图片描述

  1. 查询所有价格大于平均价格的商品,并且按价格降序排序

select * from goods where price>(select avg(price) from goods) order by price desc;
在这里插入图片描述

  1. 查询每种类型中最贵的产品信息

(一) 找到突破口

select cate_name as ‘商品种类’,max(price) from goods group by cate_name;
目前我们能得到一个表,储存了每种商品的最大值。这个结果表,我们看作是新表。可以用连接!

(二)完成代码

select * from goods inner join (select cate_name,max(price) as price from goods group by cate_name) as maxgoods on goods.cate_name=maxgoods.cate_name and goods.price=maxgoods.price;
把(一)中代码用括号装起来,取别名,就可以用了。
在这里插入图片描述
有列级子查询,行级子查询。上面这个叫表级子查询。再前面select avg(price) from goods得出一个数,可以直接用的,叫行级子查询。

(三)如果插入新的一行会怎样?

select goods.cate_name,goods.name,goods.brand_name,goods.price from goods inner join (select cate_name,max(price) as price from goods group by cate_name) as maxgoods on goods.cate_name=maxgoods.cate_name and goods.price=maxgoods.price order by goods.cate_name desc;
在这里插入图片描述

4)拆开这张表

我们接下来,把goods表拆了,多拆出一张分类表cates(id,name)

  1. 创建一个名为cates的新表

create table cates(id int unsigned primary key auto_increment not null,name varchar(40) not null);

  1. 接下来要插入数据。

--思路是:把goods中的品名弄到cates的name中,且不能重复。可以用select distinct cate_name from goods;
--不能用values。insert in的原理是,插入到表(字段),插入的值为一个列子表(只有一列)。而value相当于把后面的值封装为一个列子表。
insert into cates(name) select distinct cate_name from goods;

3.把goods表中的cate_name的品名,换成cates表中对应的id。

--第一条思路是:update 一个表 set 字段=值;
--第二条思路是:goods表与cates表内连接,排列组合成一张大表。然后加上条件,获得goods表品名,与cates表名字相同的记录表。goods inner join cates on cates.name=goods.cate_name
--先把第二个思路得到的表,放入第一个思路里。
update goods inner join cates on cates.name=goods.cate_name set 字段=值;
--再把 字段=值 选好。goods.cate_name=cates.id
          ↓最终代码↓
update goods inner join cates on cates.name=goods.cate_name set goods.cate_name=cates.id;
--假如只显示部分,聚合函数相关的,比如max(price)之类的,那么字段名是不是会为max(price)?怎样使用这个字段名,而不被程序理解为函数呢?as 取别名

  1. 更新这个表结构,使cate_name变为cate_id int。

alter table goods change cate_name cate_id int unsigned not null;

  1. 添加外键限制 alter table 表1 add foreign key (表1的字段) references 表2(id);

alter table goods add foreign key (cate_id) references cates(id);

  • 哎呀呀,报错了3780 (HY000):怎么解决呢?
  • 3780 (HY000)报错的解决
    报错是由于不兼容。就有两种可能,其一是编码不兼容,其二是字段类型约束不兼容。

1>编码不兼容

看编码: show create table 表名;
改编码: alter table 表名 convert to character set utf8;

2> 字段类型约束不兼容

看字段类型约束:  desc 表名;
要改到一致 alter table 要链接外键那个表的表名 modify 字段名 类型约束;

  1. 再次执行添加外键的语句,添加成功!

5)再次拆开这张表

我们接下来,把goods表拆了,多拆出一张品牌表brands(id,name)

  1. 创建一个名为brands的表,并插入数据。

--写一个新建表的代码:create table brands(id int unsigned primary key auto_increment not null,name varchar(40) not null);
--再写一个我们需要的品牌列子表:select distinct brand_name from goods;
组合:create table brands(id int unsigned primary key auto_increment not null,name varchar(40) not null) select distinct brand_name from goods;
--那么问题来了?新建表没问题,列子表也没问题。可是,凭什么列子表就是插在name字段里?为什么不是ID,如果换一张表,为什么不是其他的?
--当这个新表brands里的字段名与插入的列子表的字段名相同的时候,就可以准确定位。如果不相同怎么办?用as取取别名,改变这个列子表的字段名呗。
          ↓最终代码↓
create table brands(id int unsigned primary key auto_increment not null,name varchar(40) not null) select distinct brand_name as name from goods;

  1. 修改表多个结构

alter table 表名 修改方式1 字段名1 类型约束1,修改方式2 字段名2 类型约束2;
--关键是用逗号隔开
举个栗子: alter table sheet change col1 colnew int(10),modify col2 int(13);

  1. 查看创建语句:show create table goods;

在这里插入图片描述
--红色框里的意思是:约束  `外键名`  外键  (`外键所在字段`) 参考了 `另一张表` (`的 id字段`)

  1. 实际开发中,很少会用到外键的约束,会很大地影响表更新的效率

删除外键
alter table 表名 drop foreign key `外键名称`
ex: alter table goods drop foreign key `goods_ibfk_1`,drop foreign key `goods_ibfk_3`;

猜你喜欢

转载自blog.csdn.net/weixin_44925501/article/details/102755145