MySQL内置功能
连接数据库
提供内置命令
help 打印mysql命令帮助
\c ctr+c 结束上个命令运行
\q ctrl+d exit quit 退出mysql
\G 把结果竖起来显示
source . 恢复备份
SQL的基础应用
SQL的介绍
结构化查询语言,遵循SQL92标准(SQL_MODE),所有关系型数据库通用命令
SQL种类
- DDL 数据定义语言
- DCL 数据控制语言
- DML 数据操作语言
- DQL 数据查询语言
SQL引入
库
- 库名
- 库属性(字符集,排序规则)
表
- 表名
- 表属性(字符集,排序规则,存储引擎)
列
- 列名
- 列属性(数据类型,约束,其他属性)
字符集
字符集相当于mysql的加密工具,在A上使用一个字符集将SQL语句写成符合这个字符集的16进制,则在B上也应用相同字符集,将16进制的数据,给翻译过来
- utf8(占用3个字节)
- utf8mb4(占用4个字节,可以存储emoji字符,生产常用)
- 其他如 gbk ,latin1
5.7默认的字符集是latin1
show charset; 查看字符集
排序规则 collation
仅以utf8mb4 为例
-
utf8mb4_general_ci
utf8mb4 默认的排序规则,不区分大小写 -
utf8mb4_bin
区分大小写,当字符中有日文,拼音时
一般ci都为不区分大小写,bin 区分大小写
数据类型
整数
tinyint: 0到255 -128到127 -256到 -1 1个字节,适合存储年龄
int: -2^31 到 2^31-1 10位数 4个字节
字符串
char: 定长,最大存储255个字符长度
varchar:变长,最多存储65533个字符,其中有2个存储字符长度(超过255用2个字节存储)
对于字符串类型的选择,不仅会影响写入,还会影响索引,查询功能
枚举类型
enum('sz','sh','bj'....)
1 2 3
在定义时,把所有的可能性都写上,然后选择。把定义的值,都加上编号。存入时,只存入编号。写入快,占用空间小
时间类型
datatime: 支持 1000-01-01 00:00:00.000000 到 9999-12-31 23:59:59.9999 ,不支持时区,设定什么就是神
timestamp: unix时间戳 1970-01-01 00.00.00.00000到2038-01-19 03:14:07 ,根据时区的变动,时间跟着变动
DDL 语句
库
- 建库
create database wordpress charset utf8mb4 collate utf8mb4_general_ci;
- 删库
drop database wordpress
- 更改库属性
alter database wordpress charset utf8;
表
列属性
- 数据类型
+约束
primary key(唯一,不为空),一般为ID列,且表中只能有一列
default: 默认值
comment: 注释
not null: 不为空,一般所有列都设为非空,防止索引失效
auto_increment: 自增
unsigned:非负数
建表规范
- 表名要小写,不能以数字开头,符合业务
- 选择合适的数据类型和长度
- 要每个列都设置not null+default .对于数字用0填充,对于字符串用“空格”填充
- 每个列都设置注释
- 表设置字符集和存储引擎
- 主键尽量使用无关的数字列,最好是自增长
- enum 类型不要保存数字,只能是字符串类型
对表的语句
- 建表
CREATE TABLE stu(
id INT PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT 'ID号',
sname VARCHAR(100) NOT NULL COMMENT '名字',
sex ENUM('m','f','n') NOT NULL DEFAULT 'n' COMMENT '性别'
) ENGINE INNODB CHARSET utf8mb4 COLLATE utf8mb4_bin
- 删除表
drop table stu
- 修改表
在stu表增加qq列
ALTER TABLE stu ADD qq VARCHAR(15) NOT NULL COMMENT 'qq号'
修改sname的数据类型
ALTER TABLE stu MODIFY sname CHAR(100) NOT NULL COMMENT '名字'
将sex列改为gender,并修改数据类型为char
ALTER TABLE stu CHANGE sex gender CHAR(4) NOT NULL COMMENT '性别'
DCL
- grant语句
grant all on *.* to root@'10.0.0.%' identified by '123456' with grant option;
- revoke 语句
revoke all on *.* from root@'10.0.0.%';
DML
- insert
# 偷懒做法,如果有审核工具,审核工具不识别
INSERT INTO wordpress.`stu1` VALUES(1,'ls','m')
# 标准做法
INSERT INTO wordpress.`stu1`(id,sname,sex) VALUES(2,'ls','m')
# 针对性插入
INSERT INTO wordpress.`stu1`(sname,sex) VALUES('ls','m')
注:server_id 单实例没有作用,在主从关系中区分不同的节点,help create database 库名;查看建库的帮助用户
DQL
show 语句的应用
show 语句主要查看数据库元数据
# 查看建库语句
show create database wordpress;
# 查看建表语句
show create table stu
#查看oldguo@'10.0.0.%'的权限
show grants for oldguo@'10.0.0.%'
select 应用
# select 单独使用(了解)
select @@port; //查看端口号
select @@basedir; //查看软件路径
select @@xxx //可以查看配置文件的配置
# 函数应用
select database(); // 查看当前所在的数据库名称
select now(); //查看前时间
# select 核心语法通用
select 列 from 表 where 条件 group by 分组列 having 条件 order by 条件 limit 行数
select 配和 from子句应用
select 列 from 表
select 配合 where 子句
select 列 from 表 where 过滤条件
1 .where 等值条件查询
2 .where不等值条件查询(>,<,>=,<=)
select name,population from city where population<100;
3 .where配合逻辑连接符(and or)
# 查询中国人口数量大于1000w的城市名和人口
select name,population from city where countrycode='CHN' and population>1000000;
# 查询中国或美国的城市名和人口数
select name,population from city where countrycode='CHN' or countrycode='USA';
3.1 between and 语法
# 查询中国和美国的城市名和人口数
select name,population from city where countrycode between 'CHN' and 'USA';
between ... and 和 and 语法一样,查询性能也一样只是写法不同。不过between .. and 只能用一列作为条件
3.2 in 语句
in 语句 和 or语法一样,查询性能也一样,写法不同。in 也只能以一列作为条件
# 查询 中国或美国的人口数和城市名
SELECT NAME,population FROM world.city WHERE countrycode IN ('CHN','USA')
4 .where 配合like子句实现模糊查询
# 查询countrycode 中有C开头的城市信息
SELECT * FROM city WHERE NAME LIKE 'C%';
也支持 like '%c'
注意:不要在前面加%,不走索引。如果业务中有大量前后都带%的查询需求,比如(百度索索,淘宝搜索栏),建议使用ES
5 .select 配合group by + 聚合函数
5.1 常用的聚合函数
MAX()
MIN()
AVG()
COUNT()
SUM()
GROUP_CONCAT() 同列多行数据转换为一行数据
CONCAT() 拼接函数
5.2 group by
group by 列 将某列中有共同条件的数据行,分成一组,在进行聚合函数的操作
# 统计每个国家的城市个数
select countrycode,count(name) from city group by countrycode
# 统计每个国家的总人口数
select countrycode,sum(population) from city group by countrycode
# 统计每个国家省的个数
select countrycode,count(DISTINCT district) from city group by countrycode
DISTINCT 表示去重
# 统计中国每个省的列表
select district group_concat(NAME) from city where countrycode='CHA' group by district
5.3 concat 拼接函数
# 统计中国每个省的列表
select concat(district,':',group_concat(NAME)) where countrycode='CHA' group by district
select 配合having应用
having 和 where条件功能一样
# 统计所有国家的总人口数量,将总人口数大于1亿的过滤出来
select countrycode ,sum(population) from city group by countrycode having sum(population) > 1000000000
where 是在group by+聚合函数 之前过滤
having 在 group by+ 聚合函数之后过滤
一般having 在放在group by 之后过滤
select 配合order by 子句
order by给最后的结果集进行排序,也可以单独使用
# 统计所有国家总人口数量,并将总人口数大于500w的过滤出来,并按照从大到小的顺序进行排序
select countrycode, sum(population) from city group by countrycode having sum(population) > 5000000 order by sum(population)
select 配合limit
limit n 表示只显示前n行
# 统计所有国家总人口数量,并将总人口数大于500w的过滤出来,并按照从大到小的顺序进行排序,只显示前3行
select countrycode,sum(population) from city group by countrycode having sum(population) > 5000000 order by sum(population) limit 3;
# 统计所有国家总人口数量,并将总人口数大于500w的过滤出来,并按照从大到小的顺序进行排序,显示 第 4行到第6行
limit 3,3 表示跳过前面3行,显示了3行
limit 3 offset 3 表示显示前3行然后偏移3行
SELECT countrycode,SUM(population) FROM city GROUP BY countrycode HAVING SUM(population) > 5000000
ORDER BY SUM(population) LIMIT 3,3
SELECT countrycode,SUM(population) FROM city GROUP BY countrycode HAVING SUM(population) > 5000000
ORDER BY SUM(population) LIMIT 3 OFFSET 3
union 和union all
主要用来提高语句的查询效率
作用:是做多个结果集合并查询的功能
# 查询中国或美国的城市信息
select * from city where countrycode='CHN' or countrycode='USA';
改写
select * from city where countrycode='CHN' union all select * from city where countrycode='USA'
多表连接查询
作用:单表数据不能满足查询需求时
# 查询世界上小于100人城市,所在国家名,国土面积,城市名,人口数
拆分
city 表
select countrycode,name,population from population<100;
country 表
select name,surface from country where code='PCN';
1 .多表连接的基本语法
1 .最核心,找到多张表之前的关联条件列
2 .列书写时,必须是表名.列名
3 .所有涉及查询的列都放在select 后面
4 .将所有的过滤,分组,排序等按条件排在on后面
select country.name,country.surface,city.name,city.population from city join country on city.countrycode = country.code where city.population < 100
2 .多张表的关联
A join B on A.x=B.y join C on B.m=c.n 先A和Bjoin,再B和C join
如果想查看A和C中的内容,但A和C没有关联联系
找一个中间表B,让A和B关联,B和C关联,这样A和C就关联起来了
别名应用
# 表别名应用(全局调用)
SELECT country.name,country.surfacearea,c.name,
c.population FROM city AS c
JOIN country ON c.countrycode=country.code
WHERE c.population < 100
# 列别名应用(group by 之后调用)
因为在group by之后才会进行列查询,列别名才会被其他的应用调用
SELECT country.name AS 国家名字,country.surfacearea AS 国家面积,
city.name AS 城市名字,
city.population AS 城市人口数
FROM city JOIN country ON city.countrycode = country.code
WHERE city.population < 100
group by的工作原理
group by name
先把name列进行排序,然后去重复,如果是索引列就不需要group by进行排序了
例:
id | name | age |
---|---|---|
1 | a | 10 |
2 | b | 12 |
3 | c | 10 |
4 | a | 12 |
group by name之后
id | name | age |
---|---|---|
1 | a | 10 |
4 | a | 12 |
2 | b | 12 |
3 | c | 10 |
如果不加上函数,a对应两个值,只能取一个即第一列。可以用avg函数或者group_concat 函数,把多行聚合成一行。
关于group by的sql_mode
only_full_group_by
说明
- 在5.7中自带的,5.6和8.0 都没有
select 支持加减乘除
select concat(10/15*100)
# concat是将列值进行拼接
多表连接的进阶说明
A join B on A.a = B.b
数据行较少的值放在左边,叫驱动表。右表列(B.b)要建立索引,否则会匹配所有数据行,驱动表是不走索引的,是遍历所有的数据和右表进行遍历,右表的列,最好是主键或者唯一列(一般在表设计方面执行的),最少也要有一个索引
select执行顺序的进阶应用
select 列 from 表 where 列 group by 列 having 列 order by 列 limit
执行逻辑中没有索引
1 .SQL层做语义检查,一般是select语句,发现是from(select 也可以加@@ 或者函数)
2 .有from意味着要从表中获取某些数据,执行open table 动作,open table不立即把所有的数据拿出来
3 .要看语句后面的条件,找到where条件,没有索引直接把整表的内容放在内存中进行过滤,形成新的内容,把多余的内存释放掉
4 .针对剩下的数据内容,通过分组(也在内存中),其余的列就会找到select 后面的列,形成了一个新表
5 .形成的表进行having过滤
6 .过滤完的数据进行order by,挨个进行比较判断
7 . 通过limit将数据显示出来
有了索引
where 条件就会受到影响,只取一小部分数据放在内存中,group by的功能也会受到索引的影响
扩展类内容,元数据获取(可以减轻DBA的劳动)
元数据
元数据是存储在基表中的。mysql无法直接进行增删改,需要通过专门的DCL和DDL语句进行修改,如建库,建表,通过专用的视图进行数据查询
information_schema 基本的应用
show: 命令是封装好功能,提供元数据查询的基本功能
information_schema: 提供了所有的查询功能
视图:把sql语句封装好成一个视图,执行sql语句时,执行执行视图就可以
创建视图: create view aa as sql语句;select * from aa;相当于执行sql语句
information_schema中的视图
TABLES 保存了数据库中所有表的元数据
desc tables; 查看视图
TABLE_SCHEMA 表所在的库名
table_name 表的名字
engine 存储引擎
table_rows 数据行
avg_row_length 平均行长度
index_length 索引长度
# 整个数据库的所有表的信息
use information_schema
SELECT table_schema,GROUP_CONCAT(table_name) FROM TABLES GROUP BY TABLE_SCHEMA
# 统计所有innodb引擎的表
SELECT TABLE_SCHEMA table_name,ENGINE FROM TABLES WHERE ENGINE="innodb"
生产常用的功能
# 统计word库,city表占用空间大小(表大小=平均行长度*行数+索引长度)
SELECT CONCAT((AVG_ROW_LENGTH*TABLE_ROWS+INDEX_LENGTH)/1024) AS "city表大小" FROM TABLES WHERE TABLE_SCHEMA="world" AND TABLE_NAME="city"
# 统计每个库的数据量大小
SELECT table_schema,SUM((AVG_ROW_LENGTH*TABLE_ROWS+INDEX_LENGTH)/1024) AS "库大小" FROM TABLES GROUP BY TABLE_schema
配合concat() 函数进行语句拼接
例子:模仿以下语句对数据库进行分库分表备份
mysqldump -uroot -p123 word city > /bak/world_city.sql
SELECT CONCAT("mysqldump -uroot -p123"," ", table_schema," ",table_name," > ","/bak/",table_schema,".",table_name) FROM TABLES;
2 .模仿以下语句,进行world库的操作
alter table world.city discard tablespace
SELECT CONCAT("alter table",table_schema,".",table_name,"discard tablespaces") FROM TABLES WHERE table_schema="world"
show语句介绍
show database;
show tables;
show grants for root@'localhost'
show create table city 查看建表语句
show creat database world 查看建库语句
show processlist
show master status;
show slave status;
show variables like '';
show engines;
show binary logs; 查看二进制日志信息
show status like '' 查看参数信息
show index from 表名; 查看索引
show engine innodb status\G; 查看innodb的引擎详细信息
show charset; 查看字符集
show collaction; 查看校对规则
show binlog events in ''; 查看二进制日志事件信息
show relay log events in '';查看中继日志的事件信息
into outfile 应用
介绍
导出批量语句,或导出查询结果
#修改配置文件
vim /etc/my.cnf
secure-file-priv= //代表可以导出任意目录
# 批量导出语句
select concat('alter talbe', ' ',table_schema,'.',table_name,' ','discard tablespace') from information_schema.tables where table_schema='world' into outfile '/tmp/world.sql'
# 批量导出查询结果,做异构平台迁移
select * from world.city where id<100 into outfile '/tmp/city.csv';