程序员面试备战篇:18个经典MySQL面试专题解析,干货分享

程序员面试备战篇:18个经典MySQL面试专题解析,干货分享

1.数据库三范式是什么?

  1. 第一范式(1NF):字段具备原子性,不可再分。(全部关系型数据库系统都知足第一范式数据库表中的字段都是单一属性的,不可再分)
  2. 第二范式(2NF)是在第一范式(1NF)的基础上创建起来的,即知足第二范式(2NF)必须先知足第一范式(1NF)。要求数据库表中的每一个实例或行必须能够被唯一地区分。一般须要为表加上一个列,以存储各个实例的唯一标识。这个唯一属性列被称为主关键字或主键。
  3. 知足第三范式(3NF)必须先知足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。>因此第三范式具备以下特征:>>1. 每一列只有一个值 >>2. 每一行都能区分。>>3. 每个表都不包含其余表已经包含的非主关键字信息。

2.有哪些数据库优化方面的经验?

  1. 用 PreparedStatement, 通常来讲比 Statement 性能高:一个 sql发给服务器去执行,涉及步骤:语法检查、语义分析, 编译,缓存。
  2. 有外键约束会影响插入和删除性能,若是程序可以保证数据的完整性,那在设计数据库时就去掉外键。
  3. 表中容许适当冗余,譬如,主题帖的回复数量和最后回复时间等4. UNION ALL 要比UNION 快不少,因此,若是能够确认合并的两个结果集中不包含重复数据且不须要排序时的话,那么就使用 UNIONALL。>>UNION 和 UNION ALL 关键字都是将两个结果集合并为一个,但这二者从使用和效率上来讲都有所不一样。>1. 对重复结果的处理:UNION 在进行表连接后会筛选掉重复的记录,Union All 不会去除重复记录。>2. 对排序的处理:Union 将会按照字段的顺序进行排序;UNION ALL 只是简单的将两个结果合并后就返回。

3.请简述经常使用的索引有哪些种类?

  1. 普通索引: 即针对数据库表建立索引
  2. 惟一索引: 与普通索引相似,不一样的就是:MySQL 数据库索引列的值必须惟一,但容许有空值
  3. 主键索引: 它是一种特殊的惟一索引,不容许有空值。通常是在建表的时候同时建立主键索引
  4. 组合索引: 为了进一步榨取 MySQL 的效率,就要考虑创建组合索引。即将数据库表中的多个字段联合起来做为一个组合索引。

4.以及在 mysql 数据库中索引的工做机制是什么?

  • 数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。索引的实现一般使用 B 树及其变种 B+树

5.MySQL 的基础操做命令:

  1. MySQL 是否处于运行状态:Debian 上运行命令 service mysqlstatus,在 RedHat上运行命令 service mysqld status
  2. 开启或中止 MySQL 服务 :运行命令 service mysqld start 开启服务;运行命令service mysqld stop 中止服务
  3. Shell 登入 MySQL: 运行命令 mysql -u root -p
  4. 列出全部数据库:运行命令 show databases;
  5. 切换到某个数据库并在上面工做:运行命令 use databasename; 进入名为databasename 的数据库
  6. 列出某个数据库内全部表: show tables;
  7. 获取表内全部 Field 对象的名称和类型 :describe table_name;

6.mysql 的复制原理以及流程。

Mysql 内建的复制功能是构建大型,高性能应用程序的基础。将 Mysql 的数据分布到多个系统上去,这种分布的机制,是经过将 Mysql 的某一台主机的数据复制到其它主机(slaves)上,并从新执行一遍来实现的。* 复制过程当中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。php

主服务器将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环。这些日志能够记录发送到从服务器的更新。当一个从服务器链接主服务器时,它通知主服务器在日志中读取的最后一次成功更新的位置。mysql

从服务器接收从那时起发生的任何更新,而后封锁并等待主服务器通知新的更新。过程以下程序员

1. 主服务器把更新记录到二进制日志文件中。面试

2. 从服务器把主服务器的二进制日志拷贝到本身的中继日志(replay log)中。3. 从服务器重作中继日志中的时间,把更新应用到本身的数据库上。sql

