SQL笔记
SQL笔记
余生一、SQL语句
DDL
data definition language 数据定义语言
1 | show databases; --显示数据库 |
1 | SHOW TABLES; --显示数据表 |
DML
data manipulation language 数据操作语言,增删改
1 | INSERT INTO 表名(字段1,字段2)VALUES (值1,值2); |
DQL
data query language 数据查询语言
1 | select col from name_of_table; |
条件查询
注意 in() 、LIKE、 IS NULL
_匹配单个字符
%任意字符
1 | select * from tablename where col is null; |
聚合函数
count、max、min、avg、sum
null不参与运算
1 | select count(col) from name_of_table; |
分组查询
1 | select col form naem where group by 分组字段 having |
分组查询一般针对分组之后的字段和聚合函数
排序
1 | select cols from name_of_table order by col1 method, col2; |
分页
1 | select cols from name_of_table LIMIT start,number; |
执行顺序
from where groupby having select orderby limit
DCL
data control language 数据控制语言
创建用户
修改密码
删除用户
权限
查询权限
show grants for
grant 权限 on 数据表 to
remove from
二、函数
- 字符串函数
concat
lower upper
lpad rpad 填充
trim 去除空格
substring
- 数值函数
ceil
floor
mod
rand
round
- 日期函数
CURDATE()
CURTIME()
NOW
YEAR
MONTH
DAY
DATE_ADD(data,interval)
datediff
- 流程函数
IF(value,t,f)
ifnull(value1,value2)
case col when * then * else end
case when col >0 then when clo then end
三、约束
非空约束 NOT NULL
唯一约束 UNIQUE
主键约束 PRIMARY KEY
默认约束 DEFAULT
检查约束 CHECK
外键约束 F 保证数据完整性和一致性
四、多表查询
内连接
两张表的交集
1 | select 字段 from 表1, 表2 where --隐式 |
外连接
1 | select * from emp e left join dept d on e.id=d.id |
自连接
1 | select * from table1 t1 left join table2 t2 on t1.id=t2.id; |
联合查询
1 | select 字段 from 表a |
子查询
嵌套select
1 | select * fromm t1 where col1=(select col1 from t2); |
五、事务
一个操作的集合,要么同时成功要么同时失败。 经典事物 转账
1 | select @@autocommit; --查询 |
特性
- 原子性:不可分割的最小操作单元
- 一致性:数据保持一致状态
- 隔离性:事务独立
- 持久性:提交回滚的改变是永久的
并发事务
- 脏读:一个事务读到另一个事务没提交的数据
- 不可重复读:一个事务先后读取同一条记录,读取的结果不同
- 幻读:事物查询时没有,在插入时有了
事物的隔离级别
六、存储引擎
MySQL体系结构
连接层、服务层、引擎层、存储层
存储引擎是存储数据、建立索引、更新查询数据等技术的实现方式。存储引擎是基于表的,也称为表类型
默认 INNODB
1 | create table ss{ |
InnoDB 特点
- 支持事务
- 行级锁
- 外键
文件:**.idb
MyISAM特点
不支持事务 不支持外键
支持表锁 不支持行锁
访问速度快
- sdi
- myd
- myi
Memory特点
作为临时表
hash索引
- sdi 存储表结构
选择
InnoDB
MyISAM -MongoDB 查询插入
Memory --redis 缓存
七、索引
- B+ Tree
- Hash
- R-tree 空间索引 用于地理空间数据
- Full-text 全文索引
b-tree 多路平衡二叉树
b+ tree
所有的元素都在叶子节点
叶子节点形成单向链表
MySQL中的B+
双向训练链表
Hash索引
- Hash只能进行对等比较,不能进行范围
- 无法利用索引进行排序
- 查询效率高
Menmory支持
为什么使用b+ teee
- 相对于二叉树 层级更少
- 对于b树 无论叶子节点还是非叶子节点都会保存数据,导致一页中存储的键值减少,指针也减少,要保存大量数据,只能增加树的高度.(1)B+树空间利用率更高,可减少I/O次数 增删文件(节点)时,效率更高 B+树的查询效率更加稳定
- 对于hash,b+ 支持范围和排序操作
索引分类
-
主键索引 只能有一个
-
唯一索引
-
常规索引
-
全文索引
-
聚焦索引 必须有 只有一个 b+树 叶子节点挂行数据
-
二级索引 叶子节点为id
如果存在主键 主键就是聚集 ->唯一索引 -> 自动生成
回表查询:先查二级索引 再查聚集索引
索引操作
1 | create index index_name on table_name (col1, col2); |
SQL性能分析
1 | show global status like 'com_______' --查看增删改查次数 |
索引使用
- 最左前缀法则
针对联合索引 在使用的时候最左变的索引必须存在 ,如果跳过中间索引 ,则后面索引失效
- 范围查询
出现范围查询时(< >),范围查询右侧的索引失效 >= <=不会
- 索引列运算
不要在索引上进行运算,否则会失效
- 字符串不加引号的情况下索引失效
- 模糊查询,后面模糊走索引,前面模糊%ss不走索引
- or连接的条件 只有两侧都有索引 才会走涉及到的索引
- 数据分布影响 使用索引比全表扫描慢的话不走索引
- SQL提示:use index() , ignore index() ,force index()
- 覆盖索引, 减少使用select * 减少回表
- 前缀索引
字符串的一部分作为索引
1 | create index idx_ on table_(col(n)); |
- 单列索引和联合索引 存在多个查询条件,考虑为这几个字段构建联合索引
索引设计原则
- 数据量大 >100w,查询频繁
- 查询 排序 分组
- 选择区分度高的,尽量建立唯一索引
- 针对长字符串,建立前缀索引
- 尽量使用联合索引
- 控制索引数量,会影响增删改
- 如果索引不能存储null,在创建时使用not null约束
八、SQL优化
insert优化
- 一致性插入多条数据
- 手动事务提交 多条insert统一提交
- 主键顺序插入 12345
- 大批量数据插入 使用load指令
主键优化
- 页分裂
- 页合并
- 设计原则:尽量降低主键的长度;尽量选择顺序插入,使用自增;尽量不要使用uuid或其他自然主键;避免对主键的修改
order by优化
- using filesort
没有索引的情况下
不可避免的时候,适当增加排序缓冲区的大小 sort_buffer_size
- using index
有索引
针对一个升序一个降序的条件,可以再创建对应的索引; 默认均为升序
group by优化
没有索引,using temporary
有索引,using index
分组的时候,索引的使用也满足最左前缀原则
limit优化
limit start, num
通过覆盖索引和子查询
1 | select * from tb, (select id from tb_b order by id limit * *) a where a.id = b.id |
count 优化
MyISAM会把总行数存在磁盘上,很快;InnoDB 不会
优化思路:自己计数
count对null不计数
count(*) count(1)
count(主键) 取主键 主键直接累加,主键不能为null
count(字段) 针对有没有not null 约束,采取两种不同的策略
count(1) 不取值,放1
count(*) 不取值,之间累加
效率 count(字段)<count(主键id)<count(1)≈count(*)
Update 优化
条件在没有所以的字段进行选择,会是表锁,有索引是行锁
因此尽量使用索引进行选择
九、视图
视图是一张虚拟存在的表, 不存储数据 数据仍在基表中
1 | create or replace view view_n as select 字段 from table_n where ** |
视图检查选项
with [ca/local] check option
检查插入时的选项
cascaded:会检查依赖视图中的规则
local:检查视图中有条件的视图规则
视图更新
视图的行和基础表中的行一一对应
视图的作用
简单:将复杂的查询条件定义在视图中
安全:通过视图进行授权,对表进行授权
数据独立:基表的字段变化
十、存储过程/触发器
存储过程:对SQL语句的封装
特点:封装 复用
可以接收参数、可以返回数据、减少网络交互、效率提升
1 | create procedure 存储过程名称 |
变量:
系统变量
1 | show session| global variables; |
用户自定义变量
作用域为当前连接
1 | -- 赋值 |
局部变量
1 | declare 变量名 变量类型 |
- if
1 | if exp then |
参数
1 | create procedure name(in/out/inout var_name 类型) |
Case
1 | case case_value |
while
1 | whlie 条件 do |
repeat
1 | repeat |
loop
1 | [begin label]loop |
游标
1 | declare 游标名称 cursor for 查询语句 |
条件处理程序 handler
1 | declare handler_action hander for condi |
存储函数
1 | create function 名称(参数) |
触发器
insert/update/delete之前之后进行的操作
因此有三种触发器, old new记录变化,现在触发器只支持行级触发
1 | create trigger name |
十一、锁
协调多个进程或线程并发访问某一资源的机制
- 全局锁
- 表级锁
- 行级锁
全局锁
对整个数据库进行加锁,整个实例处于只读状态,DML DDL 阻塞,DQL可以
数据库备份: mysqldump -uroot -p1234 db01 > save_dir
1 | flush tables with read lock; |
表级锁
- 表锁
- 元数据锁MDL
- 意向锁
1 | 表共享读 |
元数据锁:维护表结构的数据一致性,在表上有活动事务时,不能修改元数据,是系统自动控制的。避免DML和DDL冲突
意向锁:避免行锁和表锁冲突。加行锁,再加意向锁。 检查意向锁
行级锁
行锁是通过对索引上的索引项加锁实现的,不是对记录加锁。不通过索引检索数据,会升级为表锁
- 行锁record lock,防止update delete。
- 间隙锁 gap lock,确保索引记录间隙不变,不包含该记录。查询不存在索引记录时,会锁gap。排它锁;对非唯一索引等值查询,会向下继续,加gap锁,向上加临键锁;范围查询:当前行锁,间隙锁,以及到无穷大的间隙锁。防止其他事务插入间隙,间隙锁可以共存
- 临键锁,同时锁住间隙和gap
十二、InnoDB引擎
十三、Mysql管理
系统数据库
- mysql mysql信息 时区、用户
- information_schema 元数据 数据表的信息 视图的信息
- performance_schema 运行状态的底层监控
- sys 性能调佣和诊断