目录
SQL通用语法以及分类
SQL通用语法
SQL语句的分类
数据库/表/列的命名规则
DDL语句
DDL设计的数据类型
数据库操作
表操作(必须先进入到数据库)
DQL语句
DQL的执行顺序
基本查询 SELECT
条件查询 WHERE
分组查询 GROUP BY
排序查询 ORDER BY
分页查询 LIMIT
DML语句
添加数据 INSERT INIO
修改/更新数据UPDATE … SET
删除数据DELETE FROM
DCL语句
用户管理
权限控制
DDL数据定义语言(Data Definition Language)
用来定义数据库对象(数据库、数据库中的表、表中的字段)
DQL数据查询语言(Data Query Language)
查询数据库中表的记录(数据)
DML数据操作语言(Data Manipilation Language)
用来对数据库中表的数据进行增删改
DCL数据控制语言(Data Control Language)
创建数据库用户、控制数据库的访问权限
只可以使用半角英文字母(大小写字母)、数字、下划线(_)作为名称
$ # ?等特殊字符无法作为名称使用
名称必须以半角英文字母开头(推荐)
在同一个数据库中不能创建相同名称的表,在同一个表中不能创建相同名称的列
Data Definition Language 用来定义数据库对象(数据库、数据库中的表、表中的字段)
数值类型
类型
大小
有符号范围(SIGNED 存在负数时的范围)
无符号范围(UNSIGNED)
TINYINT
1字节
(-128,127)
(0,255)
非常小的整数
SMALLINT
2字节
(-2^15,2^15-1)
(0,2^16)
小的整数
MEDIUMINT
3字节
(-2^23,2^23-1)
(0,2^24)
中等的整数
INT/INTEGER
4字节
(-2^31,2^31-1)
(0,2^32)
整数
BIGINT
8字节
(-2^63,2^63-1)
(0,2^64)
大的整数
FLOAT
4字节
(-3.402823466E+38,3.402823466351 E+38)
0和 (1.175494351 E-38,3.402823466 E+38)
单精度浮点型整数
DOUBLE
8字节
(-1.7976931348623157 E+308,1.7976931348623157 E+308)
0和 (2.2250738585072014 E-308,1.7976931348623157 E+308)
双精度浮点型整数
DECIMAL
通过M(精度-数字的长度)和D(标度-小数的长度)的值来得到精确小数
例如:222.2 精度就为4,标度为1
精确小数
字符串类型
类型
大小
CHAR
0-255 bytes
定长的字符串 使用格式char(x)
x表示字符串个长度为x字节
VARCHAR
0-65535 bytes
变长的字符串 使用格式varchar(x)
TINYTEXT
0-255 bytes
短文本字符串
TEXT
0-2^16 bytes
长文本数据
MEDIUMTEXT
0-2^24 bytes
中等长度文本数据
LONGTEXT
0-2^32 bytes
极大文本数据
TINYBLOB
0-255 bytes
二进制形式的短文本数据
BLOB
0-2^16 bytes
二进制形式的长文本数据
MEDIUMBLOB
0-2^24 bytes
二进制形式的中等长度文本数据
LONGBLOB
0-2^32 bytes
二进制形式的极大文本数据
二进制数据与文本数据
关系型数据库一般存放文本数据
二进制数据一般不会存放在关系型数据库中,性能不高,管理不方便;一般采用专门的文件存储器进行二进制数据(视频、音频等都是二进制数据)
char 和varchar的区别
char(x) 如果输入的字符串长度未达到x字节,则未占用的字节会通过0补位
性能高,占用空间大
varchar(x) 不会用0补位,根据输入的内容去自动计算占用了多少字节
性能低(需要自动计算),但是占用空间小
不过两者都需要注意输入的字符串长度不能超过X字节,一旦超出将会报错
日期类型
类型
大小
范围
DATE
3字节
1000-01-01 至 9999-12-31
年月日 日期值
TIME
3字节
-838:59:59 至 838:59:59
时分秒 时间值
YEAR
1字节
1901 至 2155
年 年份值
DATETIME
8字节
1000-01-01 00:00:00 至 9999-12-31 23:59:59
年月日-时分秒
日期值+时间值
TIMESTAMP
4字节
1970-01-01 00:00:01 至 2038-01-19 03:14:07
年月日-时分秒
日期值+时间值
[]内容以及绿色部分表示可选项
查询当前服务器中所有数据库
SHOW DATABASES;
创建数据库(字符集和排序规则都是有默认值,为可选操作)
CREATE DATABASE IF NOT EXISTS 数据库名称 [DEFAULT CHARSET字符] [COLLATE 排序规则];
IF NOT EXISTS 如果数据库不存在则创建数据库,否则不创建(可以避免报错)
DEFAULT CHARSET 指定字符集
COLLATE 指定排序规则
删除数据库
DROP DATABASE IF EXISTS 数据库名;
IF EXISTS 如果数据库存在则删除数据库,否则不删除(可以避免报错)
切换到此数据库
USE 数据库名;
查询当前所在的数据库
SELECT DATABASE();
show databases; #查询所有的数据库
create database if not exists test default charset utf8mb4; #如果test数据库不存在,则创建test数据库,字符集为utf8mb4
drop database if exists test1; #如果test1存在,则删除test1数据库
use test; #切换到test数据库
创建表
CREATE TABLE 表名称(
字段1 字段1的数据类型 [COMMENT字段1的注释],
字段2 字段2的数据类型 [COMMENT 字段2的注释],
……
字段n 字段n的数据类型 [COMMENT 字段n的注释]
) [COMMENT 这个表的注释];
注意:每个字段之间需要使用“,”间隔,最后一个字段不需要使用”,”
查询表
SHOW TABLES; 查询当前数据库中所有的表
DESC 表名称; 查询指定表的结构(显示表的信息不完整)
SHOW CREATE TABLE 表名称; 查询指定表的建表语句(显示表的详细信息)
表修改 ALTER TABLE
向表中添加字段
ALTER TABLE 表名称 ADD 字段名 字段的数据类型 [约束] [COMMENT注释];
约束在后续讲解
修改表中已存字段的数据类型
ALTER TABLE 表名称 MODIFY 字段名 新的数据类型;
修改表中已存字段的名称以及数据类型
ALTER TABLE 表名称 CHANGE 旧字段名 新字段名 新字段的数据类型 [约束] [COMMENT注释];
删除表中的字段
ALTER TABLE 表名称 DROP 字段名称;
修改表名
ALTER TABLE 表名称 RENAME TO 新表名称;
表删除 DROP TABLE
删除表
DROP TABLE IF EXISTS表名称;
IF EXISTS 如果此表存在则删除,不存在也不会报错
删除此表,并重新创建此表
TRUNCATE TABLE 表名称;
注意事项:删除了的表是无法恢复的,在删除时一定要注意
创建表 create table staff( #创名为staff的表,并向其添加字段 name varchar(50) comment '姓名', number int comment '工号', gender varchar(1) comment '性别' )comment '员工表'; 查询表 show tables; #查看此数据库中所有的表 desc staff; #查看名为staff表的结构 show create table staff; #查看名为staff表的建表语句表修改 alter table staff add age tinyint unsigned comment '年龄'; #向表staff中添加字段,字段名为age,数据类型为tinyint unsigned alter table staff modify age tinyint; #修改表staff中age字段的数据类型,将其数据类型修改为tinyint alter table staff change age year tinyint unsigned comment '无符号的tinyint类型'; #修改表中的age字段的名称和数据类型,名称修改为year,数据类型修改为tinyint unsigned alter table staff drop year; #删除名为year的字段 alter table staff rename staff1; #将staff表重命名为staff1 表删除 drop table if exists test2; #如果test2表存在,则删除test2表 truncate table test1; #删除test1表,并重新创建此表(test1表必须存在)
Data Query Language 查询数据库中表的记录(数据)
DQL的编写顺序是固定的
SELECT 字段列表 FROM 表名列表 WHERE 条件列表 GROUP BY分组字段列表 HAVING分组后条件列表 ORDER BY 排序字段列表 LIMIT分页参数;
SELECT 字段列表
FROM 表名列表
WHERE 条件列表
GROUP BY 分组字段列表
HAVING 分组后条件列表
ORDER BY 排序字段列表
LIMIT 分页参数
DQL的执行顺序
FROM 表名列表 先查找表
WHERE 条件列表 查询满足条件的字段值
GROUP BY 分组字段列表 对这些满足条件的字段进行分组
HAVING 分组后条件列表 对分组后的字段再进行判断
SELECT 查询后返回的字段列表 此时将分组后的判断通过的数据显示出来
ORDER BY 排序字段列表 对显示出来的字段值做排序
LIMIT 分页参数 对排序后的值最分页
SELECT字段列表 FROM表名
查询多个字段
SELECT 字段1,字段2…… FROM 表名
查询全部字段
SELECT * FROM 表名;
查询时为字段设置别名方便阅读(AS可以省略)
SELECT 字段1 [AS 别名1] , 字段2 [AS 别名2]…… FROM 表名;
查询时去除重复记录(DISTINCT关键字只可以使用在第一个字段名之前)
SELECT DISTINCT 字段1,字段2,…… FROM 表名;
select name from staff1; #查询staff1表中name字段的所有数据select * from staff1; #查询staff1表中所有字段的所有数据select name '姓名', number '工号' from staff1; #查询staff1表中name、number字段的所有数据,并设置别名方便阅读select distinct name from staff1; #查询staff1表中name字段的所有数据,并去除重复数据
SELECT字段列表 FROM表名WHERE 条件列表;
先用WHERE查询出符合指定条件的记录,然后再选取出SELECT语句指定的字段
可以指定的条件
算数运算符——所有和NULL的算数运算,结果都是NULL
+ 加法
- 减法
* 乘法
/ 除法
比较运算符——普通的运算符无法比较NULL值,必须使用特定的IS NULL来匹配NULL值
> 大于
>= 大于等于
< 小于
<= 小于等于
<>或!= 不等于
BETWEEN … AND … 在某个范围之内(左闭右闭)
IN(…) …为多个信息,in(…)表示只要满足…中的某个信息就算匹配
LIKE 占位符 模糊匹配(_表示匹配单个字符、%表示匹配任意字符)
IS NULL 表示NULL值
IS NOT NULL 表示非NULL值
逻辑运算符
AND 或 && 多个条件同时成立
OR 或 || 多个条件成立其中一个
NOT 或 ! 条件取反
SQL的三值逻辑
普通编程语言的布尔型只有 True 和 False,因此被称为二值逻辑
在SQL中除了True、False,还有Unknown ,因此被称为三值逻辑
UNKNOWN 和NULL比较是使用IS NULL、IS NOT NULL运算符,返回的值为True或Flase
和NULL比较使用(>、<、=等)返回的值都为UNKNOWN
True and unknown 为unknown True or unknown 为 true
False and unknown 为false False or unknown 为unknown
Unknown and/or unknown 为 unknown
select age from staff1 ; #只查看年龄字段对应的值select * from staff1 where gender = null ; #Where的结果为Unknown,无法提取出任何记录 select * from staff1 where gender is null ; #查询gender为null,并将其对应的所有字段的值都显示出来select * from staff1 where gender is not null ; #查询gender为非null,并将其对应的所有字段的值都显示出来select * from staff1 where gender = '男' and name = '张三'; #查询性别为男,名为张三的信息,并将其对应的所有字段的值都显示出来select * from staff1 where gender in ('男','女') ; #查询性别为男、或者性别为女的信息,并将其对应的所有字段的值都显示出来select * from staff1 where name like '__' ; #查询名称为2个字符信息,并将其对应的所有字段的值都显示出来select * from staff1 where number between 20000100 and 20000102 #查询number为20000100到20000102之间对应的信息,并将其对应的所有字段的值都显示出来select * from staff1 where name = null or name = '张三'; #返回的结果就是name=’张三’的结果
聚合函数——分组查询一般结合聚合函数使用
将一列数据作为一个整体,进行纵向计算(所有NULL值不参与计算)
count 统计行量(一列有多少个值)
max 最大值(一列的最大值)
min 最小值(一列的最小值)
avg 平均值(一列的平均值)
sum 求和(一列的所有数值求和)
注意事项
只有SELECT、HAVING、ORDER BY可以使用聚合函数
聚合函数使用格式:
SELECT 聚合函数 (字段列表) AS [别名] FROM 表名 [WHERE条件列表];
select COUNT(*) from emp; #统计这个表有多少行(*表示统计全部的列,由于Null不参与统计,可能每个列的统计数值不一致,其中会取最大值作为结果返回) select COUNT(distinct age) from emp; #统计age字段有多少种不同的值(去除重复值后的行数) select max(age) from emp; #统计age的最大值,并显式出来 select avg(age) from emp; #统计age的平均值,并显式出来 只有count可以使用*,其它函数无法使用*,所有聚合函数都可以使用distinct关键字
分组查询
格式
SELECT 字段列表,[聚合函数] (要显示出来的字段或聚合函数)FROM 表名 [WHERE条件列表] GROUP BY 需要分组的字段名 [HAVING对分组后的结果执行的过滤条件];
通过使用聚合函数和GROUP BY子句,可以将表分割后再进行汇总
执行顺序:FROM 、 WHERE、GROUP BY、聚合函数、HAVING 、SELECT
Where和Having的区别
执行的时机不同:where是分组之前进行过滤,不满足此过滤条件的不参与分组;having是对分组之后的结果进行过滤
判断条件不同:where无法对聚合函数判断;having可以对聚合函数做判断
执行速度不同:在Where处理的速度要比在Having中快一点
注意事项
此处的聚合函数是对分组后的内容执行
分组之后,需要查询的字段一般就是聚合函数或者分组的字段,查询其他字段没有意义(即SELECT子句处理聚合函数外,一般只出现分组字段)
如果分组的数据中有NULL,则NULL单独为一组
GROUP BY子句显示的结果是无序的,可以通过排序实现
#对gender进行分组,并查询每个组对应的gender select gender from staff1 group by gender;#对gender进行分组,并分别统计每个组的数量,并将统计的数量显式出来,然后将count(*)别名为number1 select count(*) number1 from staff1 group by gender;#对gender进行分组,并分别统计每个组的的数量,并查询每个组对应的gender select gender,count(*) from staff1 group by gender;#对gender进行分组,并计算每个组的平均年龄是多少,并查询每个组对应的gender select gender,avg(age)from staff1 group by gender;#对gender进行分组,并计算每个组的平均年龄和每个组的数量,并查询每个组对应的gender select gender,avg(age),count(*) from staff1 group by gender;#对age小于30以下的人通过gender进行分组,统计每个组的数量,并将数量大于2的提取出来,并查询每个组对应的gender select gender,count(*) from staff1 where age<30 group by gender having count(*) > 2;
格式
SELECT 字段列表 FROM 表名 ORDER BY 字段1 排序方式1 , 字段2 排序方式2;
执行顺序:FROM 、 WHERE、GROUP BY、聚合函数、HAVING 、SELECT、ORDER BY
排序方式
ASC:升序(默认),在书写时可以省略
DESC:降序
注意事项
多字段排序时,先按照第一个字段排序;当第一个字段的值相同时,对这些相同的值按照第二个字段排序
NULL不进行排序,含有NULL的列作为排序键时,NULL会在结果的开头或末尾显示
select * from staff1 order by age asc ; #对年龄按照升序排序,并显示出所有字段的值 select * from staff1 order by age desc, number ; #对年龄按照降序排序,并对相同年龄按照number的升序排序 select gender,count(*) from staff1 group by gender order by count(*); #对gender进行分组,并分别统计每个组的的数量,并查询每个组对应的gender,然后对count(*)进行升序显示
格式
SELECT 字段列表 FROM 表名 LIMIT 起始索引 , 每页显示的记录数;
注意事项
起始索引从0开始,它的的值等于(需要查询页码数-1)* 每页显示的记录数
即:0代表第一页(无论每页的记录数是多少);
如果查询第二页,每页有5条记录,则起始索引为5才表示查询第二页数据
如果查询第二页,每页有10条记录,则起始索引为10才表示查询第二页数据
如果查询的是第一页数据,起始索引可以省略,可以直接LIMIT 查询记录数
分页查询时数据库的方言,不同的数据库有不同的实现,MySQL是LIMIT
select * from staff1 limit 0,2; #查询第一页数据,每页显示2行数据 select * from staff1 limit 3,3; #每页显示3行数据,查询第二页的数据 select gender,count(*) from staff1 group by gender;
Data Manipilation Language 用来对数据库中表的数据进行增删改
实际上insert inio 每执行一次,就执行一行数据的插入
给指定的部分字段添加一条数据
INSERT INTO 表名称 (字段1,字段2,……) VALUES (值1,值2,……);
将字段与字段、值与值之间使用逗号隔开,并包含在()内的形式称为清单
INSERT INIO包含列清单和值清单两种
给全部字段添加一条数据
可以省略列清单
INSERT INTO 表名称 VALUES (值1,值2,……);
给字段添加多条数据
INSERT INTO 表名称 (字段1,字段2,……) VALUES (值1,值2,……), (值1,值2,……);
INSERT INTO 表名称 VALUES (值1,值2,……) ,(值1,值2,……);
将表2的数据添加到表1中(要求两表之间的表结构一致 字段名、字段类型等)
INSERT INTO 表1 列清单 SELECT 字段列表 FROM 表2;
注意表2的字段列表要与表1的列清单内容一致
注意事项
添加的值的顺序要与字段的顺序一致;列清单的数目必须与值清单的数目保持一致,否则无法插入数据
在插入时,如果列清单没有包含所有字段,则没有包含的字段填充默认值(如果该字段没有默认值则设置为NULL)
值的大小要在字段数据类型的规定范围以内
如果值为字符串或者日期,应该用引号包含
insert into staff1 (name, number) values ('张三','20000101'); #给指定的字段添加一组数据 insert into staff1 values ('李四','20000102','男'); #给全部字段添加一组数据 insert into staff1 (name, number,gender) values ('老五','20000103','男'),('六妹','20000104','女'); #给指定的字段添加多组数据
修改某个字段的值
UPDATE 表名称 SET 字段名=值1 [WHERE 条件];
如果没有修改条件,则会将整张表中此字段对应的所有值都修改为值1
修改多个字段的值
UPDATE 表名称 SET 字段名=值1,字段名=值2,…… [WHERE 条件];
设置NULL清空(将某列值都设置为NULL)
UPDATE 表名称 SET 字段名=NULL;
update staff1 set gender = '男'; #修改某个字段的值(无条件) 将表中gender字段的所有值都修改为男 update staff1 set number = 20000100 where name = '张三'; #修改某个字段的值(有条件) 将name为张三的number修改为20000100 update staff1 set name='五弟',number=1111111 where name='老五'; #修改多个字段的值(有条件) 将neme为老五的name修改为五弟,number修改为1111111
DELETE FROM 表名称 [WHERE 条件]
如果有条件,则表示删除条件对应的所有数据;如果没有条件,则会删除整张表的数据
DELETE语句无法删除某一个字段的值,删除某一个字段的值可以使用UPDATE将某个字段的值设置为NULL
DELETE语句只可以使用WHERE语句,无法使用GROUP BY、ORDER BY等语句
delete from staff1 where name='六妹'; #删除name为六妹送对应的全部数据 update staff1 set number=NULL where name='张三'; #删除name为张三的number信息
Data Control Language 数据控制语言,用来管理数据库用户、控制数据库的访问权限等
查询用户
用户所具有的全新信息都是存放在mysql数据库中的user表中
所以我们可以直接进入mysql数据库,然后查询user表就可以查询用户
在MySQL中的用户通过Host(主机名—此用户可以在哪些主机上访问此SQL)和User(用户名)来定位
use mysql; #进入到名为mysql的数据库中 select * from user; #查询数据库中user表的所有字段及其值创建用户
CREATE USER ‘用户名’@’主机名’ IDENTIFIED BY ‘密码’;
主机名为% 表示可以在任意主机访问数据库
create user 'admin'@'localhost' identified by '123456'; #创建用户名为admin,主机名为localhost的用户,密码为123456 此时创建的用户没有分配权限修改用户密码
ALTER USER ‘用户名’@’主机名’ IDENTIFIED WITH mysql_native_password BY ‘新密码’;
musql_naative_password:为密码的一种加密方式(MySQL默认的加密方式,采用hash)
其它的加密方式:sha256_password(使用sha-256算法)、caching_sha2_password(使用sha-256算法,只是在服务器端使用内存缓存的方式使得重新连接的用户更快的进行认证)
alter user 'admin'@'localhost' identified with mysql_native_password by '12345'; #修改密码为12345删除用户
DROP USER ‘用户名’@’主机名’;
drop user 'admin'@'localhost'; #删除用户
常用的权限类型
USAGE 没有任何权限
ALL(ALL PRIVILEGES) 所有权限
SELECT 查询数据的权限
INSERT 插入数据的权限
UPDATE 修改数据的权限
DELETE 删除数据的权限
ALTER 修改表/字段的权限
DROP 删除数据库/表/视图的权限(后续讲解视图)
CREATE 创建数据库/表的权限
查询用户权限
SHOW GRANTS FOR ‘用户名’@’主机名’;
show grants for 'admin'@'localhost'; #查询权限 显示结果如下:GRANT USAGE ON *.* TO `admin`@`localhost` 表示对所有数据库的所有表都没有权限,只是能够登录连接到SQL授予用户权限
GRANT 权限列表 ON 数据库名.表名 TO ‘用户名’@’主机名’;
grant all on test.staff1 to 'admin'@'localhost'; #对此用户授予权限(对名为test数据库下的staff1表有所有权限) 此时查询此用户的权限显示如下: GRANT ALL PRIVILEGES ON `test`.`staff1` TO `admin`@`localhost`撤销用户权限
REVOKE 权限列表 ON 数据库名.表名 FROM ‘用户名’@’主机名’;
revoke delete,update on test.staff1 from 'admin'@'localhost'; #撤销此用户的权限(对名为test数据库下的staff1表的删除数据权限和修改数据的权限进行撤销)注意事项
多个权限之间使用逗号分隔
授权时数据库名和表名都可以使用*代替,表示所有数据库、所有表