MySQL-lesson03 SQL基础应用

1、SQL的介绍

  1. 结构化查询语言
  2. 5.7 以后符合SQL92严格模式
  3. 通过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 : 注释

表属性:

  1. 存储引擎:InnoDB(默认的)
  2. 字符集和排序规则:utf8、utf8mb4

建表规范:

  1. 表名小写;不能是数字开头;表名和业务有关;名字不能太长(不超过15字符);不能使用关键字
  2. 必须设置字符集和存储引擎
  3. 数据类型,合适、简短、足够
  4. 必须要有主键
  5. 每个列尽量设置 not null,不知道填啥,设定默认值
  6. 每个列都要有注释

修改表定义:

# 查看建表语句
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操作,对与表段中的数据页进行清空,速度快.
  • 伪删除:添加状态列,实现伪删除
  1. 添加一个状态列state enum(1,0) ,默认为1
    alter table sc add state enum('1','0') not null default '1';
  2. 原本要修改的数据,修改state状态为0
    update sc set state='0' where sno=1;
  3. 修改应用语句,即查找时根据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的城市(城市名、国家代号、人口数)

  1. 传统连接:表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;

  2. 标准连接: 表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

你可能感兴趣的:(MySQL-lesson03 SQL基础应用)