1.什么是MySQL?
一个开源的关系型数据库,默认端口3306
1.1数据库引擎MyISAM和InnoDB的区别
是否支持行级锁:MyISAM只有表级锁,InnoDB支持表级锁和行级锁,默认行级锁
是否支持事务和崩溃后的安全恢复:MyISAM强调的是性能,每次查询具有原子性,执行速度比InnoDB类型更快,但是不提供事务支持。但是InnoDB提供事务支持事务,外部键等高级数据库。具有事务、回滚和崩溃修复能力的事务安全型表
是否支持外键:MyISAM不支持外键,InnoDB支持外键
是否支持MVCC:仅InnoDb支持,应对高并发事务,InnoDB比单纯的加锁更高效;
MVCC只在 READ COMMITED 和 REPEATABLE READ 两个隔离级别下工作;MVCC可以使用乐观锁和悲观锁来实现
1.2索引
MySQl索引使用的数据结构主要为:BTree索引和哈希索引
当绝大多数需求为单条记录查询的时候,可以选择哈希索引,查询性能最快;其余大多数场景,建议选择BTree索引
MyISAm:非聚簇索引
InnoDB:聚簇索引
1.3什么是事务?
事务是逻辑上的一组操作,要么都执行,要么都不执行
1.31事务的四大特性ACID
- 原子性:事务是最小的执行单位,不允许分割,执行的动作要么全部完成,要么完全不起作用
- 一致性:执行事务前后,数据保持一致,多个事务对同一数据读取的结果是相同的
- 隔离性:并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
- 持久性:一个事务被提交之后。他对数据库中的数据的改变是持久的,及时数据库发生故障也不应该对其有任何的影响。
1.4并发事务带来哪些问题?
- 脏读:一个事务访问数据并对其进行了修改,但是修改并未提交到数据库的时候,另外一个事务也访问了这个数据(此时数据还未提交修改)。那么它读取到的数据被称为“脏数据”
- 丢失修改:一个事务读取一个数据时,另外一个事务也访问了该数据,那么在第一个事务修改了这个数据后,第二个事务也对它进行修改。这样第一个事务的修改结果就被丢失,因此被称为丢失修改。例如:事务1读取某张表中的数据a=20,事务2也读取a=20,事务1修改a=a-1,事务2修改a=a-1,最后a=19,事务1的修改丢失
- 不可重复读:在一个事务内多次读取同一数据。这个事务还没有结束时,另外一个事务也访问该数据。那么在第一个事务中的两次读数据之间,由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。这就发生了在一个事务内两次督导的数据是不一样的情况,因为称为不可重复读;
- 幻读:类似于不可重复读,例如事务1读取了几行数据,此时事务2并发插入了一些数据,随后事务1查询,会发现多了一些原本不存在的记录,就好像产生了幻觉一样
- 不可重复读和幻读的区别:不可重复读重点是修改,比如读取的某条记录发现其中的某些列值被修改,幻读的重点在于新增或者删除比如多次读取一条记录发现记录增多或者减少了。
1.5事务隔离级别有哪些?MySQL的默认隔离级别是?
SQL标准定义了四个隔离级别:
- READ-UNCOMMITTED(读取未提交): 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。
- READ-COMMITTED(读取已提交): 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。
- REPEATABLE-READ(可重复读): 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
- SERIALIZABLE(可串行化): 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| READ-UNCOMMITTED | √ | √ | √ |
| READ-COMMITTED | × | √ | √ |
| REPEATABLE-READ | × | × | √ |
| SERIALIZABLE | × | × | × |
MySQL默认隔离级别是可重复读(REPEATABLE-READ) 但MySQL事务隔离级别下使用的是Next-Key Lock 锁算法,因此可以避免幻读的产生。所以说InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重读) 已经可以完全保证事务的隔离性要求,即达到了 SQL标准的 SERIALIZABLE(可串行化) 隔离级别。InnoDB存储引擎在分布式事务的情况下一般才会用到 **SERIALIZABLE(可串行化)**隔离级别
2.0 锁机制和InnoDB锁算法
- MyISAM采用表级锁
- InnoDB支持行级锁和表级锁,默认行级锁
2.1表级锁和行级锁对比
- 表级锁:MySQL中锁定粒度最大的一种锁,对当前操作的整张表加锁,实现简单,资源消耗也比较少,不会出现死锁。锁定粒度最大,触发锁冲突的概率最高,并发度最低
- 行级锁:MySQL中锁定粒度最小的一种锁,值针对当前操作的行进行加锁。行级锁能大大减少数据库操作的冲突。加锁粒度最小,并发程度高,但加锁的开销也最大,加锁慢,会出现死锁
2.2 InnoDB引擎的锁的算法
- Rcord Lock:单个行记录上锁
- Gap Lock:间隙锁,锁定一个范围,不包括记录本身
- Next-Key lock:record+gap锁定一个范围,包含记录本身
3.0大表优化
- 限定数据的范围:务必禁止不带任何限制数据范围条件的查询语句。比如:我们当用户在查询订单历史的时候,我们可以控制在一个月的范围内
- 读写分离:经典的数据库拆分方案,主库负责写,从库负责读
- 垂直拆分:简单来说垂直拆分是指数据表列的拆分,把一张列比较多的表拆分为多张表
- 水平拆分:保持数据表结构不变,通过某种策略存储数据分片
3.1分库分表后,id主键如何处理?
生成全局ID的方式
- UUID:
- 数据库自增ID
- 利用redis生成ID
- Twitter的snowflake算法
- 美团的leaf分布式ID生成系统
3.2Inner join 、left join、right join有什么区别?
- Inner join 内连接,在两张表进行连接查询时,只保留两张表中完全匹配的结果集
- left join 在两张表进行连接查询时,会返回左表所有的行,即使在右表中没有匹配的记录。
- right join 在两张表进行连接查询时,会返回右表所有的行,即使在左表中没有匹配的记录。