7.mysql 支持的复制类型?

  1. 基于语句的复制:在主服务器上执行的 SQL 语句,在从服务器上执行一样的语句。MySQL 默认采用基于语句的复制,效率比较高。一旦发现无法精确复制时,会自动选着基于行的复制。
  2. 基于行的复制:把改变的内容复制过去,而不是把命令在从服务器上执行一遍. 从mysql5.0 开始支持
  3. 混合类型的复制: 默认采用基于语句的复制,一旦发现基于语句的没法精确的复制时,就会采用基于行的复制。

8.mysql 中 myisam 与 innodb 的区别?

  1. 事务支持 > MyISAM:强调的是性能,每次查询具备原子性,其执行速度比 InnoDB 类型更快,可是不提供事务支持。> InnoDB:提供事务支持事务,外部键等高级数据库功能。具备事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。
  2. InnoDB 支持行级锁,而 MyISAM 支持表级锁. >> 用户在操做myisam 表时,select,update,delete,insert 语句都会给表自动加锁,若是加锁之后的表知足insert 并发的状况下,能够在表的尾部插入新的数据。
  3. InnoDB 支持 MVCC, 而 MyISAM 不支持
  4. InnoDB 支持外键,而 MyISAM 不支持
  5. 表主键 > MyISAM:容许没有任何索引和主键的表存在,索引都是保存行的地址。> InnoDB:若是没有设定主键或者非空惟一索引,就会自动生成一个6 字节的主键(用户不可见),数据是主索引的一部分,附加索引保存的是主索引的值。
  6. InnoDB 不支持全文索引,而 MyISAM 支持。
  7. 可移植性、备份及恢复 > MyISAM:数据是以文件的形式存储,因此在跨平台的数据转移中会很方便。在备份和恢复时可单独针对某个表进行操做。> InnoDB:免费的方案能够是拷贝数据文件、备份binlog,或者用 mysqldump,在数据量达到几十 G 的时候就相对痛苦了
  8. 存储结构 > MyISAM:每一个 MyISAM 在磁盘上存储成三个文件。第一个文件的名字以表的名字开始,扩展名指出文件类型。.frm 文件存储表定义。数据文件的扩展名为.MYD (MYData)。索引文件的扩展名是.MYI (MYIndex)。> InnoDB:全部的表都保存在同一个数据文件中(也多是多个文件,或者是独立的表空间文件),InnoDB表的大小只受限于操做系统文件的大小,通常为 2GB。

9.mysql 中 varchar 与 char 的区别以及 varchar(50)中的 50 表明的涵义?

  1. varchar 与 char 的区别: char 是一种固定长度的类型,varchar 则是一种可变长度的类型.
  2. varchar(50)中 50 的涵义 : 最多存放 50 个字节
  3. int(20)中 20 的涵义: int(M)中的 M indicates the maximumdisplay width (最大显示宽度)for integer types. The maximumlegal display width is 255.

10.MySQL 中 InnoDB 支持的四种事务隔离级别名称,以及逐级之间的区别?

  1. Read Uncommitted(读取未提交内容) >> 在该隔离级别,全部事务均可以看到其余未提交事务的执行结果。本隔离级别不多用于实际应用,由于它的性能也不比其余级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。
  2. Read Committed(读取提交内容) >> 这是大多数数据库系统的默认隔离级别(但不是 MySQL 默认的)。它知足了隔离的简单定义:一个事务只能看见已经提交事务所作的改变。这种隔离级别也支持所谓的不可重复读(Nonrepeatable Read),由于同一事务的其余实例在该实例处理其间可能会有新的 commit,因此同一 select 可能返回不一样结果。
  3. Repeatable Read(可重读) >> 这是 MySQL 的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到一样的数据行。不过理论上,这会致使另外一个棘手的问题:幻读(PhantomRead)。简单的说,幻读指当用户读取某一范围的数据行时,另外一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。InnoDB 和 Falcon 存储引擎经过多版本并发控制(MVCC,Multiversion Concurrency Control 间隙锁)机制解决了该问题。注:其实多版本只是解决不可重复读问题,而加上间隙锁(也就是它这里所谓的并发控制)才解决了幻读问题。
  4. Serializable(可串行化) >> 这是最高的隔离级别,它经过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每一个读的数据行上加上共享锁。在这个级别,可能致使大量的超时现象和锁竞争。

