MySQL八股文面试

1.MySQL有哪些存储引擎(表类型)

  • MyISAM
    成熟稳定、快速读取,不支持事务,有表锁
  • InnoDB
    支持事务、外键、数据行锁,空间占用大,不支持全文索引
  • HEAP
  • BOB
  • ARCHIVE
  • CSV
    常用的就MyISAM和InnoDB

2.myisam和innodb的区别

最大的区别就在于事务和锁上

  1. myisam不支持事务,适合频繁查询、小数据量、小并发的应用。表锁,不会出现死锁。
  2. innodb支持事务,适合插入、更新操作比较多的应用,行锁。

3.MySQL数据库,一天五万条左右的增量,预计运维三年,如何优化?

  1. 设计好数据库结构,允许数据冗余,减少join操作
  2. 选择合适的存储引擎与数据类型,适当的添加索引
  3. 配置MySQL读写分离,提高效率
  4. 在项目中添加二级缓存,ehcache、redis等
  5. 提高sql的执行效率,即sql优化

4.如何进行sql优化

1.选择合适的存储引擎

  • myisam适合大量查询,很少写入的场景,查询速度非常快,因为是表锁,每次写入都会将整个表锁起来,其他进程无法对表进行操作,直到写入结束。
  • innodb查询速度比myisam慢,但是支持行锁,允许事务,适合写入操作很频繁的场景。

2.优化字段的数据类型

选择合适的数据类型,存储数据长度越小的列操作越快,当然需要留够扩展空间。
比如一个表只会有几列数据,那么就没有必要用int来作为主键,要选择更小的smallint或tinyint。
如果不需要记录具体的时间,使用date比datetime要好很多。

3.为搜索字段添加索引

除主键外,也要给搜索字段添加索引,除非是一个大文本字段,那需要建立全文索引,但是5.6之前MySQL的innodb不支持全文索引。

4.避免使用seelct *

这会导致查询变得很慢,即使要查询数据库表全部的字段,也不要用 select *。

5.在某些情况下使用enum而不是varchar

enum是一个非常快、紧凑的类型,在底层上存储的是tinyint,在外部表现为字符串。
可以用于【性别、民族、国家、部门、状态】这种有固定值的字段,在这类字段上比varchar的表现要好。

6.尽量让表成为一张【固定长度静态表】

表内所有的字段都是【固定长度】的数据类型,则这张表会被视为【static或fixed-length 即固定长度静态表】,这种表效率会更高。
比如表里不存在【varchar、text、blob】,如果包含了则不会是【固定长度静态表】。
固定的长度很容易计算下一个数据的偏移量,因此查询会很快。如果字段不是定长,每次寻找下一条时,需要先找到主键。
固定长度的表更容易被缓存和重建,唯一的副作用是,固定长度会浪费一些空间,定长字段无论你用不用,都会占这么多空间。

7.尽量不要让字段处于null的状态

当一个字段没有被赋值的时候,是处于一个null的状态,null也是需要额外存储空间的,最关键的是在where比较时会拖垮sql效率,放弃索引,走全表扫描。
尽量给字段一个合适的默认值,来替代null的状态。

5.如何设计一个高并发的系统

  1. 数据库层面:合理安排事务隔离级别,sql语句优化、索引优化
  2. 尽量缓存,减少直接打到数据库的读操作
  3. 配置MySQL读写分离

6.锁的优化策略

  1. 读写分离
  2. 分段加锁
  3. 减少锁的持有时间
  4. 多线程尽量以相同的顺序去获取锁
    以上并非绝对原则,要根据实际情况来定。比如不能将锁的粒度过于细化,否则可能会导致线程加锁、释放锁次数过多,效率反而不好。

7.索引的底层实现原理和优化

B+树,经过优化的B+树。
主要是在所有的叶子节点中,增加了指向下一个叶子节点的指针,因此innodb引擎建议大部份表使用默认的自增逐渐作为主索引。

8.什么情况下会导致:设置了索引,但是无法使用

  1. 以 % 开头的like语句
  2. or语句前后没有同时使用索引
  3. 数据类型出现隐式转换,比如varchar不加单引号可能会转为int
  4. 使用 != 或 <>

9.sql语句的优化

  1. 尽量避免全表查询,在where条件和order by中的字段上索引
  2. 在where条件中避免使用 != 或 <> 操作,这样会放弃索引,走全表扫描
  3. 避免对字段进行null值判断,这样会放弃索引,走全表扫描
  4. 避免使用or进行操作,很容易导致放弃索引,走全表扫描
  5. 避免在where中对字段进行表达式操作,这样会放弃索引,走全表扫描,例如
