MySQL面试总结

MySQL面试总结面试

# MySQL的存储引擎算法

`MyISAM`(默认表类型):非事务的存储引擎,基于传统的`ISAM`(有索引的顺序访问方法)类型,是存储记录和文件的标准方法,不是事务安全,不支持外键,适用于频繁的查询。表锁,不会出现死锁,适合小数据和小并发。sql

- 为何不会出死锁?(没有事务就不会继续持有锁)数据库

答:由于`MyISAM`再查询的时候,会同时锁定这个`sql`里面全部用到的表(获取锁的顺序是一致的),不局限与一张表,再写锁又重叠时,就得等待。缓存

**注意:【`MySQL5.5`以前默认的是`MyISAM`引擎了,5.5以后的版本默认都是`innodb`做为存储引擎】**安全

`innodb`:支持事务安全的存储引擎,适用于插入和更新,支持外键,行锁,事务。适合大数据,大并发。特别是针对多个并发和`QPS`较高的状况。服务器

- `QPS:`就是每秒查询率,`QPS`是对一个特定服务器再规定时间内能处理多少流量的衡量标准。网络

- `TPS:`就是每秒传输处理的事务个数。并发

- `innodb`的行锁模式:共享锁,排他锁,意向共享锁(表锁),意向排他锁(表锁),间隙锁。(注意:若是`sql`语句没有使用索引,`innodb`不能肯定操做的行时,使用意向锁(表锁))。负载均衡

- 死锁问题

- 什么是死锁?

死锁就是当俩个事务都须要获取对方持有的排他锁才能完成事务的时候,就致使了循环锁等待,常见的死锁类型。

- 解决办法

1. 数据库参数
2. 尽可能约定程序读取表的顺序
3. 在处理一个表时,尽可能对处理的顺序排序
4. 调整事务隔离级别(避免俩个事务同时操做一行不存在的数据,容易发生死锁)

存储引擎还有:

- `MERGE:`将多个相似的`MyISAM`表分组为一个表,能够处理非事务性表,默认状况下包括这些表。
- `MEMORY:`提供内存中的表,之前称为堆。它在RAM中处理全部数据,以便比在磁盘上存储数据更快地访问。用于快速查找引用和其余相同的数据。
- `EXAMPLE:`可使用此引擎建立表,但不能存储或获取数据。这样作的目的是教开发人员如何编写新的存储引擎。
- `ARCHIVE:`用于存储大量数据,不支持索引。
- `CSV:`在文本文件中以逗号分隔值格式存储数据。
- `BLACKHOLE:`受要存储的数据,但始终返回空。
- `FEDERATED:`将数据存储在远程数据库中。

# 数据表的类型


`MyISAM`,`InnoDB`,`MEMORY`,`HEAP`,`BOB`,`ARCHIVE`,`CSV`等

- `MYISAM:`成熟稳定,易于管理,快速读取。表级锁。
- `Innodb:`数据行锁。占用空间大,不支持全文索引。

# `MySQL`做为发布系统的储存,一天五万条以上的增量,怎么优化?

1. 设计良好的数据库结构,容许部分数据冗余,尽可能避免join查询,提升效率。
2. 选择合适的表字段类型和存储引擎,适当添加索引。
3. `MySQL`库主从读写分离。
4. 找规律分表,减小表单中的数据量,提升查询速度。
5. 添加缓存机制。可使用`Redis`缓存。
6. 不常常改动的页面,生成静态页面。
7. 写高效率的`sql`语句。如:`SELECT * FROM TABEL 改成 SELECT field_1, field_2, field_3 FROM TABLE`。

为何要避免使用join查询?

答:减小消耗。

# 对于大流量网站,如何解决各页面统计访问量问题?

1. 确认服务器是否能支撑当前访问量。
2. 优化数据库访问。
3. 禁止外部访问,如图片盗链。
4. 控制文件下载。
5. 使用不一样主机进行分流。
6. 使用浏览统计软件,了解访问量,有针对性的进行优化。

# 如何进行`SQL`优化?


