空空叶博客 学习与开发博客

mysql

2017-05-05
sql

mysql

存储引擎

INNODB

优点:

  1. 支持事务
  2. 支持外键
  3. 支持行级锁

MyISAM

是MYSQL的ISAM的扩展格式

ISAM的优点:

  1. 读取速度快!!!不占用大量内存与存储资源

MyISAM相对于ISAM的优点:

  1. 索引
  2. 字段管理
  3. 表格锁定机制,来优化并发读写(但代价是需要经常运行OPTIMIZE TABLE命令来恢复被更新机制浪费的空间)

INNODB vs MyISAM

两者主要不同在于innodb支持事务与外键,而MyISAM查询速度很快

isolation level

事务隔离级别

Read Uncommitted

读取未提交内容(实际很少用)

可能产生:

  1. 脏读: 某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因,前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的
  2. 不可重复读
  3. 幻读

Read Committed

读取提交内容

可能产生:

  1. 不可重复读: 因为同一事务的其它实例可能产生新的commit,因此同一select可能返回不同结果
  2. 幻读

可能产生: 不可重复读,幻读

Repeatable Read

可重读(Mysql的默认级别)

它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行

可能产生:

  1. 幻读: 当用户读取某一范围的数据行时,另一个事务又插入了新行,当用户再读取此范围的数据时,会发现有新的’幻影’行.(InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题)

Serializable

可串行化

最高隔离级别,不会冲突,解决幻读问题,但可能导致大量的超时与锁竞争.

隔离级别如何选择?

两个极端一般不要用,Serializable效率低,Read Uncommitted不安全, 默认Repeatable Read够用了,如果确保不会产生问题,也可以用Read Committed来优化提高效率.

Repeatable Read测试: 根据官方文档与实际测试结果,开启事务时,第一次查询时会保存快照,下次再查询时,就会使用快照来保证一致性.

比如一个表内的一条数据,开启事务A时某个值是x,然后被其它事务更新为y,然后事务A再查询,此时查询到的值是y(这是第一次查询,会保存快照),然后其它事务更新值为z,事务A再查询时查到的还是y(因为是从快照中获取的)

propagation level (事务传播级别)

PROPAGATION_REQUIRED

###

知识点

ACID

atomicity(原子性),consistency(一致性),isolation(隔离性),durability(持久性)

这几个特性都跟事务有关.

事务是原子性(atomicity)的,要么commit,要么roll back

数据库永远是一致性的(consistency),即使有事务正在进行中,如果相关数据正在更新,那么请求要么看到更新前的,要么看到更新后的,不会看到新旧值混合的状态.

双写缓冲

在将页面写入数据文件前,Innodb会先在硬盘上分配连续的区域当作双写缓冲区,在数据先写入缓冲区(顺序写)后,才会被写入数据文件(随机写).

是否总是需要双写缓冲?有的情况下不需要,可以关闭,如数据库主从架构中的从库就不需要,有的文件系统如ZFS会做同样的事,也不需要.

缺点: 会降低性能,但不会降低到50%,主要原因是它是连接的空间,是顺序写而非随机写

崩溃恢复

Innodb来说:

  • 未完成的事务会通过redo log进行重做
  • 已经commit但未写入数据文件的,会从双写缓冲重新读入

Procedure & Function

创建时definer默认为当前用户

用户定义变量

格式@变量名,变量名可包含字母,.,_,$,如果包围起来,则还能包含其它字符,如'my-var'

用户定义变量所属于会话Session

如何设置?

  1. SET语句中设置,SET @var = expr;SET @var := expr;
  2. 非SET语句中设置,此时只能用:=而不能用=,因为=会被看作比较操作,如SELECT @var1, @var2, @var3:=@var1+@var2

值类型

可以使用以下值类型:

  • integer
  • decimal
  • floating-point
  • binary or nonbinary string
  • NULL

在结果集中返回给客户端的用户变量是string型的

未初始化的变量值为NULL,类型是string

连接池大小

并非越大越好!!!

有个大致的公式: connections = ((core_count * 2) + effective_spindle_count)

比如4核cpu,可以设置连接池大小为10


上一篇 maven

下一篇 nginx

目录