MySQL面试中常见问题总结

1. JDBC连接的过程

  1. 加载驱动
    1. Class.forName("com.mysql.jdbc.Driver");
  2. 通过协议,子协议,ip,端口,URL创建连接,获取到连接对象
    1. Connection connection = DriverManager.getConnection("jdbc:mysql://xxx.xxx.xxx.xxx/jdbc?xxxxxx&xxxxx")
  3. 编写sql语句
  4. 传入sql,获得statement对象
    1. PreparedStatement ps = connection.prepareStatement
    2. 如果是加参数的sql(?作为占位符),需要填充参数
    3. ps.setObject(1, obj)
  5. 执行statement中的sql,获得结果集
    1. ResultSet resultSet=statement.executeQuery();
    2. ResultSet resultSet=statement.executeUpdate();
    3. ResultSet resultSet=statement.execute();
  6. 处理结果集
    1. rs.next() 类似于迭代器

2. 连接池

​ 在程序运行中,如果每次访问数据库都需要建立连接,使用完毕之后在关闭连接.网络开销和对系统资源的占用都非常大.那么依据资源池的思想,将连接使用完之后不进行关闭,而是放入连接池中,下一次进行重用.这就诞生了连接池

(1). 连接池的工作原理

  1. 连接池的建立
    1. 系统初始化时会根据系统配置建立连接池,并初始化几个连接对象.
  2. 连接池的管理
    1. 请求连接
      1. 当线程请求数据库连接时,如果有空闲连接,分配给线程使用
      2. 如果没有空闲连接,那么判断当前连接数量是否超出连接池上限
      3. 如果没有,那么创建新的连接
      4. 如果已经达到上限,任务等待
      5. 任务等待时间超出最大等待时间时,抛出异常
    2. 释放连接
      1. 当线程释放数据库连接时,会判断当前连接的引用次数是否超过规定值
      2. 如果超过,就从连接池中删除这个连接,否则进行白柳
  3. 连接池的关闭
    1. 当应用程序退出时,关闭连接池中的所有连接,释放相关资源

(2). 连接池主要参数

  • 最小连接数:初始化时就要达到的连接数量
  • 最大连接数:字面意思
  • 最大空闲时间:连接不被使用的最大时间,为了避免过多占用系统内存
  • 获取连接超时时间
  • 超时重连次数

3. 数据库范式

如何理解关系型数据库的常见设计范式?

​ 主码是指主键的集合(一张表被多个键唯一确定)

​ 主码中的每一个属性都是主属性.

(1). 第一范式(1NF)

​ 属性域不可分割,要具有原子性.

(2). 第二范式(2NF)

​ 非主属性必须完全依赖于主码(完全依赖是指不能被其一部分决定).

(3). 第三范式(3NF)

​ 非主属不能依赖于其他非主属性.

(4). 巴斯范式(BCNF)

​ 所有属性(这里主要针对的是主属性)不能对主属性有传递依赖.(不能传递依赖,也就是主属性之间不能相互依赖)

4. InnoDB和MyISAM区别

(1). 区别

mysql中innodb和myisam对比及索引原理区别

InnoDB MyISAM
支持行锁 只支持表锁
事务 支持完整的事务 通过锁表来模拟事务
表的组织 索引组织表,共享表空间和多表空间存储 堆表,tableName.frm用于存储表的定义,tableName.MYD用于存放数据,tableName.MYI用于存放表索引
主键 如果没有显式的定义主键,会自动生成一个用户不可见的6字节的主键 允许没有主键的表存在
索引的保存 和数据一起保存,也就是聚集索引 单独存放,非聚集索引
辅助索引 存储主键 存储指向数据的指针
外键 支持 不支持
count 遍历整个表 有数据存储总数,读取该值即可
并发 分为读锁和写锁 读和写都是相互阻塞的

​ 因为辅助索引存储指针,多查询的表使用MyISAM效率会高很多.

​ InnoDB的表锁会让表的插入删除更新操作的效率高于MyISAM

(2). InnoDB存储引擎的4大特性

  • 插入缓冲
    • 对于不唯一的辅助索引,会先在缓冲中查找有没有该索引值,如果有直接插入到该位置(相同索引值在索引表中的位置一样),如果没有先添加到插入缓冲中,在按一定频率合并到缓冲池中,然后在持久化在磁盘中
  • 二次写
    • 为了防止将一个页写入磁盘时,中途发生宕机,磁盘上的数据已经脏了,这种情况是不能使用重做日志进行恢复的
    • 重做日志之能将数据库从一个状态更改为另一个状态,不能恢复这种随机性的数据错乱
    • 在内存中有一个doublewrite buffer大小为2MB,磁盘中也会有一片连续的128个页,2MB
    • 先将缓冲中的数据写入这2MB磁盘中,然后在写入原本应该写入的位置
    • 这样保证了磁盘中要么保存了原先的数据,要么保存了新的数据,不会出现中间状态
  • 自适应哈希索引
    • 如果某个二级索引被频繁访问(连续访问模式必须一样),成为热数据.这个二级索引会被自动生成到hash索引中去
    • 根据哈希算法计算索引值得出的值作为下标,在数组中存储指向聚集索引的页面地址的指针
  • 预读
    • InnoDB可能会再一次读取中顺便读取多量数据,减少磁盘访问的次数
    • 线性预读:根据当前发生顺序读取的次数判断是否在本次磁盘访问中将下一个区中的数据顺便读入到缓冲池
    • 随机预读:随机的将当前访问的页中的一些其他数据顺便读入缓冲池,已经弃用