1. 选择正确的存储引擎。
每一个引擎都有利有弊,好比`MyISAM`,适用于大量查询,对大量写操做并非很好,`update`一个字段都会把整个表锁起来,而I`nnodb`,对一些小的应用,它比`MyISAM`慢,但它支持行锁,再写操做的时候,很优秀,它还支持更多的高级应用。
2. 优化字段的数据类型
一个原则,越小的越快,若是一个表只有几列,那咱们就不用用`INT`来作主键,可使用`MEDIUMINT`,`SMALLINT`或是更小的`TINYINT`会更经济一些,若是不须要记录时间,使用`DATE`要比`DATETIME`好的多,也要留够足够的空间进行扩展。
3. 为搜索字段添加索引
索引不必定只添加给主键或惟一的字段,若是在表中有某个字段常常用来作搜索,那就为它创建索引,若是要搜索的字段是大的文本字段,那应该为它创建全文索引。
4. 避免使用`select *`由于从数据库读出的数据越多,那么查询就会越慢。若是数据库服务和WEB服务器在不一样的机器上的话,还会增长网络传输的负载。即便要查询表的全部字段,也尽可能不要用`*`通配符。
5. 使用`ENUM`而不是`VARCHAR`
`ENUM`类型是很是快和紧凑的,它保存的是`TINYINT`,但外表上显示的是字符串,作一些选项列表很好,好比:性别,民族,部门,状态之类的字段,取值有限并且固定。
6. 尽量使用`NOT NULL`
`NULL`其实也须要额外空间的,在进行比较的时候,程序也会变得复杂,并非并不能够用`NULL`,在现实的复杂状况下,依然会有些状况须要使用`NULL`值。
7. 固定长度的表会更快
若是表中的全部字段都是固定长度的,那整个表会被认为是`“static”`或“`fixed-lenght”`。例如表中没有`VARCHAR`,`TEXT`,`BLOB`,只要表中其中一个字段是这些类型,那么这个表就不是“固定长度静态表”了,这样的话`MySQL`引擎会用另外一种方法来处理。
固定长度的表也容易被缓存和重建,惟一的反作用就是,固定长度的字段会浪费一些空间,由于固定长度的字段不管用不用,都会分配那么多的空间。

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


1. 数据库优化,喝的事务隔离级别,`SQL`语句,索引优化。
2. 使用缓存,尽可能减小数据库`IO`操做。
3. 分布式数据库,分布式缓存。
4. 服务器负载均衡。

# 什么状况下设置了索引却没法使用


1. 以%开头`LIKE`,模糊匹配。
2. `OR`语句先后没有同时使用索引。
3. 数据类型出现隐式转化,如`varchar`不加单引号可能会转换为`int`型。

# `SQL`注入的主要特色


1. 变种极多,攻击简单,危害极大。
2. 未经受权操做数据库的数据。
3. 恶意篡改网页。
4. 网页挂木马。
5. 私自添加系统帐号或是数据库使用者帐号。

# 优化数据库的方法

1. 选取最适合的字段属性,尽量减小定义字段宽度,尽可能把字段设成`NOT NULL`。
2. 使用`exists`替代`in`,用`not exists`替代`not in`。
3. 使用链接`(JOIN)`来替代子查询。
4. 适用联合`(NUION)`来代替手动建立的临时表。
5. 事务处理。
6. 锁定表,优化事务处理。
7. 适当用外键,优化锁定表。
8. 创建索引。
9. 优化查询语句。

# 数据库中的事务是什么

事务做为一个单元的一组有序的数据操做,若是组中的全部操做都完成,则认定事务成功,即便只有一个失败,事务也不成功。若是全部操做完成,事务则进行提交,其修改将做用于全部其余数据库进程。若是一个操做失败,则事务将回滚,该事务全部的操做的影响都会取消。

- `ACID`四大特性
- 原子性:不可分割,事务要么所有被执行,要么所有不执行。
- 一致性:事务的执行使得数据库从一种正确的状态转换成另外一种正确的状态。
- 隔离性:在事务正确提交前,不容许把该事务对数据的任何改变提供给任何其余事务。
- 持久性:事务正确提交后,将结果永久保存到数据库中,即便在事务提交后,有了其余故障,事务处理结果也会获得保存。

# 索引的目的是什么?

1. 快速访问数据表中特定信息,提升检索速度。
2. 建立惟一性索引,保证每一行数据的惟一性。
3. 加速表和表之间的链接。
4. 使用分组和排序子句进行数据检索时,可显著的减小分组和排序的时间。

# 索引对数据库系统的负面影响是什么?
建立索引和维护索引须要消耗时间,这个时间会随着数据量的增长而增长,索引须要占用物理空间。当对表进行增删改查的时候索引也须要动态维护,这样就下降了数据的维护速度。
# 为数据表创建索引的原则

1. 频繁使用的,用以缩小查询范围的字段上创建索引。
2. 频繁使用的,须要排序的字段上创建索引。

# 什么状况下不宜创建索引

对于查询中涉及不多的列,或是重复值较多的列,不宜创建索引。

一些特殊的数据类型,不宜就创建索引。如`text`文本字段。

# 左链接和右链接的区别


左链接:

- 左链接会读取左表中的所有数据,即便右表中没有对应的数据(若是俩个表有相同的数据,只会显示一个),用`NULL`填充。

右链接:

- 右链接会读取右表的所有数据,即便左表中没有对应的数据(若是俩个表有相同的数据,只会显示一个),用`NULL`填充。

# 什么是锁?


数据库是一个多用户使用的共享资源,当多个用户并发的存取数据时,在数据库中就会产生多个事务同时存取同一个数据的状况,若对并发操做不加控制可能就会读取和储存不正确的数据,破坏数据库的一致性。

# 什么是存储过程,用什么来调用?


存储过程就是一个预编译的`SQL`语句,优势是容许模块化设计,只须要建立一次,就能够在该程序中屡次调用,若是某次操做须要执行屡次`SQL`,使用存储过程比单纯的`SQL`语句要快。可使用一个命令对象进行调用。

# 索引的做用,和它的优缺点


