1. MySQL InnoDB、MyISAM的特点?
InnoDB:
- ⽀持事务处理
- ⽀持外键
- ⽀持⾏锁
- 不⽀持FULLTEXT类型的索引(在Mysql5.6已引⼊)
- 不保存表的具体⾏数,扫描表来计算有多少⾏
- 对于AUTO_INCREMENT类型的字段,必须包含只有该字段的索引
- DELETE 表时,是⼀⾏⼀⾏的删除
- InnoDB 把数据和索引存放在表空间⾥⾯
- 跨平台可直接拷⻉使⽤
- 表格很难被压缩
MyISAM:
- 不⽀持事务,回滚将造成不完全回滚,不具有原⼦性
- 不⽀持外键
- ⽀持全⽂搜索
- 保存表的具体⾏数,不带where时,直接返回保存的⾏数
- DELETE 表时,先drop表,然后重建表
- MyISAM 表被存放在三个⽂件 。frm ⽂件存放表格定义。 数据⽂件是MYD (MYData) 。 索引⽂件是MYI(MYIndex)引伸
- 跨平台很难直接拷⻉
- AUTO_INCREMENT类型字段可以和其他字段⼀起建⽴联合索引
- 表格可以被压缩
选择:因为MyISAM相对简单所以在效率上要优于InnoDB。如果系统读多,写少。对原⼦性要求低。那么MyISAM最好的选择。且MyISAM恢复速度快。可直接⽤备份覆盖恢复。如果系统读少,写多的时候,尤其是并发写⼊⾼的时候。InnoDB就是⾸选了。两种类型都有⾃⼰优缺点,选择那个完全要看⾃⼰的实际情况。
2. ⾏锁,表锁;乐观锁,悲观锁?
⾏锁:数据库表中某⼀⾏被锁住。
表锁:整个数据库表被锁住。
乐观锁:顾名思义,就是很乐观,每次去拿数据的时候都认为别⼈不会修改,具体实现是给表增加⼀个版本号的字段,在执⾏update操作时⽐较该版本号是否与当前数据库中版本号⼀致,如⼀致,更新数据,反之拒绝。
悲观锁:顾名思义,就是很悲观,每次去拿数据的时候都认为别⼈会修改。读数据的时候会上锁,直到update完成才释放锁,使⽤悲观锁要注意不要锁住整个表。
3. 数据库隔离级别是什么?有什么作⽤?
ISOLATION_READUNCOMMITTED 这是事务最低的隔离级别,它允许另外⼀个事务可以看到这个事务未提交的数据。这种隔离级别会产⽣脏读,不可重复读和幻读。
ISOLATION_READCOMMITTED 保证⼀个事务修改的数据提交后才能被另外⼀个事务读取。另外⼀个事务不能读取该事务未提交的数据。这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻读。
ISOLATION_REPEATABLEREAD 这种事务隔离级别可以防⽌脏读,不可重复读。但是可能出现幻读。它除了保证⼀个事务不能读取另⼀个事务未提交的数据外,还保证了避免不可重复读。
ISOLATION_SERIALIZABLE 这是花费最⾼代价但是最可靠的事务隔离级别。事务被处理为顺序执⾏。除了防⽌脏读,不可重复读外,还避免了幻读。
未提交读(Read Uncommitted):允许脏读,也就是可能读到其他会话中未提交事务修改的数据。
提交读(Read Committed):只能读取到已经提交的数据,Oracle等多数数据库默认都是该级别(不重复读)。
可重复读(Repeated Read):可重复读。在同一事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻读。
串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞。
4. MySQL主备同步的基本原理
mysql主备复制实现分成三个步骤:
- master将改变记录到⼆进制⽇志(binary log)中(这些记录叫做⼆进制⽇志事件,binary log events,可以通过show binlog events进⾏查看);
- slave将master的binary log events拷⻉到它的中继⽇志(relay log);
- slave重做中继⽇志中的事件,将改变反映它⾃⼰的数据。
5. select * from table t where size > 10 group by size order by size的sql语句执⾏顺序?
sql语句执⾏顺序如下:
- where -> group by -> having -> select -> orderby
6. 如何优化数据库性能(索引、分库分表、批置操作、分⻚算法、升级硬盘SSD、业务优化、主从部署)
- 选择合适的数据库引擎,合理使⽤索引
- 分⻚获取数据,只获取需要的字段
- 优化业务逻辑,减少数据库IO
- 分库分表
- 部署主从数据库
- 升级硬件
7. SQL什么情况下不会使⽤索引(不包含,不等于,函数)
- select * 可能导致不⾛索引;
- 空值会导致不⾛索引,因为hashset不能存空值;
- 索引列有函数运算,不⾛索引,可以在索引列建⽴⼀个函数的索引。
- 隐式转换可能导致不⾛索引;
- 表的数据库⼩或者需要选择⼤部分数据,不⾛索引;
- !=或者<>可能导致不⾛索引;
- 字符型的索引列会导致优化器认为需要扫描索引⼤部分数据且聚簇因⼦很⼤,最终导致弃⽤索引扫描⽽改⽤全表扫描⽅式
- like ‘%liu’ 百分号在前不⾛索引;
- not in, not exist不⾛索引;
8. —般在什么字段上建索引(过滤数据最多的字段)
- 表的主键、外键必须有索引;
- 数据量超过300的表应该有索引;
- 经常与其他表进⾏连接的表,在连接字段上应该建⽴索引;
- 经常出现在Where⼦句中的字段,特别是⼤表的字段,应该建⽴索引;
- 索引应该建在选择性⾼的字段上;
- 索引应该建在⼩字段上,对于⼤的⽂本字段甚⾄超⻓字段,不要建索引;
9. 如何从⼀张表中查出name字段不包含"XYZ"的所有⾏?
select * from table where name not like '%XYZ%';
10. HRedis, RDB和A0Ff如何做⾼可⽤、集群
11. 如何解决⾼并发减库存问题
消息队列,异步处理,减库存加锁
12. mysql存储引擎中索引的实现机制
13. 数据库事务的⼏种粒度
表锁定:对整个表的锁定。
⾏锁定:只锁定进⾏更改的⾏,例如:insert,update,delete,都隐式采⽤⾏锁定。
数据库锁机制可分为多种粒度的: 数据库,表,⻚⾯,⾏粒度越⼤,DBMS管理越容易,但是实现并发处理的能⼒就越差,表,⻚⾯,⾏。
14. mysql调优
- explain select语句;
- 当只要⼀条数据时使⽤limit 1;
- 为搜索字段建索引;
- 避免select *;
- 字段尽量使⽤not null;
- 垂直分割;
- 拆分⼤的delete和insert语句:delete和insert会锁表;
- 分表分库分区。
15. 说说事务的四种特性(ACID)?
16. innodb如何实现mysql的事务?
事务进⾏过程中,每次sql语句执⾏,都会记录undo log和redo log,然后更新数据形成脏⻚,然后redo log按照时间或者空间等条件进⾏落盘,undo log和脏⻚按照checkpoint进⾏落盘,落盘后相应的redo log就可以删除了。此时,事务还未COMMIT,如果发⽣崩溃,则⾸先检查checkpoint记录,使⽤相应的redo log进⾏数据和undo log的恢复,然后查看undo log的状态发现事务尚未提交,然后就使⽤undo log进⾏事务回滚。事务执⾏COMMIT操作时,会将本事务相关的所有redo log都进⾏落盘,只有所有redo log落盘成功,才算COMMIT成功。然后内存中的数据脏⻚继续按照checkpoint进⾏落盘。如果此时发⽣了崩溃,则只使⽤redo log恢复数据。
17. 让你设计⼀个索引,你会怎么设计?
mysql默认存储引擎innodb只显式⽀持B树索引,对于频繁访问的表,innodb会透明建⽴⾃适应hash索引,即在B树索引基础上建⽴hash索引,可以显著提⾼查找效率,对于客户端是透明的,不可控制的,隐式的。