5. 堆组织表,索引组织表和索引聚簇表

(1). 堆组织表

​ 物理存放顺序是随机的,索引中记录了数据所在位置的rowid,查找的时候先找索引,然后根据rowid找到行数据

​ 数据和索引是分离的.

(2). 索引组织表

​ 行数据和索引一起存放,找到索引就找到了行数据.

(3). 索引聚簇表

​ 一组表如果有共同的列,那么存储在相同的数据库块中.(可以理解为连接操作)

6. mysql优化

  • 开启查询缓存,优化查询
  • explain你的select查询,这可以帮你分析你的查询语句或是表结构的性能瓶颈。EXPLAIN 的查询结果还会告诉你你的索引主键被如何利用的,你的数据表是如何被搜索和排序的
  • 当只要一行数据时使用limit 1,MySQL数据库引擎会在找到一条数据后停止搜索,而不是继续往后查少下一条符合记录的数据
  • 为搜索字段建索引
  • 使用 ENUM 而不是 VARCHAR。如果你有一个字段,比如“性别”,“国家”,“民族”,“状态”或“部门”,你知道这些字段的取值是有限而且固定的,那么,你应该使用 ENUM 而不是VARCHAR
  • Prepared Statements
    • Prepared Statements很像存储过程,是一种运行在后台的SQL语句集合,我们可以从使用 prepared statements 获得很多好处,无论是性能问题还是安全问题。
    • Prepared Statements 可以检查一些你绑定好的变量,这样可以保护你的程序不会受到“SQL注入式”攻击
  • 垂直分表
  • 选择正确的存储引擎

7. B+树

​ InnoDB存储引擎中的索引是使用B+树来存储的.

(1). 特点

  • 非叶子节点中指针域(子节点)和索引域(索引值)的数量一致,B树的指针域要加一
  • 指针指向的子树中的所有数据都要小于此指针对应的索引域的值
  • 所有数据都存放在叶节点中,非叶子节点中保存的索引值只是其中数据的复制
  • 所有叶子节点上的数据都有两个指针,分别指向上一个和下一个节点(叶子节点双向链表连接)

(2). 较B树的优点

  • 由于所有数据都存放在叶子节点,树更加矮胖,相同树高能存放更多数据
  • 所有数据都在一层,查询效率更高
  • 对数据的扫描通过双向链表实现,不需要中序遍历整棵树

8. 添加索引

(1). alter方式

alter table 表名
add 索引类型 索引名
(索引列[,索引列2]);

(2). create方式

create 索引类型 索引名
on 表名 (索引列[,索引列2]);

9. MySQL 5.6对DDL的优化

​ 在MySQL 5.6之前MySQL本身不增加任何脚本的情况下,进行DDL操作(改变表或者库的结构)时都是建立一张包含新的结构的表,然后将数据导入新表.

​ MySQL 5.6开始支持Online DDL,其本质是在进行结构更改的时候,将此时的insert,update,delete这类操作日志写入缓存中,当DDL完成后,在重做到表上.

10. 事务

(1). 事务的特性

  • 原子性:事务中的操作要么全部完成,要么全部失败
  • 一致性:事务执行前后,数据库都要有一致性(事务中的操作要合法,否则回滚)
  • 隔离性:事物之间根据隔离级别有不同程度的不可见
  • 持久性:事务一旦提交,就永久的改变数据库中的数据

(2). 事务的隔离级别

事务隔离级别 脏读 不可重复读 幻读
读未提交(read-uncommitted)
读已提交(read-committed)
可重复读(repeatable-read,MySQL默认)
串行化(serializable)

(3). 事务中出现的并发问题

1). 脏读

​ 一个事务已经修改但还未提交的数据成为脏数据.脏读就是一个事务读到了另一个事务还未提交的事务,当另一个事务回滚时,这个事务当前得到的数据与数据库中不一致.

2). 不可重复读

​ 一个事务多次读取表的同时,另一个事务对数据进行了修改,并进行了提交.这时该事务没有进行修改数据但是读取的数据发生了改变.

3). 幻读

​ 一个事务多次读取表,另一个事务新增或者删除了数据.这时该数据读取到的数据数量发生了改变.

​ 幻读和不可重复读的区别在于侧重点不同,不可重复读侧重数据的更新,而幻读侧重于数据的增减.

​ 这就决定了,不可重复读可以通过行锁解决,而幻读需要一些别的措施(InnoDB中使用间隙锁完成).

