天天看点

SQL 语句student :学生表teacher :教师表course :课程表score :成绩表

SQL

MySQL内置功能

连接数据库

-u

-p

-S

-h

-P

-e

<

示例:

mysql -u root -p -S /tmp/mysql.sock

mysql -u root -p -h 10.0.0.51 -P3306

-e 免交互执行 sql 语句

[root@db01 ~]# mysql -uroot -p -e "show databases;"

< 导入数据

[root@db01 ~]# mysql -uroot -p123 /root/world.sql

内置命令

help 帮助

\c ctrl+c 结束上个命令运行

\q quit exit ctrl+d 退出

\G 竖行显示

source 恢复备份文件

SQL 基础应用

介绍

结构化的查询语言

关系型数据库通用的命令

遵循SQL92标准(SQL_MODE)

常用种类

DDL 数据定义语言

DCL 数据控制语言

DML 数据操作语言

DQL 数据查询语言

数据库的逻辑结构

库名

库属性(字符集,排序规则)

表名

表属性(存储引擎类型,字符集,排序规则)

列名

列属性(数据类型,约束,其他属性)

数据行

字符集(charset)

查看支持字符集 show charset

utf8 三个字符

utfmb4 四个字符(支持emoji)

排序规则(collation)

查看排序规则 show collation

英文字符串的大小写不敏感

utf8mb4_general_ci 大小写不敏感

utf8mb4_bin 大小写敏感(存拼音,日文)

数据类型

数字:tinyint int

字符串:

char(100)

定长字符串类型,不管字符串长度多长,都立即分配100个字符长度的存储空间,未占满的空间使用"空格"填充

varchar(100)

变长字符串类型,每次存储数据之前,都要先判断一下长度,按需分配此盘空间.

会单独申请一个字符长度的空间存储字符长度(少于255,如果超过255以上,会占用两个存储空间)

如何选择这两个数据类型?

少于255个字符串长度,定长的列值,选择char

多于255字符长度,变长的字符串,可以选择varchar

枚举

address enum('sz','sh','bj'.....)

可能会影响到索引的性能

时间

datetime

范围为从 1000-01-01 00:00:00.000000 至 9999-12-31 23:59:59.999999

timestamp

范围为从 1970-01-01 00:00:00.000000 至 2038-01-19 03:14:07.999999

二进制

DDL

库的定义

创建数据库

CREATE DATABASE zabbix CHARSET utf8mb4 COLLATE utf8mb4_bin;

查看库情况

SHOW DATABASES;

SHOW CREATE DATABASE zabbix;

删除数据库(不代表生产操作)

DROP DATABASE oldguo;

修改数据库字符集

注意: 一定是从小往大了改,比如utf8--->utf8mb4.

目标字符集一定是源字符集的严格超级.

CREATE DATABASE oldguo;

SHOW CREATE DATABASE oldguo;

ALTER DATABASE oldguo CHARSET utf8mb4;

库定义规范

库名使用小写字符

库名不能以数字开头

不能为数据库内部关键字

必须设置字符集

表的定义

建表

表名, 列名, 列属性, 表属性

列属性

PRIMARY KEY : 主键约束,表中只能有一个,非空且唯一.

NOT NULL : 非空约束,不允许空值

UNIQUE KEY : 唯一键约束,不允许重复值

DEFAULT : 一般配合 NOT NULL 一起使用.

UNSIGNED : 无符号,一般是配合数字列,非负数

COMMENT : 注释

AUTO_INCREMENT : 自增长的列

CREATE TABLE stu (

id INT PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT '学号',

sname VARCHAR(255) NOT NULL COMMENT '姓名',

age TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '年龄',

gender ENUM('m','f','n') NOT NULL DEFAULT 'n' COMMENT '性别',

intime DATETIME NOT NULL DEFAULT NOW() COMMENT '入学时间'

)ENGINE INNODB CHARSET utf8mb4;

建表规范

表名小写字母,不能数字开头

不能是保留字符,使用和业务有关的表名

选择合适的数据类型及长度

每个列设置 NOT NULL + DEFAULT ;对于数据0填充,对于字符使用有效字符串填充

每个列设置注释

表必须设置存储引擎和字符集

主键列尽量是无关列数字列,最好是自增长

enum类型不要保存数字,只能是字符串类型

