SQL语句
DDL(Data Definition Language)
数据定义语言,用来定义数据库对象(数据库,表,字段)
数据库操作
1 | #查询所有数据库 |
表操作
1 | #查询当前数据库所有表 |
DML(Data Manipulation Language)
数据操作语言,用来对数据库表中的数据进行增删改
1 | #添加数据 |
DQL(Data Query Language)
数据查询语言,用来查询数据库中表的记录
基本查询
1 | #基本查询 |
条件查询
1 | #条件查询 |
条件查询的条件列表
比较运算符 | 功能 |
---|---|
>,>=,<,<=,=,<>或!= | 最后一个是不等于 |
BETWEEND..AND… | 在某个范围之内(含最小,最大值)前面可以加一个字段 |
IN(…) | 在in之后的列表中的值,多选一 |
LIKE 占位符 | 模糊匹配(_匹配单个字符,%匹配任意个字符),占位符用单引号括起来 |
IS NULL | 是NULL |
逻辑运算符 | 功能 |
---|---|
AND 或 && | 并且(同时成立) |
OR 或 || | 或者(任一成立) |
NOT 或 ! | 非,不是 |
分组查询
聚合函数
将一列数据作为整体,进行纵向计算
函数 | 功能 |
---|---|
count | 统计数量 |
max | 最大值 |
min | 最小值 |
avg | 平均值 |
sum | 求和 |
1 | #语法 |
分组查询
1 | #语法 |
这里where和having的区别
- 执行时机不同:where是分组前进行过滤,having是对分组后的数据进行过滤
- 判断条件不同:where不能对聚合函数判断(即不能使用聚合函数),having可以
执行顺序:where > 聚合函数 > having
分组之后,查询的字段一般为聚合函数和分组字段,查询其它字段无意义
排序查询
1 | #语法 |
排序方式
- ASC :升序(默认)
- DESC:降序
注意:如果是多字段排序,当第一个字段值相同时,才会根据第二个字段排序
分页查询
1 | #语法 |
注意:
- 起始索引从0开始,起始索引=(查询页码-1)*每页记录数
- 如果查询的是第一页数据,起始索引可以省略,直接简写为limit 10。
DQL的执行顺序
编写顺序如下:
1 | SELECT #----第四步 |
DCL(Data Control Language)
数据控制语言,用来创建数据库用户、控制数据库的访问权限
管理用户
1 | #查询用户 |
权限控制
权限 | 说明 |
---|---|
ALL,ALL PRIVILEGES | 所有权限 |
SELECT | 查询数据 |
INSERT | 插入数据 |
UPDATE | 修改数据 |
DELETE | 删除数据 |
ALTER | 修改表 |
DROP | 删除数据库/表/视图 |
CREATE | 创建数据库/表 |
1 | #查询权限 |
- 多个权限之间,用逗号分隔
- 授权时,数据库名和表名可以用*进行通配
函数
字符串函数
函数 | 功能 |
---|---|
CONCAT(S1,S2,…Sn) | 将S1,S2,..SN拼接为一个字符串 |
LOWER(str) | 转小写 |
UPPER(str) | 转大写 |
LPAD(str,n,pad) | 左填充,用pad对str的左边进行填充,达到n个字符串长度 |
RPAD(str,n,pad) | 右填充,用pad对str的右边进行填充,达到n个字符串长度 |
TRIM(str) | 去掉字符串头部和尾部的空格 |
SUBSTRING(str,start,len) | 返回str从start起len个长度的字符串 |
数值函数
函数 | 功能 |
---|---|
CEIL(x) | 向上取整 |
FLOOR(x) | 向下取整 |
MOD(x,y) | 返回x/y的模 |
RAND() | 返回0~1的随机数 |
ROUND(x,y) | 求参数x的四舍五入的值,保留y位小数 |
日期函数
函数 | 功能 |
---|---|
CURDATE() | 返回当前日期 |
CURTIME() | 返回当前时间 |
NOW() | 返回当前日期和时间 |
YEAR(date) | 获取指定date的年份 |
MONTH(date) | 获取指定date的月份 |
DAY(date) | 获取指定date的日期 |
DATE_ADD(date,INTERVAL expr type) | 返回一个日期/时间值加上一个时间间隔expr后的时间值 |
DATEDIFF(date1,date2) | 返回起始时间date1和结束时间date2之间的天数 |
流程函数
可以在SQL语句中实现条件筛选,从而提高语句的效率
函数 | 功能 |
---|---|
IF(value,t,f) | 如果value为true,返回t,否则返回f |
IFNULL(value1,value2) | 如果value不为空,返回value1,否则返回value2 |
CASE WHEN [val1] THEN [res1]…ELSE [default] END | 如果val1为true,返回res1,否则返回默认值 |
CASE [expr] WHEN [val1] THEN [res1]…ELSE [default] END | 如果expr的值等于val1,返回res1,否则返回默认值 |
约束
约束是作用于表中字段上的规则,用于限制存储在表中的数据
约束 | 功能 | 关键字 |
---|---|---|
非空约束 | NOT NULL | |
唯一约束 | UNIQUE | |
主键约束 | 主键是一行数据的唯一标识,要求非空且唯一 | PRIMARY KEY |
默认约束 | 保存数据时,如果未指定该字段的值,采用默认值 | DEFAULT |
检查约束 | 保证字段值满足某一个条件 | CHECK |
外键约束 | 用来让两张表的数据之间建立联系,保持数据的一致性和完整性 | FOREIGN KEY |
1 | #语法一、创建的时候指定外键约束 |
删除/更新行为
行为 | 说明 |
---|---|
NO ACTION / RESTRICT | 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。(默认情况) |
CASCADE | 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有,则也删除/更新外键在子表中的记录。 |
SET NULL | 当在父表中删除对应记录时,首先检查该记录是否有对应外键,如果有则设置子表中该外键值为nu(这就要求该外键允许取nul) |
1 | #语法,只需在后面加上更新和删除的方式 |
多表查询
多表关系
- 一对多(多对一)
- 多对多
- 一对一
内连接
查询两张表的交集部分
1 | #隐式内连接 |
外连接
左外连接和右外连接
左:查询左表的所有数据和左右表交集部分的数据
右:查询右表的所有数据和左右表交集部分的数据
1 | #语法------左 [OUTER可有可无 |
右外可改成左外。左外会写就行
自连接
1 | #语法 |
自连接查询,可以是内连接也可以是外连接
联合查询
对于union查询,就是把多次查询的结果合并起来,形成一个新的查询结果集
1 | #语法 |
使用条件:两个语句的字段列表(数量/类型)要保持一致
子查询
SQL语句中嵌套SELECT语句,称为嵌套查询,又称子查询。子查询要用()括起来
子查询外部的语句可以是INSERT/UPADTE/DELETE/SELECT 中的任何一个
标量子查询
子查询结果为单个值
常用的操作符:=,<>,>,>=,<,<=
列子查询
子查询结果是一列
常用的操作符:IN , NOT IN , ANY(满足子查询列表的一个即可) , SOME(与ANY同等) ,ALL(必须全部满足)
行子查询
子查询结果是一行
常用的操作符: = ,<> , IN , NOT IN
表子查询
子查询结果是多行多列
常用的操作符: IN
事务
事务 是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。
事务操作
1 | #开启事务 |
*事务四大特性ACID
- 原子性(
Atomicity
) :事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用; - 一致性(
Consistency
) :执行事务前后,数据保持一致,多个事务对同一个数据读取的结果是相同的; - 隔离性(
Isolation
): 并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的; - 持久性(
Durability
): 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。
*脏读、不可重复读、幻读
脏读(Drity Read):某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因,前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的。
例子:小明读取到小红提交的100数据.但是小红异常回滚了数据,100变成了90,这个时候小明还是100,但实际是90(脏读)
不可重复读(Non-repeatable read):在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新的原有的数据。
例子:小明多次读取A数据,小红在小明读取数据时,每次读取都修改了数据并提交,小明多次读到的数据不一致
幻读(Phantom Read):在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。
例子:小明修改了A,B数据,小红同时又插入了一条C数据,小明会感觉自己明明数据都改了,突然多出来一条,以为出现了幻觉自己漏了一条
*事务的隔离级别
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
Read uncommitted | 有 | 有 | 有 |
Read committed | 无 | 有 | 有 |
Repeatable Read(Mysql的默认级别) | 无 | 无 | 有 |
Serializable | 无 | 无 | 无 |
级别越高,安全性越高,执行效率越低
1 | #查看事务隔离级别 |
引擎
存储引擎Storage engine:MySQL中的数据、索引以及其他对象是如何存储的,是一套文件系统的实现。
MySQL存储引擎MyISAM与InnoDB区别
- Innodb引擎:Innodb引擎提供了对数据库ACID事务的支持。并且还提供了行级锁和外键的约束。
- MyIASM引擎(原本Mysql的默认引擎):不提供事务的支持,也不支持行级锁和外键。
存储引擎选择
如果没有特别的需求,使用默认的Innodb
即可。
MyISAM:以读写插入为主的应用程序,比如博客系统、新闻门户网站。
Innodb:更新(删除)操作频率也高,或者要保证数据的完整性;并发量高,支持事务和外键。比如OA自动化办公系统。
索引
索引介绍
索引是一种用于快速查询和检索数据的数据结构,其本质可以看成是一种排序好的数据结构。
索引的优缺点
优点
- 使用索引可以大大加快数据的检索速度
缺点
- 时间方面:创建索引和维护索引要耗费时间,具体地,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,会降低增/改/删的执行效率;
- 空间方面:索引需要占物理空间。
索引结构
索引分类
从数据结构角度
- 树索引
- Hash索引
从物理存储角度
聚集索引
- 聚簇索引是一种索引组织方式,它将索引和数据行存储在一起,即数据行按照索引的顺序存储在磁盘上。
- 聚簇索引的叶子节点保存的是完整的数据行,因此不需要进行额外的查找操作就可以获取到所需的数据。
- InnoDB 存储引擎的主键索引就是一个聚簇索引,如果表没有显式地定义主键,InnoDB 会选择一个唯一的非空索引作为聚簇索引。
非聚集索引
- 非聚簇索引是一种索引组织方式,它将索引和数据行分开存储,即索引保存了指向数据行的指针(通常是行的物理地址或主键值)。
- 非聚簇索引的叶子节点保存的是指向数据行的引用,当查询需要获取数据时,首先根据索引查找到相应的行指针,然后再通过行指针获取数据行。
- 在MySQL中,MyISAM 存储引擎的索引通常是非聚簇索引。
总的来说,聚簇索引和非聚簇索引的区别在于索引和数据行的存储方式。聚簇索引将索引和数据行存储在一起,而非聚簇索引将索引和数据行分开存储。
对于非聚簇索引,一定会回表查询吗?
答:不一定。试想一种情况,用户准备使用 SQL 查询用户名,而用户名字段正好建立了索引。那么这个索引的 key 本身就是 name,查到对应的 name 直接返回就行了,无需回表查询。 这种情况就称之为索引覆盖。
索引覆盖:如果要查询的字段都建立过索引,那么引擎会直接在索引表中查询而不会访问原始数据(否则只要有一个字段没有建立索引就会做全表扫描),这叫索引覆盖。因此我们需要尽可能的在select
后只写必要的查询字段,以增加索引覆盖的几率。
这里值得注意的是不要想着为每个字段建立索引,因为优先使用索引的优势就在于其体积小。
从逻辑角度
- 普通索引:基本的索引类型,没有唯一性的限制,允许为NULL值。
- 可以通过
ALTER TABLE table_name ADD INDEX index_name (column);
创建普通索引
- 可以通过
- 唯一索引:数据列不允许重复,允许为NULL值,一个表允许多个列创建唯一索引。
- 可以通过
ALTER TABLE table_name ADD UNIQUE (column);
创建唯一索引 - 可以通过
ALTER TABLE table_name ADD UNIQUE (column1,column2);
创建唯一组合索引
- 可以通过
- 主键索引:数据列不允许重复,不允许为NULL,一个表只能有一个主键。
- 联合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并。
- 可以通过
ALTER TABLE table_name ADD INDEX index_name(column1, column2, column3);
创建组合索引
- 可以通过
索引语法
SQL性能分析
SQL优化
插入数据
load指令一次插入大批量数据
主键优化
- 满足业务需求的情况下,尽量降低主键的长度
- 插入数据时,尽量选择顺序插入,选择使用AUTO_INCREMENT自增主键
- 尽量不要使用UUID做主键或者是其它自然主键,如身份证号
- 业务操作时,避免对主键的修改