11. MySQL主从复制原理

主服务:binlog(二进制日志,存储数据库的所有更改操作)线程会记录下所有改变数据库的语句,放入二进制日志中

从服务:io线程请求主服务的binlog,写入relay log(中继日志,只在这里使用)中

从服务:sql执行线程执行relay log中的语句

12. 表分区

(1). 水平分区

横向的将某张表截断成不同的分区(分离的是行,每一行的数据是完整的),有4中分区方式:

  • range:按照给定的取值区间进行分区
  • hash:按照给定的hash算法进行分区
  • key:使用mysql提供的方法进行hash
  • list:离散型的进行选择分区

(2). 垂直分区

​ 纵向的将某张表划分成不同的分区(将数据库的列进行分离),查询时需要连接查询.

13. 关于MVCC

​ MVCC就是多版本并发控制,在Mysql的InnoDB引擎中就是指在==已提交读==(READ COMMITTD)和==可重复读==(REPEATABLE READ)这两种隔离级别下的事务对于SELECT操作会访问版本链中的记录的过程。

(1). 版本链

​ 在聚簇索引(主键索引)中会有两个隐藏列.

​ 每次当有事务对某条数据进行修改的时候都会有一个trx_id来存储这个事务的id,然后将老版本地址写入undo page,并用roll_pointer指向这个版本.

​ 通过roll_pointer来找到上个版本,然后通过比对trx_id找到是否是当前事务要查询的版本,如果不是继续在上个版本中找到上上个版本.

(2). 快照读

​ 快照读是指每个事务都读取之前所有版本和当前版本的其中之一.

​ read view是一个列表来存储当前活跃的读写事务,也就是未提交事务,用这个列表来判断记录某个版本是否对当前版本可见.寻找到数据时,查找其当前版本对应的事务id,并判断是否能读取,如果不能,继续查找之前的版本,知道找到一个能读取的版本为止.

  1. 看不到read view创建时刻以后启动的事务
  2. 看不到read view创建时活跃的事务

​ 读已提交(不可重复读)在每次进行select时创建新的read view,而可重复读只在第一次select时创建read view.

14. 什么是索引,其优缺点,注意事项

(1). 什么是索引

​ 索引是数据库中的一种具有物理存储的数据结构.通常使用B树或者B+树实现.在这个数据结构上可以实现数据库维护的高级查找算法.

(2). 索引的作用

​ 协助快速查询

(3). 索引的优缺点

优点:

  • 提高数据的查找速度
  • 加快连接速度

缺点:

  • 创建和维护索引需要耗费时间
  • 索引需要占用物理空间

(4). 建立索引的注意事项

应该建立索引的情况:

  • 经常搜索的列
  • 需要连接的列,尤其是外键
  • 小范围查找的列
  • 经常需要排序的列
  • 经常使用where子句的列

不应该创建索引的列:

  • 数据大量重复
  • 数据量非常大(text等类型)
  • 对修改性能需求远大于检索性能(实时更新数据,反例是用于统计的数据)

15. 嵌套事务

​ 嵌套事务指的是子事务是父事务的一部分,进入子事务之前父事务会建立保存点.

​ 如果子事务回滚,父事务会回滚到之前设置的保存点.

​ 如果父事务回滚,子事务也会回滚.

​ 提交事务时,子事务先提交,父事务再提交.

16. SQL执行顺序

查询语句中select, from, where, group by, having, order by的执行顺序

(1). 总体上的执行顺序

​ from -> where -> group by -> having -> select -> order by

  1. from确定数据的来源
    1. 从后往前进行连接,所以小表放后面
  2. where确定数据的筛选条件
    1. orcale从后往前
    2. mysql从前往后
    3. 要点就是尽量先排除尽可能多的数据
  3. group by先进行分组
  4. having对分组进行筛选
    1. 很耗资源,尽量使用where代替
  5. select确定要展示的列
    1. 少用*,尽量使用字段名
  6. order by确定要展示的顺序
    1. 很耗资源
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容

  • 这篇文章主要涉及到MySQL的知识点: 索引(包括分类及优化方式,失效条件,底层结构) sql语法(join,un...
    一根薯条阅读 2,682评论 0 8
  • MySQL不权威总结 欢迎阅读 本文并非事无巨细的mysql学习资料,而是选择其中重要、困难、易错的部分进行系统地...
    liufxlucky365阅读 2,555评论 0 26
  • InnoDB体系架构 上图简单显示了InnoDB存储引擎的体系架构图中可见,InnoDB存储引擎有多个内存块,可以...
    Rick617阅读 4,003评论 0 6
  • 索引 数据库中的查询操作非常普遍,索引就是提升查找速度的一种手段 索引的类型 从数据结构角度分 1.B+索引:传统...
    一凡呀阅读 2,839评论 0 8
  • 坚持是一种幸福 177/300书名:《蔡康永的情商课》作者: 蔡康永阅读感悟:※ 我们的心灵,不是通道,任由各种信...
    牛奶_4e00阅读 126评论 0 0