复习——数据库

数据库(《高性能MySQL》)

事务

事务的标准特征

隔离级别

事务日志

脏读、不可重复读、幻读(MVCC、范围锁(行级锁和间隙锁))

死锁

存储引擎

InnoDB

被设计用来支持大量短期事务(很少回滚)、自动崩溃恢复特性、支持行级锁

1. 空间占用过多

2. 批量插入处理速度低

3. 唯一支持外键的存储引擎

MyISAM

不支持事务和行级锁,崩溃后无法安全恢复

1. 对整张表加锁(性能问题)

2. 可以手动或自动执行检查和修复操作(可能导致数据丢失,而且非常慢)

3. 延迟更新索引

4. 占用空间低

5. 批量插入处理速度高

 

索引

索引是存储引擎用于快速找到记录的一种数据结构。

索引是放在内存中的。

索引优化应该是对查询性能优化最有效的手段了。能轻易将查询性能提高几个数量级。

B-Tree索引、B+Tree索引、哈希索引

 

分区表

对用户来说, 分区表是一个独立的逻辑表, 但是底层由多个物理子表组成。 实现分区的代码实际上是对一组底层表的句柄对象的封装。 对分区表的请求, 都会通过句柄对象转化成对存储引擎的接口调用。

索引也是按照分区的子表定义的, 没有全局索引。

分区的主要目的是将数据按照一个较粗的粒度分在不同的表中。这样可以将相关的数据放到一起。 如果想一次批量删除整个分区的数据也会很方便。

分区最大的优点就是优化器可以根据分区函数过滤掉一些分区, 通常可以让查询扫描更少的数据。

应用

1. 表非常大无法全部放在内存中, 或者只在表的最后部分有热点数据

2. 想对一个分区做删除、优化、检查、修复等操作

3. 分区表的数据可以分布在不同的物理设备上, 从而高效地利用多个硬件设备

4. 可以使用分区表避免某种特殊的瓶颈

5. 可以备份和恢复独立的分区, 再大的数据集的场景下非常好

所有的底层表都必须使用相同的存储引擎

过程

1. 打开并锁住所有的底层表

2. 确定分区(优化过滤分区)

3. 对指定分区进行操作

打开并锁住所有的底层表:如果支持行级锁(InnoDB), 会在分区层释放对应表锁

 

使用策略

1. 全量扫面数据, 不要任何索引:使用简单的分区方式存放表, 不要任何索引, 根据分区的规则答指定位需要的数据位置。

2. 索引数据, 并分离热点:如果数据有明显的热点, 而且除了这部分热点数据其他数据很少被访问到, 可以将这部分热点数据单独放在一个分区中, 让这个分区的数据能够有机会都缓存内存中, 就可以对这部分热点数据使用索引。

 

问题:

1. 选择分区的成本可能很高:大量数据写入时, 如果每一条数据都扫描分区定义表找到合适的目标分区, 效率不高。 可以限制分区数量, 如果是键分区和哈希分区, 没有这样的问题。

2. 打开并锁住所有的底层表的成本可能很高:可以用批量操作的方式降低单个操作的此类开销, 同时还要限制分区个数。

3. 维护分区的成本可能很高:重组分区、类似ALTER语句的操作(需要复制数据), 先创建一个临时分区, 将数据复制到其中, 再删除原分区。

还有一些其他限制

... ...

 

视图

视图本身是一个虚拟表, 不存放任何数据。 在使用SQL语句访问视图时, 它返回的数据是从其他表中生成的。MySQL中很多地方将视图和表同样对待。

视图和表也有不同:MySQL视图不能使用触发器、不能用DROP TABLE删除视图、MySQL不支持在视图中创建索引、MySQL不支持物化视图(将视图结果数据放在一张可以查看的表中)等

 

优点:

1. 简化用户操作

2. 安全性:只能查询和修改用户看到的数据

缺点:

每次对视图的操作都需要转化为对基本表的操作, 对于比较复杂的视图, 对性能可能有影响。

 

外键约束

只能引用指定的表中的内容。

外键需要在另一张表中查找内容, InnoDB强制外键使用索引, 但还是无法消除查找的开销。

在某些场景下, 外键会提升一些性能。

 

存储过程和函数的区别

https://www.cnblogs.com/youxin/p/3568379.html

1. 一般来说, 存储过程的功能复杂一些, 函数功能的针对性更强一些

2. 函数只能返回一个变量, 存储过程可以返回多个, 函数的参数只能有IN, 而存储过程的参数有IN、OUT、INOUT, 存储过程不需要返回类型, 函数必须要返回类型以及RETURN语句

3. 存储过程可以使用非确定函数, 函数不可以

4. 存储过程一般作为单独的的部分使用, SQL语句中不可以使用存储过程, 可以使用函数。

 

触发器

可以让你在执行INSERT、UPDATE或DELETE的时候执行一些特定的操作。

可以指定在SQL语句执行前触发还是执行后触发, 本身没有返回值, 可以读取或者改变SQL语句所影响的数据。

可以用于加强数据完整性约束或实现强制限制及某些业务逻辑。

 

1. 每一个事件只能定义一个触发器

2. MySQL只支持基于行的触发, 触发器只是针对一条数据的, 不是针对整个SQL语句, 如果变更的数据集非常大, 效率会很低

3. 触发器的问题很难排查

4. 不能保证更新的原子性, 失败不会回滚(InnoDB中是原子的)

 

事件

是MySQL5.1引入的一种新的存储代码的方式, 类似于Linux的定时任务。 可以创建事件, 指定MySQL在某个时候执行一段SQL代码, 或者每隔一段时间间隔执行一段SQL代码

 

游标

MySQL在服务器端提供只读的单向的游标, 只能在存储过程或更底层的客户端的API中使用。

MySQL游标中指向的对象都是存储在临时表中而不是实际查询道德数据, 所以MySQL中的游标总是只读的。

可以逐行指向查询结果, 让程序做进一步处理。

可以将游标理解为指针, 每次指向一行数据, 处理完后可以指向下一行...

在一个存储过程中, 可以有多个游标, 可以在循环嵌套地使用游标。

 

复习——数据库

上一篇:Oracle 备份脚本


下一篇:iOS底层原理(三)Category