@Mrliang123
2022-02-28 22:42
字数 15802
阅读 0
MySQL
产品
简介
即市场占有率最大的关系型数据库,类似于excel表格
DML:select、insert、update、delete
DDL:drop、create等
分类
常用的关系型数据库:Oracle、Microsoft SQL Server、MySQL、SQLite
常用的非关系型数据库(NoSQL,Key-Value 的方式存储数据):MongoDB、Redis
MySQL主从复制原理详解
主:打开binlog日志,并设置server id号(默认为1),创建主从复制账号;
从:打开中继日志(relay log),设置server id号(非1的任何数字);向主发送验证信息,激活主从复制,开启长连接。
从:从IO线程实时监听主的二进制日志,如有变化,便向主发送信息。
主:主IO线程将从需要的的二进制日志对应位置之后的日志复制出来发送给从,并发送新的文件名和位置。
从:将新的文件名和位置记录在master.info中,将主复制的内容放入中继日志中。
从:从的SQL线程将每次解析的中继日志的位置记录在relay-log.info文件中,并解析中继日志,把每条命令写入到data目录中。
数据库设计
三大范式
1、列的原子性,不可拆分
2、每个表必须有一个主键且非主键字段必须完全依赖主键
3、非主键字段必须直接依赖主键,不能传递依赖
E-R模型
可以考虑通过power designer,db desinger等软件来建模,从而达到相关的设计
实体: 用矩形表示,并标注实体名称
属性: 用椭圆表示,并标注属性名称
关系: 用菱形表示,并标注关系名称
关系共分为三种
1、一对一
在表A或表B中创建一个字段,存储另一个表的主键值
2、一对多
在多的一方表(学生表)中创建一个字段,存储班级表的主键值
3、多对多
新建一张表C,这个表只有两个字段,一个用于存储A的主键值,一个用于存储B的主键值
数据类型和约束
数据类型
指存储的数据类型,共分为:
- 整数:int,bit
- 小数:decimal
如 decimal(5, 2) 表示共存5位数,小数占 2 位 - 字符串:varchar,char,text
varchar表示可变长度的字符串,如varchar(3),填充'ab'时就会存储'ab',3表示字符数
char表示固定长度的字符串,如char(3),如果填充'ab'时会补一个空格为'ab ',3表示字符数
字符串 text 表示存储大文本,当字符大于 4000 时推荐使用 - 日期时间: date(年月日), time(时分秒), datetime(年月日时分秒)
- 枚举类型(enum),用法:
enum('男','女')
数据类型附录表
1、整数类型
2、字符串
3、时间类型
数据约束
在数据类型的基础上再增加额外的要求
常见的约束:
- 主键 primary key:即id号,唯一的,标识数据记录,用于区分不同记录数据
- 自增 auto_increment:自增,用于id号从小到大自增
- 非空 not null: 此字段不允许填写空值.
- 惟一 unique: 此字段的值不允许重复.
- 默认 default: 当不填写字段对应的值会使用默认值,如果填写时以填写为准.
- 外键 foreign key: 即使用某个表中的主键数据,可用于连表查询
事务
什么是事务
- 一个最小的不可分割的单元,逻辑上的一组操作,通常一个事务对应一个完整的业务,为一组sql语句,要么成功,要么失败
- 一个完整的由多个批量的DML(select、insert、update、delete)语句组成
- 事务只和DML语句有关
- 事务未成功之前只是在内容中完成记录,只有事务结束后才会记录到硬盘中
- 只有InnoDB引擎才能使用事务
引擎
常用的存储引擎为:InnoDB和MyISAM。InnoDB支持事务,MyISAM不支持事务但是访问速度快
提交事务
开启事务后变更的数据会保存到缓存中,而不是落地,mysql默认采用自动提交事务模式,即autocommit
模式,不需要手动,可直接落地
set autocommit = 0 表示取消自动提交事务模式,此为临时模式,关闭会话后自动取消,需手动执行commit
完成事务的提交,将缓存落地,也可以rollback
取消缓存,回到事务前的状态
开启事务begin
后,也需要commit
提交事务
术语
- 开启事务:Start Transaction或者
begin;
- 结束事务:End Transaction
- 提交事务:Commit Transaction
- 回滚事务:Rollback Transaction
事务的特性-ACID
如银行转账,每个转账的步骤都有多个sql执行,若执行一半后出现断电等情况就会导致只执行了一半,从而出现了一些数据丢失的情况出现,为防止此类发生需通过事务来解决,事务能保证数据的合法性
- 原子性
最小单元,无法再次分割,要么全部成功,要么全部失败(如A向B转账200,此事务要不成功要不失败)- 一致性
执行事务之前和之后必须处于一致(如A向B转账,若系统崩溃则此事务不会提交到数据库中,不会丢失数据)
- 不一致的三种情况
- 脏读
一个事务运行期间读取了另一个未提交的事务中的数据- 不可重复读
一个事务运行期间查找相同的表读取到不同的数据,可以通过行级锁防止该数据被更改或删除- 幻读
一个事务运行期间查找相同的表读取到新增的数据,通过表级锁来防止新增数据或者加上间隙锁(next-key lock)- 隔离性
多个并发的事务之间相互隔离,比如多个用户操作同一张表,数据库为每个用户开启的事务不能被其他事务干扰,如:转账这个事务未成功时,若其他汇款程序开始执行,则看到是原数据- 持久性
永久存储到硬盘中,即使系统崩溃也无影响
事务隔离的级别(select @@tx_isolation)
- 未提交读-Read-Uncommitted(0级)
即能够读取到没有提交的数据,无法解决脏读、不可重复度、幻读任何一种 - 已提交读-Read-Committed(1级)
即能够读取到已经提交的数据,写数据会锁住对应的行,只能解决脏读 - 可重复读-Repeatable-Read(2级)
当读取了一条数据,这个事务不结束其他事务就无法更改此数据,解决了脏读、不可重复度 - 串行化-Serializable(3级)
高并发多个事务时,只有运行完一个事务后才能运行其他事务,读写数据会锁住整个表,效率差
锁机制
- 表级锁
一次只能有一个事务可以访问- 行级锁(InnoDB)
并非锁住一行,主要加在索引上- 页面锁
mysql安装
ubuntu安装
service端安装:sudo apt-get install mysql-server
client端安装:sudo apt-get install mysql-client
默认配置文件路径: /etc/mysql/mysql.conf.d/mysqld.cnf
存储位置:/var/lib/mysql
错误日志: /var/log/mysql/error.log
配置
- 远程连接
1、需注释/etc/mysql/mysql.conf.d/mysqld.cnf中的bind-address=127.0.0.1
2、更改mysql库中的user表,将对应的用户改为%
,如update user set host = '%' where user='root'
3、重启mysql,service mysql restart
常用sql语句
语法 | 解释 |
---|---|
select now(); | 显示当前时间 |
show databases; | 显示所有数据库 |
show tables; | 查看数据库中的表 |
show engines; | 查看数据库支持的表的存储引擎 |
show master status; | 查看当前binlog的位置 |
show create table 表名; | 查看创建表的sql语句 |
show create database 库名; | 查看创建库的sql语句 |
show index from 表名; | 查看表中已有索引 |
create database 库名 charset=utf8; | 创建数据库,并使用 |
drop database 库名; | 删除数据库,drop无法回滚 |
drop table 表名; | 删除数据表 |
truncate table 表名; | 清空表数据 |
alter table 表名 add 列名 类型 约束; | 添加列名、类型、约束 |
alter table 表名 modify 列名 类型 约束; | 修改字段类型和约束,不能改列名 |
alter table 表名 change 原列名 新列名 类型 约束; | 修改类型、约束、列名 |
alter table 表名 drop 列名; | 删除指定列名 |
alter table old_表名 rename as new_表名; | 更改表名 |
alter table students engine='MyISAM'; | 更改表引擎 |
alter table 表名 add index 索引名(列名, ..) | 创建索引 |
alter table 表名 drop index 索引名 | 删除索引 |
desc 表名; | 查看表结构 |
use 库名; | 使用数据库 |
create table 表名(字段名1 数据类型 约束条件,字段2 数据类型 约束条件...); | 创建表,并指定表字段 |
create table 表名 like 已有表名; | 创建与现有表一样字段的新表 |
create table 表名 select * from 现有表 where...(查询语句); | 将查询结果创建新表 |
insert into 表名 value(...) | 全列插入,值的顺序需和表结构一一对应,主键列是自动增长的,但需要(0/null/default)这些空值来占位,若有默认值的列位则使用default占位 |
insert into 表名 value(值1,值2,值3...),(值1,值2,值3....) | 全列多行插入 |
insert into 表名(列1,列2...) values(值1,值2...) | 部分列插入,值的顺序要和列名对应 |
insert into 表名(列1,列2...) value(值1,值2..),(值1,值2...) | 部分列多行插入 |
insert into 表名(列1) select .. | 把查询结果插入到指定表中,也就是表复制。 |
delete from 表名 where 条件=字段; | 删除表数据中的指定行,尽量使用逻辑删除,即加一列用作标识字段 |
update 表名 set 列1=值1,列2=值2 where 条件=字段; | 更改数据 |
update 多表查询结果(不包含select * from) set 表1=列1=表2.列2; | 将多表查询的结果批量更新,即将查询结果看出一整个表进行操作 |
select database(); | 查看当前使用的数据库 |
flush logs; | 生成新的binlog文件 |
source 绝对路径 | 导入具体的sql语句 |
system clear; | 清屏 |
set profiling=1; | 开启运行时间检测 |
show profiles; | 查看sql运行时间 |
实践
- 创建数据库
create database pythontest charset=utf8;
- 创建表并设置相关字段
create table students( id int unsigned primary key auto_increment not null,
name varchar(10) not null,
age tinyint unsigned default 0,
height decimal(5,2),
gender enum('男','女'),
s_id int unsigned not null,
foreign key(s_id) references class(id);
);- 查看表字段
desc 表名
- 添加列,并指定类型、约束
alter table students add birthday datetime;
- 修改列名、类型、约束
alter table students change birthday birth date not null;
- 删除列名
alter table students drop birth;
索引
- 索引也就是一个键值对,是一个特殊的文件,可以提高查询速率
- 经常查询的表可以创建索引,但是经常更新的表不建议加索引
- 自动创建索引的两种方式:1、主键会自动创建索引;2、外键约束会自动创建
- 创建索引,若不知道索引名,默认使用列名
alter table 表名 add index 索引名(列名, ..);
- 查看表中已有索引
show index from 表名;
- 删除索引
查看索引名:show create table 表名;
删除索引:alter table 表名 drop index 索引名
联合索引
即一个索引覆盖两个或多个字段,为减少磁盘空间,可以使用联合索引
创建联合索引:alter table teacher add index (列1,列2...);
最左原则:即index(name,age)支持name、name和age组合查询,而不支持单独age查询,因为没有用到创建的联合索引
-- 下面的查询使用到了联合索引
select * from stu where name='张三' -- 这里使用了联合索引的name部分
select * from stu where name='李四' and age=10 -- 这里完整的使用联合索引,包括 name 和 age 部分
-- 下面的查询没有使用到联合索引
select * from stu where age=10 -- 因为联合索引里面没有这个组合,只有 name | name age 这两种组合
where查询
比较运算符
用法(id大于3的列举):select * from 表名 where id >3;
等于: =
大于: >
大于等于: >=
小于: <
小于等于: <=
不等于: != 或 <>
逻辑运算符
and(都满足)、or(部分满足)、not(取反)
示例:select * from 表名 where id > 3 and gender='女';
select * from 表名 where not (id > 3 and gender='女');
范围查询
- 连续范围内:
between .. and ..
如:查询编号为3至8的学生:select * from students where id between 3 and 8;
- 非连续范围内:in
如:查询编号为3,5,7的学生:select * from students where id in (3,5,7);
查询编号不为3,5,7的学生:select * from students where id not in (3,5,7);
模糊查询
like表示模糊查询的关键字,%表示多个任意字符,_表示任意一个字符
如:select * from students where name like '诸葛%';
空判断查询
查询非空的数据,null无法直接作为关键字查询
为空is null
;非空is not null
如:select * from 表名 where height is null
进阶查询
分页查询
limit后第一个参数默认是0,表示开始行索引(索引都是从0开始的),第二个是查询条数
用法:每页显示m条数据,求第n页显示的数据 select * from xxx limit (n-1)*m,m
排序
排序需使用order by;asc 升序,默认,desc 从大到小排序
示例:显示所有信息,先按照列1倒序,若列1字符相同则使用列2倒序 select * from 表名 where 条件 order by 列1 desc,列2 desc
聚合函数
聚合函数又称组函数,一般结合分组(group by)来使用
- count(col): 表示求指定列的总行数,常用*替换指定的字段做统计,若需指定字段统计建议使用主键
示例:返回非NULL数据的总行数select count(*) from students;
- max(col): 表示求指定列的最大值
示例:查询女生的编号最大值select max(id) from students where gender = 2;
- min(col): 表示求指定列的最小值
示例:查询未删除的学生最小编号select min(id) from students where is_delete = 0;
- sum(col): 表示求指定列的和
示例:查询男生的总身高select sum(height) from students where gender = 1;
- avg(col): 表示求指定列的平均值
示例:求男生的平均身高, 聚合函数不统计null值,平均身高有误select avg(height) from students where gender = 1;
- ifnull:表示判断指定字段是否为空值(null、0、default),若为空使用自己提供的值,聚合函数默认忽略字段为空的值
示例:求男生的平均身高, 包含身高是null的select avg(ifnull(height,0)) from students where gender = 1;
分组查询
用于对查询的结果按照指定字段进行分组,相同字段的结果分为一组,若指定了分组字段,查询时只能用指定分组字段
语法格式:GROUP BY 列名 [HAVING 条件表达式] [WITH ROLLUP]
having表示对分组后的数据进行过滤,类似于where
with rollup表示
- group by + group_concat()常用于对分组的内容进行聚合,每个信息之间用逗号分割
select gender,group_concat(name) from students group by gender;
+--------+----------------------------------------------+
| gender | group_concat(name) |
+--------+----------------------------------------------+
| 男 | 张飞,关羽,刘备,曹操,诸葛亮,周瑜 |
| 女 | 黄蓉,聂小倩 |
+--------+----------------------------------------------+
2 rows in set (0.00 sec)
- 和聚合函数配合,统计不同性别的人数
select gender,count(*) from students group by gender;
+--------+----------+
| gender | count(*) |
+--------+----------+
| 男 | 6 |
| 女 | 2 |
+--------+----------+
2 rows in set (0.00 sec)
- 和having配合,根据gender字段进行分组,统计分组条数大于2的
select gender,count(*) from students group by gender having count(*)>2;
+--------+----------+
| gender | count(*) |
+--------+----------+
| 男 | 6 |
+--------+----------+
1 row in set (0.01 sec)
- 和with rollup配合,在最后加一行,为聚合函数进行汇总数据
select gender,group_concat(name) from students group by gender with rollup;
+--------+---------------------------------------------------------------+
| gender | group_concat(name) |
+--------+---------------------------------------------------------------+
| 男 | 张飞,关羽,刘备,曹操,诸葛亮,周瑜 |
| 女 | 黄蓉,聂小倩 |
| NULL | 张飞,关羽,刘备,曹操,诸葛亮,周瑜,黄蓉,聂小倩 |
+--------+---------------------------------------------------------------+
3 rows in set (0.00 sec)
多表查询
内连接
查询两个表的共有字段
用法:select 字段 from 表1 inner join 表2 on 表1.字段1 = 表2.字段2
inner join 表示连接两个表;on表示连接条件
mysql> select * from students;
+----+-----------+------+--------+--------+----------+
| id | name | age | height | gender | class_id |
+----+-----------+------+--------+--------+----------+
| 1 | 张飞 | 55 | 1.75 | 男 | 1 |
| 2 | 关羽 | 58 | 1.85 | 男 | 2 |
| 3 | 刘备 | 60 | 1.75 | 男 | 1 |
| 4 | 曹操 | 58 | 1.85 | 男 | 2 |
| 5 | 诸葛亮 | 56 | 1.70 | 男 | 1 |
| 6 | 周瑜 | 50 | 1.80 | 男 | NULL |
| 7 | 黄蓉 | 26 | 1.68 | 女 | NULL |
| 8 | 聂小倩 | 25 | 1.65 | 女 | NULL |
+----+-----------+------+--------+--------+----------+
8 rows in set (0.00 sec)
mysql> select * from class;
+----+------+
| id | name |
+----+------+
| 1 | 1班 |
| 2 | 6班 |
+----+------+
2 rows in set (0.00 sec)
mysql> select s.name,c.name from students as s inner join class as c on s.class_id=c.id;
+-----------+------+
| name | name |
+-----------+------+
| 张飞 | 1班 |
| 关羽 | 6班 |
| 刘备 | 1班 |
| 曹操 | 6班 |
| 诸葛亮 | 1班 |
+-----------+------+
5 rows in set (0.00 sec)
左连接
用法:elect 字段 from 表1 left join 表2 on 表1.字段1 = 表2.字段2
以左表为主根据条件查询右表数据,如果根据条件查询右表数据不存在使用null值填充
select * from students s left join class c on s.class_id=c.id;
+----+-----------+------+--------+--------+----------+------+------+
| id | name | age | height | gender | class_id | id | name |
+----+-----------+------+--------+--------+----------+------+------+
| 1 | 张飞 | 55 | 1.75 | 男 | 1 | 1 | 1班 |
| 3 | 刘备 | 60 | 1.75 | 男 | 1 | 1 | 1班 |
| 5 | 诸葛亮 | 56 | 1.70 | 男 | 1 | 1 | 1班 |
| 2 | 关羽 | 58 | 1.85 | 男 | 2 | 2 | 6班 |
| 4 | 曹操 | 58 | 1.85 | 男 | 2 | 2 | 6班 |
| 6 | 周瑜 | 50 | 1.80 | 男 | NULL | NULL | NULL |
| 7 | 黄蓉 | 26 | 1.68 | 女 | NULL | NULL | NULL |
| 8 | 聂小倩 | 25 | 1.65 | 女 | NULL | NULL | NULL |
+----+-----------+------+--------+--------+----------+------+------+
右连接
用法:select 字段 from 表1 right join 表2 on 表1.字段1 = 表2.字段2
以右表为主根据条件查询左表数据,如果根据条件查询左表数据不存在使用null值填充
insert into class value(0,'9班');
Query OK, 1 row affected (0.00 sec)
select * from students s right join class c on s.class_id=c.id;
+------+-----------+------+--------+--------+----------+----+------+
| id | name | age | height | gender | class_id | id | name |
+------+-----------+------+--------+--------+----------+----+------+
| 1 | 张飞 | 55 | 1.75 | 男 | 1 | 1 | 1班 |
| 2 | 关羽 | 58 | 1.85 | 男 | 2 | 2 | 6班 |
| 3 | 刘备 | 60 | 1.75 | 男 | 1 | 1 | 1班 |
| 4 | 曹操 | 58 | 1.85 | 男 | 2 | 2 | 6班 |
| 5 | 诸葛亮 | 56 | 1.70 | 男 | 1 | 1 | 1班 |
| NULL | NULL | NULL | NULL | NULL | NULL | 3 | 9班 |
+------+-----------+------+--------+--------+----------+----+------+
6 rows in set (0.00 sec)
自连接
将一张表模拟成左右两张表,然后进行连表查询
mysql> create table areas(id varchar(30) not null primary key,title varchar(30) not null,pid varchar(30));
mysql> source /home/python/Desktop/areas.sql
mysql> select c.id as 省id,c.title as 省市名,c.pid as 市id,p.title as 省名 from tb_areas c inner join tb_areas p on c.pid=p.id where p.title='山西省';
+--------+-----------+--------+-----------+
| 省id | 省市名 | 市id | 省名 |
+--------+-----------+--------+-----------+
| 140100 | 太原市 | 140000 | 山西省 |
| 140200 | 大同市 | 140000 | 山西省 |
| 140300 | 阳泉市 | 140000 | 山西省 |
| 140400 | 长治市 | 140000 | 山西省 |
| 140500 | 晋城市 | 140000 | 山西省 |
| 140600 | 朔州市 | 140000 | 山西省 |
| 140700 | 晋中市 | 140000 | 山西省 |
| 140800 | 运城市 | 140000 | 山西省 |
| 140900 | 忻州市 | 140000 | 山西省 |
| 141000 | 临汾市 | 140000 | 山西省 |
| 141100 | 吕梁市 | 140000 | 山西省 |
+--------+-----------+--------+-----------+
11 rows in set (0.01 sec)
mysql> select c.id as 省id,c.title as 省市名,c.pid as 市id,p.title as 省名 from tb_areas c inner join tb_areas p on c.pid=p.id where c.title='运城市';
+--------+-----------+--------+-----------+
| 省id | 省市名 | 市id | 省名 |
+--------+-----------+--------+-----------+
| 140800 | 运城市 | 140000 | 山西省 |
+--------+-----------+--------+-----------+
1 row in set (0.00 sec)
子查询
在一个select语句中,嵌入了另外一个select语句,那么被嵌入的select语句称之为子查询语句,外部那个select语句则称为主查询。子查询为一个完整的sql语句,可以独立存在的,放于()内;子查询先执行,主查询根据子查询数据执行
补充
as
用于别名,方便展示
mysql> select name,age from students;
+--------+------+
| name | age |
+--------+------+
| 张飞 | 55 |
| 关羽 | 58 |
+--------+------+
2 rows in set (0.00 sec)
mysql> select name as 姓名,age as 年龄 from students as s;
+--------+--------+
| 姓名 | 年龄 |
+--------+--------+
| 张飞 | 55 |
| 关羽 | 58 |
+--------+--------+
2 rows in set (0.00 sec)
distinct
用于去重
实例:select distinct 列1,列2... from 表名
外键约束
添加外键约束:alter table 从表 add foreign key(外键字段) references 主表(主键字段);
删除外键约束:
1、获取外键约束名字:show create table 表名;
2、删除外键约束:alter table 表名 drop foreign key 外键名;
实践
数据准备
表结构说明:
id 表示主键 自增
name 表示商品名称
cate_name 表示分类名称
brand_name 表示品牌名称
price 表示价格
is_show 表示是否显示
is_saleoff 表示是否售完
-- 创建 "京东" 数据库
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);
mysql> desc goods;
+------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(150) | NO | | NULL | |
| cate_name | varchar(40) | NO | | NULL | |
| brand_name | varchar(40) | NO | | NULL | |
| price | decimal(10,3) | NO | | 0.000 | |
| is_show | bit(1) | NO | | b'1' | |
| is_saleoff | bit(1) | NO | | b'0' | |
+------------+------------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)
-- 创建商品分类表(因为只增加一个商品分类,但不写入具体的商品信息,因此需再增加一个表)
create table good_cates(
id int not null primary key auto_increment,
name varchar(50) not null
);
-- 查询goods表中商品的分类信息
select cate_name from goods group by cate_name;
-- 将查询结果插入到good_cates表中
insert into good_cates(name) select cate_name from goods group by cate_name;
-- 添加移动设备分类信息
insert into good_cates(name) values('移动设备');
-- 查看goods表中的商品分类名称对应的商品分类id
select * from goods g inner join goods_cates gs on g.cate_name = gs.name;
-- 将goods表中的分类名称更改成商品分类表中对应的分类id,连接更新表中的某个字段
update goods g inner join goods_cates gs on g.cate_name = gs.name set g.cate_name = gs.id;
-- 通过create table ...select来创建商品品牌表并且同时插入数据,其中插入的数据需和创建的表名相同,可以用as改
create table good_brands(id int unsigned not null primary key auto_increment,name varchar(50) not null) select brand_name as name from goods group by brand_name;
-- 插入双飞燕品牌
insert into goods_brands(name) values('双飞燕');
-- 查看goods表中的商品品牌对应的商品品牌id
select * from goods g inner join goods_brands gs on g.brand_name = gs.name;
-- 将goods表中的品牌更改成品牌表中对应的品牌id,连接更新表中的某个字段
update goods g inner join goods_brands gs on g.brand_name = gs.name set g.brand_name = gs.id;
-- 通过alter table语句修改表结构,把cate_name改成cate_id,把brand_name改成brand_id
alter table goods change cate_name cate_id int not null,change brand_name brand_id int not null;
相关sql
- 查询类型cate_name为 '超级本' 的商品名称、价格
select name, price from goods where cate_name = '超级本';
- 显示商品的分类
select distinct cate_name from goods;
select cate_name from goods group by cate_name;
- 求所有电脑产品的平均价格,并且保留两位小数
select round(avg(price),2) from goods;
- 显示每种商品的平均价格
select cate_name, avg(price) from goods group by cate_name;
select cate_name, round(avg(price),2) from goods group by cate_name;
- 查询每种类型的商品中 最贵、最便宜、平均价、数量
select cate_name, max(price), min(price), avg(price), count(*) from goods group by cate_name
- 查询所有价格大于平均价格的商品,并且按价格降序排序
select * from goods where price > (select avg(price) from goods) order by price desc;
- 将查询结果插入到good_cates表中
insert into good_cates(name) select cate_name from goods group by cate_name;
@Mrliang123
2022-02-28 22:42
字数 15802
阅读 0