1、ACID

(1)ACID是靠什么来保证的

ACID(数据库事务正确执行的四个基本要素的缩写)

原子性、一致性、隔离性、持久性

  • 原子性

undolog

  • 隔离性

MVVC

  • 持久性

redolog

  • 一致性

由其他三个特性来保证的

2、MVVC

(1)MVCC解决的问题到底是啥

MVCC:多版本并发控制(常常用在数据库里的技术)

数据库并发场景有三种:

  • 读读

    不存在任何问题,无需并发控制

  • 读写

    有线程安全,可能会造成事务的隔离性问题,可能遇到脏读、幻读、不可重复读

  • 写写

    有线程安全问题,可能存在更新丢失问题

脏读(读取未提交数据):脏读又称无效数据的读出,是指在数据库访问中,事务T1将某一值修改,然后事务T2读取该值,此后T1因为某种原因撤销对该值的修改,这就导致了T2所读取到的数据是无效的,值得注意的是,脏读一般是针对于update操作的。

幻读(前后多次读取,数据总量不一致):事务A在执行读取操作,需要两次统计数据的总量,前一次查询数据总量后,此时事务B执行了新增数据的操作并提交后,这个时候事务A读取的数据总量和之前统计的不一样,就像产生了幻觉一样,平白无故的多了几条数据,成为幻读。

不可重复读(前后多次读取,数据内容不一致):事务A在执行读取操作,由整个事务A比较大,前后读取同一条数据需要经历很长的时间 。而在事务A第一次读取数据,比如此时读取了小明的年龄为20岁,事务B执行更改操作,将小明的年龄更改为30岁,此时事务A第二次读取到小明的年龄时,发现其年龄是30岁,和之前的数据不一样了,也就是数据不重复了,系统不可以读取到重复的数据,成为不可重复读。

不可重复读和幻读到底有什么区别呢?

(1) 不可重复读是读取了其他事务更改的数据,针对update操作

解决:使用行级锁,锁定该行,事务A多次读取操作完成后才释放该锁,这个时候才允许其他事务更改刚才的数据。

(2) 幻读是读取了其他事务新增的数据,针对insert和delete操作

解决:使用表级锁,锁定整张表,事务A多次读取数据总量之后才释放该锁,这个时候才允许其他事务新增数据。

MVCC为事务分配单项增长的时间戳,为每个修改保存一个版本,版本与事务时间戳关联,读操作只读事务开始前的数据库快照,所以MVCC可以为数据解决以下问题:

​ 1、在并发读写数据库时,可以在读操作时不阻塞写操作,写操作也不阻塞读操作,提高了数据库并发读写的能力

​ 2、解决脏读、幻读、不可重复读等事务隔离问题,但是不能解决更新丢失问题

(2)MVCC实现原理

3、MySQL的隔离级别有哪些?

https://www.cnblogs.com/fengzheng/p/12557762.html

首先我们来看看隔离级别是个玩意

有四种隔离级别

  1. 读未提交(READ UNCOMMITTED)

    所有事务都可以看到未提交事务的执行结果

  2. 读提交 (READ COMMITTED)

    一个事务开始时,只能看到已经提交事务所做的改变

  3. 可重复读 (REPEATABLE READ)

    ???

  4. 串行化 (SERIALIZABLE)

    通过强制事务排序

隔离级别 脏读 不可重复读 幻读
读未提交 可能 可能 可能
读提交 不可能 可能 可能
可重复读 不可能 不可能 可能
串行化 不可能 不可能 不可能

4、MySQL索引

https://www.cnblogs.com/zsql/p/13808417.html

(1)为什么要有索引?

一般的应用系统中,读写比例为10:1,而且插入和一般的更新操作很少出现性能问题

生产环境中,我们遇到最多的也是最容易出问题的,是一些复杂的查询操作

索引就是为了进行高速查询

(2)什么是索引?

索引在MySQL中也叫一种“键”,是存储引擎用于快速找到记录的一种数据结构

索引对于良好的性能非常关键,尤其是当表的数据量愈发巨大时,索引对于性能的影响愈发巨大