查询表信息

SHOW TABLES;

SHOW CREATE TABLE stu;

DESC stu;

创建一个表结构一样的表

CREATE TABLE test LIKE stu;

删表(不代表生产操作)

DROP TABLE test;

修改

在stu表中添加qq列

ALTER TABLE stu ADD qq VARCHAR(20) NOT NULL COMMENT 'qq号';

在sname后加微信列

ALTER TABLE stu ADD wechat VARCHAR(64) NOT NULL UNIQUE COMMENT '微信号' AFTER sname;

在id列前加一个新列num

ALTER TABLE stu ADD num INT NOT NULL UNIQUE COMMENT '身份证' FIRST ;

DESC stu;

把刚才添加的列都删掉(危险,不代表生产操作

ALTER TABLE stu DROP num;

ALTER TABLE stu DROP qq;

ALTER TABLE stu DROP wechat;

修改sname数据类型的属性

ALTER TABLE stu MODIFY sname VARCHAR(64) NOT NULL COMMENT '姓名';

将gender 改为 sex 数据类型改为 CHAR 类型

ALTER TABLE stu CHANGE gender sex CHAR(4) NOT NULL COMMENT '性别';

DCL

grant

revoke

DML

插入数据(insert)

简单

INSERT stu VALUES(1,'zs',18,'m',NOW());

SELECT * FROM stu;

规范

NSERT INTO stu(id,sname,age,sex,intime)

VALUES (2,'ls',19,'f',NOW());

录入多行

INSERT INTO stu(sname,age,sex)

VALUES

('aa',11,'m'),

('bb',12,'f'),

('cc',13,'m');

update (一定加where条件)

UPDATE stu SET sname='aaa';

UPDATE stu SET sname='bb' WHERE id=6;

delete (一定要加where条件)

DELETE FROM stu;

DELETE FROM stu WHERE id=9;

生产中屏蔽delete功能,使用update替代delete

ALTER TABLE stu ADD is_del TINYINT DEFAULT 0 ;

UPDATE stu SET is_del=1 WHERE id=7;

SELECT * FROM stu WHERE is_del=0;

DQL

DQL介绍

SELECT

SHOW

SELECT 语句的应用

SELECT单独使用的情况

mysql> select @@basedir;

mysql> select @@port;

mysql> select @@innodb_flush_log_at_trx_commit;

mysql> show variables like 'innodb%';

mysql> select database();

mysql> select now();

SELECT通用语法表(单表)

select 列

from 表

where 条件

group by 条件

having 条件

order by 条件

limit

学习环境说明

world 数据库

city 城市表

country 国家表

countrylanguage 语言表

city表结构

ID 城市序号

name 城市名代号

countrycode 国家

district 区域

population 人口

SELECT 配合 FROM 子句使用

SELECT 列 from 表

查询表中所有的信息(生产中几乎是没有这种需求的)

USE world ;

SELECT id,NAME ,countrycode ,district,population FROM city;

或者

SELECT * FROM city;

查询表中 name 和population的值

SELECT NAME ,population FROM city;

SELECT 配合 WHERE 子句使用

select 列 from 表 where 过滤条件

示例:

等值条件查询

查询中国所有的城市名和人口数

SELECT NAME,population FROM city

WHERE countrycode='CHN';

比较判断查询

世界上小于100人的城市名和人口数

SELECT NAME,population FROM city

WHERE population<100;

逻辑连接符

查询中国人口数量大于1000w的城市名和人口

WHERE countrycode='CHN' AND population>8000000;

查询中国或美国的城市名和人口数

WHERE countrycode='CHN' OR countrycode='USA';

查询人口数量在500w到600w之间的城市名和人口数

WHERE population>5000000 AND population<6000000;

WHERE population BETWEEN 5000000 AND 6000000;

模糊查询

查询一下contrycode中带有CH开头,城市信息

SELECT * FROM city

WHERE countrycode LIKE 'CH%';

TIP:不要出现类似于 %CH%,前后都有百分号的语句,因为不走索引,性能极差。如果业务中有大量需求,我们用"ES"来替代。

in 语句

查询中国或美国的城市信息

WHERE countrycode IN ('CHN' ,'USA');

GROUP BY

将某列中有共同条件的数据行,分成一组,然后在进行聚合函数操作

统计每个国家,城市的个数

SELECT countrycode ,COUNT(id) FROM city

GROUP BY countrycode;

统计每个国家的总人口数.

SELECT countrycode,SUM(population) FROM city

统计每个 国家 省 的个数

SELECT countrycode,COUNT(DISTINCT district) FROM city

统计中国 每个省的总人口数

SELECT district, SUM(population) FROM city

WHERE countrycode='CHN'

GROUP BY district ;

统计中国 每个省城市的个数

SELECT district, COUNT(NAME) FROM city

GROUP BY distric

统计中国 每个省城市的名字列表GROUP_CONCAT()

SELECT district, GROUP_CONCAT(NAME) FROM city

anhui : hefei,huaian ....

SELECT CONCAT(district,":" ,GROUP_CONCAT(NAME)) FROM city

ORDER BY

统计所有国家的总人口数量,将总人口数大于5000w的过滤出来,并且按照从大到小顺序排列

SELECT countrycode,SUM(population) FROM city

GROUP BY countrycode

HAVING SUM(population)>50000000

ORDER BY SUM(population) DESC ;

LIMIT

统计所有国家的总人口数量,将总人口数大于5000w的过滤出来,并且按照从大到小顺序排列,只显示前三名

ORDER BY SUM(population) DESC

LIMIT 3 OFFSET 0;

LIMIT M,N :跳过M行,显示一共N行

LIMIT Y OFFSET X: 跳过X行,显示一共Y行

小结

select disctrict , count(name) from city

where countrycode='CHN'

group by district

having count(name) >10

order by count(name) desc

limit 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';

union 和 union all 的区别 ?

union all 不做去重复

union 会做去重操作

练习题

统计中国每个省的总人口数,只打印总人口数小于100w的

SELECT district ,SUM(population) FROM city

GROUP BY district

HAVING SUM(population)<1000000;

查看中国所有的城市,并按人口数进行排序(从大到小)

SELECT * FROM city WHERE countrycode='CHN'

ORDER BY population DESC;

统计中国各个省的总人口数量,按照总人口从大到小排序

ORDER BY SUM(population) DESC ;

统计中国,每个省的总人口,找出总人口大于500w的,并按总人口从大到小排序,只显示前三名

HAVING SUM(population)>5000000

ORDER BY SUM(population) DESC

LIMIT 3;

多表连接查询(内连接)

作用

单表数据不能满足查询需求时

查询世界上小于100人的城市,所在的国家名,国土面积,城市名,人口数

SELECT countrycode,NAME,population FROM city WHERE population<100;

PCN Adamstown 42

SELECT NAME ,SurfaceArea FROM country WHERE CODE='PCN';

多表连接基本语法

student :学生表

sno: 学号

sname:学生姓名

sage: 学生年龄

ssex: 学生性别

teacher :教师表

tno: 教师编号

tname:教师名字

course :课程表

cno: 课程编号

cname:课程名字

tno: 教师编号

score :成绩表

sno: 学号

score:成绩

多表连接例子

统计zhang3,学习了几门课

SELECT student.sname,COUNT(sc.cno)

FROM student JOIN sc

ON student.sno=sc.sno

WHERE student.sname='zhang3';

查询zhang3,学习的课程名称有哪些?

SELECT student.sname,GROUP_CONCAT(course.cname)

FROM student

JOIN sc

ON student.sno=sc.sno

JOIN course

ON sc.cno=course.cno

WHERE student.sname='zhang3'

GROUP BY student.sname;

查询oldguo老师教的学生名和个数.

SELECT teacher.tname,GROUP_CONCAT(student.sname),COUNT(student.sname)

FROM teacher

JOIN course

ON teacher.tno=course.tno

ON course.cno=sc.cno

JOIN student

ON sc.sno=student.sno

WHERE teacher.tname='oldguo'

GROUP BY teacher.tname;

查询oldguo所教课程的平均分数

SELECT teacher.tname,AVG(sc.score)

FROM teacher

GROUP BY sc.cno;

每位老师所教课程的平均分,并按平均分排序

SELECT teacher.tname,course.cname,AVG(sc.score)

ON course.cno=sc.cno

GROUP BY teacher.tname,course.cname

ORDER BY AVG(sc.score);

查询oldguo所教的不及格的学生姓名

SELECT teacher.tname,student.sname,sc.score

WHERE teacher.tname='oldguo' AND sc.score<60;

查询所有老师所教学生不及格的信息(扩展)

SELECT teacher.tname,GROUP_CONCAT(CONCAT(student.sname,":",sc.score))

WHERE sc.score<60

GROUP BY teacher.tno;

别名应用

表别名 (全局调用)

SELECT t.tname,GROUP_CONCAT(CONCAT(st.sname,":",sc.score))

FROM teacher as t

JOIN course as c

ON t.tno=c.tno

JOIN sc

ON c.cno=sc.cno

JOIN student as st

ON sc.sno=st.sno

GROUP BY t.tno;

列别名(having 和 order by 调用)

SELECT t.tname as 讲师名 ,GROUP_CONCAT(CONCAT(st.sname,":",sc.score)) as 不及格的

WHERE sc.score<60;

扩展类内容-元数据获取

元数据介绍及获取

元数据是存储在"基表"中。

通过专用的DDL语句,DCL语句进行修改

通过专用视图和命令进行元数据的查询

information_schema中保存了大量元数据查询的试图

show 命令是封装好功能,提供元数据查询基础功能

information_schema的基本应用

tables 视图的应用

use information_schema;

mysql> desc tables;

TABLE_SCHEMA 表所在的库名

TABLE_NAME 表名

ENGINE 存储引擎

TABLE_ROWS 数据行

AVG_ROW_LENGTH 平均行长度

INDEX_LENGTH 索引长度

示例

USE information_schema;

DESC TABLES;

显示所有的库和表的信息

SELECT table_schema,table_name FROM information_schema.tables;

以以下模式 显示所有的库和表的信息

world city,country,countrylanguage

SELECT table_schema,GROUP_CONCAT(table_name)

FROM information_schema.tables

GROUP BY table_schema;

查询所有innodb引擎的表

SELECT table_schema,table_name ,ENGINE

FROM information_schema.tables

WHERE ENGINE='innodb';

统计world下的city表占用空间大小

表的数据量=平均行长度*行数+索引长度

AVG_ROW_LENGTH*TABLE_ROWS+INDEX_LENGTH

SELECT table_name,(AVG_ROW_LENGTH*TABLE_ROWS+INDEX_LENGTH)/1024

FROM information_schema.TABLES

WHERE table_schema='world' AND table_name='city';

统计world库数据量总大小

SELECT table_schema,SUM((AVG_ROW_LENGTH*TABLE_ROWS+INDEX_LENGTH))/1024

WHERE table_schema='world';

统计每个库的数据量大小,并按数据量从大到小排序

SELECT table_schema,SUM((AVG_ROW_LENGTH*TABLE_ROWS+INDEX_LENGTH))/1024 AS total_KB

GROUP BY table_schema

ORDER BY total_KB DESC ;

配合concat()函数拼接语句或命令

模仿以下语句,进行数据库的分库分表备份。

mysqldump -uroot -p123 world city >/bak/world_city.sql

CONCAT("mysqldump -uroot -p123 ",table_schema," ",table_name

," >/bak/",table_schema,"_",table_name,".sql")

FROM information_schema.tables;

模仿以下语句,进行批量生成对world库下所有表进行操作

ALTER TABLE world.city DISCARD TABLESPACE;

SELECT

CONCAT("ALTER TABLE ",table_schema,".",table_name," DISCARD TABLESPACE;")

show介绍

show databases; 查看数据库名

show tables; 查看表名

show create database xx; 查看建库语句

show create table xx; 查看建表语句

show processlist; 查看所有用户连接情况

show charset; 查看支持的字符集

show collation; 查看所有支持的校对规则

show grants for xx; 查看用户的权限信息

show variables like '%xx%' 查看参数信息

show engines; 查看所有支持的存储引擎类型

show index from xxx 查看表的索引信息

show engine innodb status\G 查看innoDB引擎详细状态信息

show binary logs 查看二进制日志的列表信息

show binlog events in '' 查看二进制日志的事件信息

show master status ; 查看mysql当前使用二进制日志信息

show slave status\G 查看从库状态信息

show relaylog events in '' 查看中继日志的事件信息

show status like '' 查看数据库整体状态信息