1、SQL的介绍
- 结构化查询语言
- 5.7 以后符合SQL92严格模式
- 通过sql_mode参数来控制
2、SQL的分类:
- DDL:数据定义语言:表的元数据管理,表名、表属性、库名、库属性
DCL:数据控制语言:grant、revoke
DML:数据操作语言:数据操作语言,操作的是表中的数据行
DQL:数据的查询语言:select
3、DDL语句
库定义:
# 创建库:
create database wordpress charset utf8;
# 创建库帮助
help create database
帮助解释:大写为必写,中括号可写可不写,小写为变量自己设置
# 删除库
drop database oldboy; //生产中禁止使用
# 修改库定义
alter database oldboy charset gbk; //注意:修改字符集,修改后的字符集一定是原字符集的严格超集
# 查看库的信息:
show databases;
# 查看建库语句:
show create database oldboy ;
建库规范:
1.库名不能出现大写
2.库名不能以数字开头
3.库名要和业务功能相关
4.建库要加字符集
表定义:
- 数据类型
int: 整数 -2^31 ~ 2^31 -1,只是正数:0-2^32-1(10位数字),当需求超过10为可用字符串类型
varchar:字符类型 (变长),用多少分多少,在存数据时,会判断字符长度
char: 字符类型 (定长),不管用多少都立即分配20个字符长度,会有磁盘空间浪费
tinyint: 整数 -128 ~ 127,只是正数:0-255
enum: 枚举类型,可能出现的类型列出来
datetime: 时间类型 年月日时分秒
TIMESTAMP:时间戳
建表示例
USE school;
CREATE TABLE stu(
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '学号',
sname VARCHAR(255) NOT NULL COMMENT '姓名',
sage TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '年龄',
sgender ENUM('m','f','n') NOT NULL DEFAULT 'n' COMMENT '性别' ,
sfz CHAR(18) NOT NULL UNIQUE COMMENT '身份证',
intime TIMESTAMP NOT NULL DEFAULT NOW() COMMENT '入学时间'
) ENGINE=INNODB CHARSET=utf8 COMMENT '学生表';
建表约束:
primary key :非空且唯一,整个表只能有一个主键,但是可以有多个列一起构成;
# 会根据主键生成聚集索引组织表,存数据时会按照主键的顺序,组织存储行数据;按照主键条件查询,是顺序IO,速度很快。
not null :非空约束
# 列值不能为空,也是表设计的规范,尽可能将所有的列设置为非空。可以设置默认值为0
unique key :唯一,但可以有多个
# 列值不能重复
unsigned:无符号
# 针对数字列,非负数。
key :索引
# 可以在某列上建立索引,来优化查询,一般是根据需要后添加
default:默认值,后面接填充值;配合 not null
# 列中,没有录入值时,会自动使用default的值填充
auto_increment:自增长
# 针对数字列,顺序的自动填充数据(默认是从1开始,将来可以设定起始点和偏移量)
comment : 注释
表属性:
- 存储引擎:InnoDB(默认的)
- 字符集和排序规则:utf8、utf8mb4
建表规范:
- 表名小写;不能是数字开头;表名和业务有关;名字不能太长(不超过15字符);不能使用关键字
- 必须设置字符集和存储引擎
- 数据类型,合适、简短、足够
- 必须要有主键
- 每个列尽量设置 not null,不知道填啥,设定默认值
- 每个列都要有注释
修改表定义:
# 查看建表语句
mysql> show create table student;
# 查看表
mysql> show tables; //生产中慎用
# 查看表中列的结构信息
mysql> desc student;
# 删表
mysql>drop table t1; //生产中禁止使用
# 创建表结构一摸一样的表
mysql>create table stu1 LIKE stu2;
mysql>create table school.stu1 LIKE student.stu2;
# 创建表结构相同,并且数据也相同的表
mysql>create table stu1 select * from stu2;
# 修改表名
mysql> alter table student rename stu;
# 添加列和列定义
mysql> alter table stu add age int;
# 添加多个列
mysql> alter table stu add test varchar(20),add qq int;
# 指定位置进行添加列(表首)
mysql> alter table stu add classid varchar(20) first;
# 指定位置进行添加列(指定列后)
mysql> alter table stu add phone char(18) not null unique comment '手机' after age;
# 删除指定的列及定义
mysql> alter table stu drop qq;
# 修改sid字段数据类型为varchar;modify 只修改属性
mysql> alter table stu modify sid varchar(20);
# 修改phone字段名为telphone,并且数据类型修改为char;change既修改名字,又修改属性
mysql> alter table stu change phone telphone char(20);
# 从物理上删除表数据,表结构不会变;危险命令,数据无法恢复
truncate table t1
4、DML语句
# 插入数据,自增长的字段可不用插入
insert into table(name,age,sex) values('zhangsan',18,'man'),('lisi',20,'man');
# 修改数据,update语句必须要加where;要确定条件是唯一值
update stu set sname='zhao4' where id=2; //如果一个where条件无法确定,再加个where
# 删除数据;危险命令!!
delete from stu where id=3;
# delete与truncate的区别
delete from stu;
truncate table stu;
delete: DML操作,是逻辑性质删除,逐行进行删除,速度慢.
truncate: DDL操作,对与表段中的数据页进行清空,速度快.
- 伪删除:添加状态列,实现伪删除
- 添加一个状态列state enum(1,0) ,默认为1
alter table sc add state enum('1','0') not null default '1'; - 原本要修改的数据,修改state状态为0
update sc set state='0' where sno=1; - 修改应用语句,即查找时根据state=1字段查找,state为0的数据则会筛选掉
select * from sc where state='1';
5、DQL语句
# 查询表的所有信息;大表禁止使用!
select * from stu;
# 查询id和name列的值
select id,name from city;
# where等值查询
select * from city where countrycode='CHN';
# where不等值查询(> < >= <= <>,不等于尽量不用)
select * from city where population<100;
# 模糊查询;注意:%不能放前面,不走索引
select countrycode,name from city where countrycode like 'ch%';
# 与and的结合,尽量做到多条件查询
select * from city where population>50000 and population<60000;
# 与or的结合,尽量不要用or查询
select * from city where countrycode='CHN' or countrycode='USA';
# 与in的结合,与or功能类似
select * from city where countrycode in ('CHN','USA');
# 与between结合,与and功能类似
select * from city where population between 50000 and 60000;
# 与having的结合; 排列顺序:where | group | having
select district,sum(Population) from city where countrycode='chn' group by district having sum(Population) < 1000000 ;
//统计中国每个省的总人口数,只打印总人口数小于1000000
- 联合查询 union all
# 用 in 查询
select * from city city where countrycode in ('CHN' ,'USA');
# 用union all 查询
select * from city where countrycode='CHN'
union all
select * from city where countrycode='USA'
# 说明:一般情况下,我们会将 in 或者 or 语句 改写成 union all,来提高性能
union //去重复
union all // 不去重复
- 常用聚合函数:
max():最大值
min():最小值
avg():平均值
sum():总和
count():个数
distinct(): 去重
group_concat(): 列转行
concat():拼接函数,可用于拼接sql语句。concat("不变的值",可变的值,"不变的值")
# 聚合函数:count(),统计数量,根据主键计算
select count(*) from city;
# group by 分组,自动去重
select countrycode,count(name) from city group by countrycode; //统计各个国家的城市个数
# sum求和;count统计的是列表里符合条件的个数,sum统计的是符合条件的数据值的和
select district,sum(population) from city where countrycode='chn' group by district;
# order by 默认从小到大排序;加上desc 从大到小排序
select * from city where countrycode='CHN' order by population desc;
# limit 分页查询;一般配合 order by 使用,做行输出限制
select district,sum(population) from city where countrycode='chn' group by district desc limit 20;
limit 10,10 //表示跳过前10行,显示后面10行
limit 10 offset 1 //跳过1行,显示后10行
多表连接查询:
查询世界上人口数量少于100的城市(城市名、国家代号、人口数)
传统连接:表A.字段1 表B.字段2 表A.字段3 from 表A,表B where 关联条件 + 过滤条件
select city.name,country.name,city.population from city,country where city.population<100 and city.countrycode=country.code;标准连接: 表A join 表B on 关联条件 where 过滤条件;使用join语句时,小表在前,大表在后
select city.name,country.name,city.population from city join country on city.countrycode=country.code where city.population<100;
- 多个表关联的话,再加一个 join C on 关联条件,以此类推
from A join B
on 关联1
join C
on 关联2
···
子查询
一个查询语句嵌套在另一个查询语句里面
select name from country where code=(select countrycode from city where population<100);
select * from country where code in (select countrycode from city where population<100);
性能较差,尽量不用
替换查询语句:
select co.name from country as co join city as ci on co.code=ci.countrycode where ci.population<100
嵌套的地方:
1、作为from的条件
2、作为where的条件
别名:
select
a.name as an ,
b.name as bn ,
b.surfacearea as bs,
a.population as bp
from city as a join country as b
on a.countrycode=b.code
where a.name ='shenyang';
information_schema.tables视图:
information_schema表:用来获取更加详细的元数据。是虚拟库,数据库启动完成后,自动统计收集。
DDL语句用间接的方式修改元数据
desc information_schema.tables //记录的是mysql 所有表的属性信息
table_schema ---->库名
table_name ---->表名
engine ---->引擎
table_rows ---->表的行数
avg_row_length ---->表中行的平均行(字节)
index_length ---->索引的占用空间大小(字节)
information_schema.tables应用示例:
# 查询整个数据库中所有库包含表的信息
SELECT table_schema,table_name
FROM information_schema.tables;
# 统计所有库下的表个数
SELECT table_schema,COUNT(table_name)
FROM information_schema.TABLES
GROUP BY table_schema
# 查询所有innodb引擎的表及所在的库
SELECT table_schema,table_name,ENGINE FROM information_schema.tables
WHERE ENGINE='innodb';
# 统计school数据库下的所有表的行数信息
select table_name,table_rows from information_schema.tables where table_schema='school';
库数据量=sum(每行数据量*行数+索引长度)/1024/1024 //单位是M
表数据量=每行数据量*行数+索引长度
# 统计每个数据库的数据量,单位为KB
select table_schema,sum(avg_row_length*table_rows+index_length)/1024 as size_kb from information_schema.tables group by table_schema;
# 统计数据库的总数据量,单位为KB
select sum(avg_row_length*table_rows+index_length)/1024 as size_kb from information_schema.tables ;
# 修改zabbix库下的所有表的引擎替换为tokudb
alter table zabbix.t1 engine=tokudb;
# 修改world库下的所有表的引擎为tokudb
select concat("alter table",table_schema,".",table_name,"engine=tokudb") from information_schema.tables where table_schema='world' ; //查出后复制粘贴执行
# 统计world数据库下每张表的磁盘空间占用
SELECT table_name,CONCAT((TABLE_ROWS*AVG_ROW_LENGTH+INDEX_LENGTH)/1024," KB") AS size_KB
FROM information_schema.tables WHERE TABLE_SCHEMA='world';
# 统计所有数据库的总的磁盘空间占用
SELECT
TABLE_SCHEMA,
CONCAT(SUM(TABLE_ROWS*AVG_ROW_LENGTH+INDEX_LENGTH)/1024," KB") AS Total_KB
FROM information_schema.tables
GROUP BY table_schema;
mysql -uroot -p123 -e "SELECT TABLE_SCHEMA,CONCAT(SUM(TABLE_ROWS*AVG_ROW_LENGTH+INDEX_LENGTH)/1024,' KB') AS Total_KB FROM information_schema.tables GROUP BY table_schema;"
# 生成整个数据库下的所有表的单独备份语句
模板语句:
mysqldump -uroot -p123 world city >/tmp/world_city.sql
SELECT CONCAT("mysqldump -uroot -p123 ",table_schema," ",table_name," >/tmp/",table_schema,"_",table_name,".sql" )
FROM information_schema.tables
WHERE table_schema NOT IN('information_schema','performance_schema','sys')
INTO OUTFILE '/tmp/bak.sh' ;
CONCAT("mysqldump -uroot -p123 ",table_schema," ",table_name," >/tmp/",table_schema,"_",table_name,".sql" )
# 107张表,都需要执行以下2条语句
ALTER TABLE world.city DISCARD TABLESPACE;
ALTER TABLE world.city IMPORT TABLESPACE;
SELECT CONCAT("alter table ",table_schema,".",table_name," discard tablespace")
FROM information_schema.tables
WHERE table_schema='world'
INTO OUTFILE '/tmp/dis.sql';
// 1、前提要配置安全路径设置
[mysqld]
secure-file-priv=/tmp
2、 /tmp/dis.sql文件存在要执行的语句;登录mysql,执行 source /tmp/dis.sql 一次性执行文件里的所有sql语句
show 命令:
show databases; #查看所有数据库
show tables; #查看当前库的所有表
SHOW TABLES FROM #查看某个指定库下的表
show create database world #查看建库语句
show create table world.city #查看建表语句
show grants for root@'localhost' #查看用户的权限信息
show charset; #查看字符集
show collation #查看校对规则
show processlist; #查看数据库连接情况
show index from #表的索引情况
show status #数据库状态查看
SHOW STATUS LIKE '%lock%'; #模糊查询数据库某些状态
SHOW VARIABLES #查看所有配置信息
SHOW variables LIKE '%lock%'; #查看部分配置信息
show engines #查看支持的所有的存储引擎
show engine innodb status\G #查看InnoDB引擎相关的状态信息
show binary logs #列举所有的二进制日志
show master status #查看数据库的日志位置信息
show binlog evnets in #查看二进制日志事件
show slave status \G #查看从库状态
SHOW RELAYLOG EVENTS #查看从库relaylog事件信息
desc (show colums from city) #查看表的列定义信息
http://dev.mysql.com/doc/refman/5.7/en/show.html
6、字符集
字符集(character)
校对规则(collation)
常用字符集:
UTF8、LATIN1、GBK
常见校对规则:
ci :大小写不敏感
cs或bin:大小写敏感
使用命令查看字符集:
show charset;
show collation;
建库设置字符集:
create database oldboy default character set utf8 default collate = utf8_general_ci;
建表设置字符集:
create table test () engine=Innodb auto_increment=13 default charset=utf8
配置字符集:
vim my.cnf
[client]
default-character-set=utf8
生产环境更改数据库字符集:
库:alter database oldboy character set utf8 collate utf8_general_ci;
表:alter table t1 character set latin1;
注意:迁移的时候注意字符集的一致,建库建表要设置字符集;更改字符集时,一定要保证由小往大改,后者必须时前者的严格超集;常用的utf8、utf8mb4、mysql8.0是utf8mb3