select id from t where num/2 = 100
/*应改为:*/
select id from t where num = 100 * 2
  1. 避免在where中对字段进行函数操作,这样会放弃索引,走全表扫描,例如
select id from t where substring(name,1,3) = 'abc'  --name以abc开头的id
select id from t where datediff(day,createdate,'2005-11-30') = 0    --'2005-11-30'生成的id

/*应改为:*/

select id from t where name like 'abc%' /*注意这里like左边没有用%*/
select id from t where createdate >= '2005-11-30' and createdate < '2005-12-1'
  1. 索引不是越多越好,过多的索引会降低insert、update的效率,在插入和更新操作时,会重建索引。一般一张表不要超过6个索引,超过6个时,就要考虑一下有一些是不是没必要。
  2. 使用join来替代子查询
  3. 使用联合(UNION)来代替手动创建的临时表

10.优化MySQL整体的效率

他们四条从效果上第一条影响最大,后面越来越小

  1. sql语句和索引的优化
  2. 数据库表结构与引擎的优化
  3. 系统配置优化
  4. 硬件加配置!

11.MySQL中,索引、主键、唯一索引、联合索引的区别,对数据库性能有何影响?

索引(key或index)

索引是一种特殊文件(innodb数据表上的索引是表空间的一个组成部分),包含对数据表里所有记录的引用指针。
普通索引(关键字key或index定义的索引)唯一的任务就是加快对数据的访问速度。
普通索引允许出现重复的值。

唯一索引(UNIQUE)

唯一索引和索引的区别在一,唯一索引不允许出现数据重复。

主键(PRIMARY KEY)

主键是一种特殊的唯一索引,一张表只能有一个

联合索引 【 INDEX(columnA, columnB) 】

覆盖多个数据列的索引,列如 INDEX(columnA, columnB, columnC),这就是联合索引,比如电话簿里的名称和手机号是一对。
联合索引是有顺序的,支持a 、 a,b 、 a,b,c 3种组合进行查找,但不支持 b,c进行查找,当最左侧字段是常量引用时,索引就十分有效。

对数据库的影响

索引会加快查询速度,但是会降低插入、更新、删除的速度,因为需要额外的变更索引文件。

12.key和index的区别

  • key是数据库的物理结构,有两层意义和作用,一个是约束(偏重于约束和规范数据库的结构完整性),第二个是索引(辅助查询用的)。
    包括primary key, unique key, foreign key 等
  • index是数据库的物理结构,只是辅助查询的,创建时会在另外的表空间(mysql中的innodb表空间)以一个类似于目录的结构存储。
    包括前缀索引、全文本索引等

13. 外键和主键的区别

主键是本表的,外键是其他表的主键,一张表可以有多个外键,但是只能有一个主键

14.MySQL内连接、外连接区别

  • 交叉连接 :交叉连接又叫笛卡尔积,是指不用任何条件,直接将一个表的所有记录和另一个表的所有记录挨个匹配。
  • 内连接 :只有条件的交叉连接,根究条件筛选出合适的记录,内连接只连接匹配的行
  • 外连接 :结果集不仅包含符合条件的行,还可以包含【左表、右表、两个表中所有的数据行】,空值用null表示,分表叫【左外连接、右外连接、全外连接】

15.mysql支持的分区类型

  • RANGE分区:将数据划分为不同的范围,例如将一个表通过年份分为若个分区。
  • LIST分区:通过与定义的列表值,对数据进行分割,按照list中的值分区。
  • HASH分区:通过对表中一个或多个字段的hash进行分区,例如建立一个对标主键进行分区的表。
  • KEY分区:上面Hash模式的一种延伸,这里的Hash Key是MySQL系统产生的。

16.什么是事务

事务(transaction)是作为一个单元的一组有序数据库操作。
如果组里所有的操作都成功,则事务成功,提交事务,所有操作将推广至所有其他数据库进程。
有一个操作失败,则事务失败,进行事务回滚,该事务的所有操作都被当作没进行过。

17.事务四种隔离级别

  1. Serializable (串行化):可避免脏读、不可重复读、幻读的发生。
  2. Repeatable read (可重复读):可避免脏读、不可重复读的发生。
  3. Read committed (读已提交):可避免脏读的发生。
  4. Read uncommitted (读未提交):最低级别,任何情况都无法保证。
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值