让眼睛休息休息,再继续吧!

11.表中有大字段 X(例如:text 类型),且字段 X 不会常常更新,以读为为主,将该字段拆成子表好处是什么?

若是字段里面有大字段(text,blob)类型的,并且这些字段的访问并很少,这时候放在一块儿就变成缺点了。MYSQL 数据库的记录存储是按行存储的,数据块大小又是固定的(16K),每条记录越小,相同的块存储的记录就越多。此时应该把大字段拆走,这样应付大部分小字段的查询时,就能提升效率。当须要查询大字段时,此时的关联查询是不可避免的,但也是值得的。拆分开后,对字段的 UPDAE 就要 UPDATE 多个表了数据库

12.MySQL 中 InnoDB 引擎的行锁是经过加在什么上完成(或称实现)的?

InnoDB 行锁是经过给索引上的索引项加锁来实现的,这一点 MySQL 与Oracle 不一样,后者是经过在数据块中对相应数据行加锁来实现的。InnoDB 这种行锁实现特色意味着:只有经过索引条件检索数据,InnoDB 才使用行级锁,不然,InnoDB 将使用表锁!缓存

13.MySQL 中控制内存分配的全局参数,有哪些?

  1. Keybuffersize:> keybuffersize 指定索引缓冲区的大小,它决定索引处理的速度,尤为是索引读的速度。经过检查状态值Keyreadrequests 和 Keyreads,能够知道 keybuffersize 设置是否合理。比例 keyreads /keyreadrequests 应该尽量的低,至少是1:100,1:1000 更好(上述状态值可使用 SHOW STATUS LIKE‘keyread%'得到)。> keybuffersize 只对 MyISAM 表起做用。即便你不使用MyISAM 表,可是内部的临时磁盘表是 MyISAM 表,也要使用该值。可使用检查状态值 createdtmpdisktables 得知详情。对于 1G 内存的机器,若是不使用 MyISAM表,推荐值是 16M(8-64M) > keybuffersize 设置注意事项 >>>1. 单个keybuffer 的大小不能超过 4G,若是设置超过 4G,就有可能遇到下面 3 个bug: >>>>> http://bugs.mysql.com/bug.php?id=29446 <br/> >>>>> http://bugs.mysql.com/bug.php?id=29419 <br/> >>>>> http://bugs.mysql.com/bug.php?id=5731 <br/> >>>2. 建议 keybuffer 设置为物理内存的 1/4(针对 MyISAM 引 擎),甚至是物理内存的 30%~40%,若是keybuffersize 设置太大,系统就会频繁的换页,下降系统性能。由于 MySQL 使用操做系统的缓存来缓存数据,因此咱们得为系统留够足够的内存;在不少状况下数据要比索引大得多。>>>3. 若是机器性能优越,能够设置多个keybuffer,分别让不一样的key*buffer 来缓存专门的索引
  2. innodbbufferpool_size > 表示缓冲池字节大小,InnoDB 缓存表和索引数据的内存区域。mysql 默认的值是 128M。最大值与你的CPU 体系结构有关,在 32 位操做系统,最大值是 4294967295(2^32-1) ,在 64 位操做系统,最大值为18446744073709551615 (2^64-1)。> 在 32 位操做系统中,CPU 和操做系统实用的最大大小低于设置的最大值。若是设定的缓冲池的大小大于 1G,设置innodbbufferpoolinstances 的值大于 1. > 数据读写在内存中很是快, innodbbufferpoolsize 减小了对磁盘的读写。当数据提交或知足检查点条件后才一次性将内存数据刷新到磁盘中。然而内存还有操做系统或数据库其余进程使用, 通常设置bufferpool 大小为总内存的 3/4 至 4/5。若设置不当, 内存使用可能浪费或者使用过多。对于繁忙的服务器, buffer pool 将划分为多个实例以提升系统并发性, 减小线程间读写缓存的争用。buffer pool 的大小首先受 innodbbuffer*pool_instances 影响,固然影响较小。
  3. querycachesize > 当 mysql 接收到一条 select 类型的 query时,mysql 会对这条query 进行 hash 计算而获得一个 hash 值,而后经过该 hash 值到 query cache 中去匹配,若是没有匹配中,则将这个hash 值存放在一个 hash 链表中,同时将 query 的结果集存放进cache 中,存放 hash 值的链表的每个 hash 节点存放了相应query结果集在 cache 中的地址,以及该 query 所涉及到的一些 table 的相关信息;若是经过 hash 值匹配到了同样的 query,则直接将 cache 中相应的 query 结果集返回给客户端。若是 mysql 任何一个表中的任何一条数据发生了变化,便会通知query cache 须要与该 table 相关的query 的 cache 所有失效,并释放占用的内存地址。> query cache优缺点 >> 1. query 语句的 hash 计算和 hash 查找带来的资源消耗。mysql 会对每条接收到的 select 类型的 query 进行 hash 计算而后查找该query 的 cache 是否存在,虽然 hash 计算和查找的效率已经足够高了,一条query 所带来的消耗能够忽略,但一旦涉及到高并发,有成千上万条 query 时,hash计算和查找所带来的开销就的重视了;>> 2. query cache 的失效问题。若是表变动比较频繁,则会形成 query cache 的失效率很是高。表变动不只仅指表中的数据发生变化,还包括结构或者索引的任何变化;>> 3. 对于不一样 sql 但同一结果集的 query都会被缓存,这样便会形成内存资源的过渡消耗。sql 的字符大小写、空格或者注释的不一样,缓存都是认为是不一样的 sql(由于他们的 hash 值会不一样);>> 4. 相关参数设置不合理会形成大量内存碎片,相关的参数设置会稍后介绍。
  4. readbuffersize >是 MySQL 读入缓冲区大小。对表进行顺序扫描的请求将分配一个读入缓冲区,MySQL 会为它分配一段内存缓冲区。readbuffersize 变量控制这一缓冲区的大小。若是对表的顺序扫描请求很是频繁,而且你认为频繁扫描进行得太慢,能够经过增长该变量值以及内存缓冲区大小提升其性能。

14.若一张表中只有一个字段 VARCHAR(N)类型,utf8 编码,则 N 最大值为多少(精确到数量级便可)?

因为 utf8 的每一个字符最多占用 3 个字节。而 MySQL 定义行的长度不能超过65535,所以 N 的最大值计算方法为:(65535-1-2)/3。减去 1 的缘由是实际存储从第二个字节开始,减去 2 的缘由是由于要在列表长度存储实际的字符长度,除以 3 是由于utf8 限制:每一个字符最多占用 3 个字节。安全

*15. [SELECT ] 和[SELECT 所有字段]的 2 种写法有何优缺点?**

  1. 前者要解析数据字典,后者不须要
  2. 结果输出顺序,前者与建表列顺序相同,后者按指定字段顺序。
  3. 表字段更名,前者不须要修改,后者须要改
  4. 后者能够创建索引进行优化,前者没法优化
  5. 后者的可读性比前者要高

16.HAVNG 子句 和 WHERE 的异同点?

  1. 语法上:where 用表中列名,having 用 select 结果别名
  2. 影响结果范围:where 从表读出数据的行数,having 返回客户端的行数
  3. 索引:where 可使用索引,having 不能使用索引,只能在临时结果集操做
  4. where 后面不能使用汇集函数,having 是专门使用汇集函数的。

17.MySQL 当记录不存在时 insert,当记录存在时 update,语句怎么写?

INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEYUPDATE c=c+1;服务器

18.MySQL 的 insert 和 update 的 select 语句语法

SQL insert into student (stuid,stuname,deptid) select 10,'xzm',3from student where stuid > 8;
update student a inner join student b on b.stuID=10 seta.
stuname=concat(b.stuname, b.stuID) where a.stuID=10 ;

您的关注转发是我继续前行的动力,感谢您的阅读,赞扬。微信

程序员面试备战篇:18个经典MySQL面试专题解析,干货分享
欢迎关注微信公众号:慕容千语的架构笔记。欢迎关注一块儿进步。

相关文章
相关标签/搜索