索引就是一种特殊的查询表,数据库引擎能够用它加速对数据的检索,索引是惟一的,在建立时能够以指定单个列或是多个列。缺点是它减慢了数据录入的速度,同时也增长了数据库的尺寸大小。

# 主键,外键,索引的区别?

主键:

- 惟一标识一条记录,不可重复,不可为`NULL`。
- 用来保证数据的完整性。
- 只能有一个。

外键:

- 表的外键是另外一个表的主键,外键能够重复,能够为空。
- 用来和其余表创建联系。
- 一个表能够有多个外键。

索引:

- 该字段没有重复值,能够有一个是空值。
- 提升查询效率排序速度。
- 一个表能够有多个惟一索引。

# 对`SQL`语句的优化方法
1. 避免在索引列上使用计算。
2. 避免在索引列上使用`IS NULL`和`IS NOT NULL`。
3. 对查询进行优化,尽可能避免全表扫描,首先因该考虑在`where`和`order by`涉及的列上创建索引。
4. 避免在`where`子句对字段进行null值判断,这件致使引擎放弃使用索引而进行全表扫描。
5. 避免在`where`子句中对字段进行表达式操做,也会致使引擎放弃使用索引而进行全表扫描。

# `SQL`语句中“相关子查询”和“非相关子查询”有什么区别
若是你想加载一篇你写过的.md文件,在上方工具栏能够选择导入功能进行对应扩展名的文件导入,
继续你的创做。

子查询:嵌套在其余查询中的查询。

非相关子查询:

- 非相关子查询是独立于外部查询的子查询,子查询总共执行一次,执行完毕后将值传递给外部的查询。

相关子查询:

- 相关子查询的执行依赖于外部的查询数据,外部查询执行一次,子查询就会执行一次。

【因此非相关子查询比相关子查询效率高】

# `char`和`varchar`的区别

- char`类型的数据列里,每一个值都占`M`个字节,若是长度小于`M`,就会在它的右边用空格字符进行补足(在检索操做中填补出来的空格符将会被去掉)。
- `vachar`类型的数据列里,每一个值只占用恰好够用的字节再加上一个用来记录长度的字节,因此总长度为`L+1`字节。

# `SQL`问题

- 脏读

- 在一个事务处理过程当中读取到了另外一个未提交事务中的数据。

【例子】

A在一个转帐事务中,转了100给B,此时B读到了这个转帐的数据,而后作了一些操做(给A发货,或是其余),但是这个时候A的事务并无提交,若是A回滚了事务,那这就是脏读。

- 不可重复读

- 对数据库中的某个数据,一个事务范围内屡次查询却返回了不一样的数据值,是因为在查询间隔,被另外一个事务修改并提交了。

【例子】

事务A在读取某一数据,而事务B立马修改了这个数据而且提交了事务到数据库,事务A再次读取就获得了不一样的结果。发生了不重复读。

- 幻读

- 事务非独立执行时发生的一种现象。

【例子】

事务A对一个表中全部的行的某个数据项作了从“1”修改成“2”的操做,这时事务B又对这个表中插入了一行数据项,这个数据的数值仍是“1”而且提给了数据库,若是事务A查看刚刚修改的数据,会发现还有一数据没有修改,而这行数据时事务B中添加的,就像产生的幻觉同样。发生了幻读。

# `MySQL`事务隔离级别

1. `read uncmmited`:读到未提交数据
- 最低级别,没法保证任状况
2. `read commited`:读已提交
- 可避免脏读
3. `repeatable read`:可重复读
- 可避免脏读、不可重复读
4. `serializable`:串行事务
- 可避免脏读、不可重复读、幻读

**【`MySQL`默认事务隔离级别为`Repeatable Read`(可重复读)】**

# `MySQL`临时表

什么是临时表:临时表是`MySQL`用于存储中间结果集的表,临时表只在当前链接可看,当链接关闭时会自动删除表并释放全部空间。

为何会产生临时表:通常是由于复杂的`SQL`致使临时表被大量建立

- 进行`union`查询时
- 用到`temptable`算法或者是`union`查询中的视图
- `ORDER BY`和`GROUP BY`的子句不同时
- 表链接中,`ORDER BY`的列不是驱动表中的
- `DISTINCT`查询而且加上`ORDER BY`时
- `SQL`中用到`SLQ_SMALL_RESULT`选项时
- `RROM`中的子查询

临时表分为俩种:

- 内存临时表
- 采用的是`memory`存储引擎
- 磁盘临时表
- 菜用的是`myisam`存储引擎

# 什么是视图,游标是什么?

视图:视图是一种虚拟表,具备和物理表相同的功能。能够对视图表进行增删改查操做,视图一般是有一个表或者多个表的子集。对视图的修改不会影响基本表。

- 【使得咱们获取数据更容易,相比多表查询】

游标:是对查询出来的结果集做为一个单元来有效的处理。游标能够定在该单元的特定行,从结果集的当前行检索一行或多行。能够对结果集当前行进行修改。

- 【通常不会使用,但须要逐条处理数据的时候,游标显得十分重要】

相关文章
相关标签/搜索