索引就相当于字典的音序表

(3)索引的原理

(4)索引的数据结构

MySQL主要用到两种结构:B+Tree索引和Hash索引

Inodb存储引擎默认是B+Tree索引

Memory存储引擎默认是Hash索引

Hash索引

(5)聚簇和非聚簇索引的区别

索引存在于磁盘,MySQL的索引类型与存储引擎是相关的,innobd存储引擎数据文件和索引文件全都放在ibd文件中,而myisam的数据文件全都放在myd文件中,索引放在myi文件中,判断条件:数据和索引是否是分开的

(6)索引分类

按数据结构分类可分为:B+tree索引、Hash索引、Full-text索引
按物理存储分类可分为:聚簇索引、二级索引(辅助索引)
按字段特性分类可分为:主键索引、普通索引、前缀索引
按字段个数分类可分为:单列索引、联合索引(复合索引、组合索引)

5、数据库事务、主键和外键的区别

  • 事务即用户定义的一个数据库操作序列,这些操作要么全做要全不做,是一个不可分割的工作单位,它具有四个特性,即ACID:原子性、一致性、隔离性、持续性
  • 主键是能确定一条记录的唯一标识
  • 外键用于与另一张表的关联,是能确定另一张表记录的字段,用于保持数据的一致性

6、简单介绍having和where的区别

  • 用的地方不一样

    where可以用于selectupdatedeleteinsert into values(select * from table where …)语句中

    having只能用于select语句中

  • 执行的顺序不一样

    where的搜索条件是在执行语句进行分组之前应用

    having的搜索条件是在分组条件后执行的,即如果where和having一起用时,where会先执行,having后执行

  • 子句有区别

    where子句中的条件表达式having都可以跟

    having子句中的有些表达式where不可以跟,例如集合函数(sum、count、avg、max和min)

总之,WHERE 子句用来筛选 FROM 子句中指定的操作所产生的行。GROUP BY 子句用来分组 WHERE 子句的输出。HAVING 子句用来从分组的结果中筛选行

7、SQL优化技巧

SQL优化技巧

MySQL优化的五个原则:

  • 减少数据的访问

    压缩、索引等手段减少磁盘IO

  • 返回更少的数据

    只返回需要的字段和数据分页处理,减少磁盘 IO 及网络 IO

  • 减少交互次数

    批量 DML 操作,函数存储等减少数据连接次数

  • 减少服务器 CPU 开销

    减少数据库排序操作以及全表查询,减少 CPU 内存占用

  • 利用更多资源

    使用表分区,可以增加并行操作,更大限度利用 CPU 资源

总结到SQL:

  • 最大化利用索引
  • 尽可能避免全表扫描
  • 减少无效数据的查询

(1)避免不走索引的场景

  • 避免在字段开头模糊查询,会导致数据库放弃索引全表扫描

    如:SELECT * FROM t WHERE username LIKE '%陈%'

    改为:SELECT * FROM t WHERE username LIKE '陈%'

  • 尽量避免使用 in 和 not in,会导致引擎走全表扫描

  • 如果是子查询,可以用 exists 代替

    如:select * from A where A.id in (select id from B);

    改为:select * from A where exists (select * from B where B.id = A.id);

  • 尽量避免使用 or,会导致数据库引擎放弃索引进行全表扫描

    可以用 union 代替 or,如下:

    SELECT * FROM t WHERE id = 1 OR id = 3改为

    SELECT * FROM t WHERE id = 1 UNION SELECT * FROM t WHERE id = 3

  • 尽量避免进行 null 值的判断,会导致数据库引擎放弃索引进行全表扫描

    如:SELECT * FROM t WHERE score IS NULL

    改为0值判断:SELECT * FROM t WHERE score = 0

  • 查询条件不能用 <> 或者 !=

    使用索引列作为条件进行查询时,需要避免使用<>或者!=等判断条件

  • order by 条件要与 where 中条件一致,否则 order by 不会利用索引进行排序

    如:SELECT * FROM t order by age;

    改为:SELECT * FROM t where age > 0 order by age;

8、联合索引和单独建立索引的区别