MySql 面试21题

MySQL 涉及到数据存储、锁、磁盘寻道、分页等操作系统概念,而且互联网对 MySQL 的注重程度是不言而喻的。

目录

一 非关系型和关系型比较

二 MySQL 事务四大特性

2.1 隔离级别

2.2 什么是死锁?怎么解决

三 MySQL 常见储存引擎

3.1 MyISAM 存储引擎的特点

3.2 InnoDB 存储引擎的特点

3.3 MyISAM 和 InnoDB 存储引擎的对比

四 ACID靠什么保证  

五 MySQL 基础架构

5.1 Server层

5.2 存储引擎层

5.3 MySQL 的执行过程

5.3.1 连接器

5.3.2 查询缓存

5.3.3 分析器

5.3.4 优化器

5.3.5 执行器

5.4 SQL语句类型

5.5 SQL的生命周期

六 SQL 的执行顺序

6.1 FROM 连接

6.2 ON 过滤

6.3 JOIN 连接

6.4 WHERE 过滤

6.5 GROUP BY 分组

6.6 HAVING 过滤

6.7 SELECT 查询

6.8 DISTINCT 去重

6.9 ORDER BY

七 什么是临时表,何时删除临时表

八 MySQL 常见索引类型

九 varchar 和 char 的区别和使用场景

十 什么是 内外连接、交叉连接、笛卡尔积

外连接

内连接

笛卡尔积(Cartesian product):

交叉连接

全连接

十一 谈谈 SQL 优化的经验

十二  数据库三大范式

十三 mysql有关权限的表有哪些

十四 分库分表的目的

十五 视图有哪些特点?

十六 主键使用自增ID还是UUID?

十七 MySQL数据库cpu飙升到100%的话怎么处理?

十八 MySQL主从复制解决了哪些问题?

十九 什么是MySQL的GTID?

二十 MySQL常用的备份工具有哪些?

二十一 MySQL备份计划如何制定


一 非关系型和关系型比较

非关系型数据库(感觉翻译不是很准确)称为 NoSQL,也就是 Not Only SQL,不仅仅是 SQL。

非关系型数据库不需要写一些复杂的 SQL 语句,其内部存储方式是以 key-value 的形式存在。

可以把它想象成电话本的形式,每个人名(key)对应电话(value)。

常见的非关系型数据库主要有 Hbase、Redis、MongoDB 等。

非关系型数据库不需要经过 SQL 的重重解析,所以性能很高。

非关系型数据库的可扩展性比较强,数据之间没有耦合性,遇见需要新加字段的需求,就直接增加一个 key-value 键值对即可。

关系型数据库以表格的形式存在,以行和列的形式存取数据,关系型数据库这一系列的行和列被称为表,无数张表组成了数据库,常见的关系型数据库有 Oracle、DB2、Microsoft SQL ServerMySQL等。

关系型数据库能够支持复杂的 SQL 查询,能够体现出数据之间、表之间的关联关系;

关系型数据库也支持事务,便于提交或者回滚。

它们之间的劣势都是基于对方的优势来满足的

二 MySQL 事务四大特性

这里涉及到一个概念,什么是 MySQL 中的事务?

事务是一组操作,组成这组操作的各个单元,要不全都成功要不全都失败,这个特性就是事务。事务是最小的执行单位,不允许分割。

在 MySQL 中,事务是在引擎层实现的,只有使用 innodb引擎的数据库或表才支持事务。

四大特性:原子性、一致性、隔离性、持久性

  • 原子性(Atomicity): 原子性指的就是 MySQL 中的包含事务的操作要么全部成功、要么全部失败回滚,因此事务的操作如果成功就必须要全部应用到数据库,如果操作失败则不能对数据库有任何影响。原子性确保动作要么全部完成,要么完全不起作用。

  • 一致性(Consistency):一致性指的是一个事务在执行前后其状态一致。比如 A 和 B 加起来的钱一共是 1000 元,那么不管 A 和 B 之间如何转账,转多少次,事务结束后两个用户的钱加起来还得是 1000,这就是事务的一致性。

  • 持久性(Durability): 持久性指的是一旦事务提交,那么发生的改变就是永久性的,即使数据库遇到特殊情况比如故障的时候也不会产生干扰。

  • 隔离性(Isolation):隔离性需要重点说一下,当多个事务同时进行时,就有可能出现脏读(dirty read)、不可重复读(non-repeatable read)、幻读(phantom read) 的情况,为了解决这些并发问题,提出了隔离性的概念。(并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的)

并发访问问题-由隔离性引起

脏读(Drity Read):事务 A 读取了事务 B 更新后的数据,但是事务 B 没有提交,然后事务 B 执行回滚操作(RollBack),那么事务 A 读到的数据就是脏数据。(A 事务读取到B事务尚未提交的数据)

不可重复读(Non-repeatable read):事务 A 中进行多次读取操作,事务 B 在事务 A 多次读取的过程中执行更新操作并提交,提交后事务 A 读到的数据内容不一致。(一个事物中两次读取的数据内容不一致)

幻读/虚读(Phantom Read):事务 A 将数据库中所有学生的成绩由 A -> B,此时事务 B 手动插入了一条成绩为 A 的记录,在事务 A 更改完毕后,再次读取,发现还有一条记录没有修改,那么这种情况就叫做出现了幻读。(一个事务中两次读取的数据的数量不一致)

2.1 隔离级别

SQL的隔离级别有四种,它们分别是读未提交(read uncommitted)、读已提交(read committed)、可重复读(repetable read) 和 串行化(serializable)。

  • 读未提交:读未提交指的是一个事务在提交之前,它所做的修改就能够被其他事务所看到。

  • 读已提交:读已提交指的是一个事务在提交之后,它所做的变更才能够让其他事务看到。

  • 可重复读:可重复读指的是一个事务在执行的过程中,看到的数据是和启动时看到的数据是一致的。未提交的变更对其他事务不可见。

  • 串行化:顾名思义是对于同一行记录,写会加写锁,读会加读锁。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。

这四个隔离级别可以解决脏读、不可重复读、幻象读这三类问题。总结如下

 其中隔离级别由低到高是:读未提交 < 读已提交 < 可重复读 < 串行化

隔离级别越高,越能够保证数据的完整性和一致性,但是对并发的性能影响越大。

大多数数据库的默认级别是读已提交(Read committed),比如 Sql Server、Oracle ,但是 MySQL 的默认隔离级别是 可重复读(repeatable-read)。

2.2 什么是死锁?怎么解决

死锁是指两个或多个事务在同一资源上相互占用,并请求锁定对方的资源,从而导致恶性循环的现象。

常见的解决死锁的方法

  1. 如果不同程序会并发存取多个表, 尽量约定以相同的顺序访问表,可以大大降低死锁机会。

  2. 在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率;

  3. 对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁产生的概率;

如果业务处理不好可以用分布式事务锁或者使用乐观锁

三 MySQL 常见储存引擎

# 查看所有存储引擎 

SHOW ENGINES;

 

 InnoDB 是 MySQL 默认支持的存储引擎,支持事务、行级锁定和外键。

3.1 MyISAM 存储引擎的特点

在 5.1 版本之前,MyISAM 是 MySQL 的默认存储引擎,MyISAM 并发性比较差,使用的场景比较少,主要特点是

  • 不支持事务操作,ACID 的特性也就不存在了,这一设计是为了性能和效率考虑的。

  • 不支持外键操作,如果强行增加外键,MySQL 不会报错,只不过外键不起作用。

  • MyISAM 默认的锁粒度是表级锁,所以并发性能比较差,加锁比较快,锁冲突比较少,不太容易发生死锁的情况。

  • MyISAM 会在磁盘上存储三个文件,文件名和表名相同,扩展名分别是 .frm(存储表定义)、.MYD(MYData,存储数据)、MYI(MyIndex,存储索引)。这里需要特别注意的是 MyISAM 只缓存索引文件,并不缓存数据文件。

  • MyISAM 支持的索引类型有 全局索引(Full-Text)、B-Tree 索引、R-Tree 索引

    • Full-Text 索引:它的出现是为了解决针对文本的模糊查询效率较低的问题。

    • B-Tree 索引:所有的索引节点都按照平衡树的数据结构来存储,所有的索引数据节点都在叶节点

    • R-Tree索引:它的存储方式和 B-Tree 索引有一些区别,主要设计用于存储空间和多维数据的字段做索引,目前的 MySQL 版本仅支持 geometry 类型的字段作索引,相对于 BTREE,RTREE 的优势在于范围查找。

  • 数据库所在主机如果宕机,MyISAM 的数据文件容易损坏,而且难以恢复。

  • 增删改查性能方面:SELECT 性能较高,适用于查询较多的情况

3.2 InnoDB 存储引擎的特点

自从 MySQL 5.1 之后,默认的存储引擎变成了 InnoDB 存储引擎,相对于 MyISAM,InnoDB 存储引擎有了较大的改变,它的主要特点是

  • 支持事务操作,具有事务 ACID 隔离特性,默认的隔离级别是可重复读(repetable-read)、通过MVCC(并发版本控制)来实现的。能够解决脏读和不可重复读的问题。

  • InnoDB 支持外键操作。

  • InnoDB 默认的锁粒度行级锁,并发性能比较好,会发生死锁的情况。

  • 和 MyISAM 一样的是,InnoDB 存储引擎也有 .frm文件存储表结构 定义,但是不同的是,InnoDB 的表数据与索引数据是存储在一起的,都位于 B+ 数的叶子节点上,而 MyISAM 的表数据和索引数据是分开的。

  • InnoDB 有安全的日志文件,这个日志文件用于恢复因数据库崩溃或其他情况导致的数据丢失问题,保证数据的一致性。

  • InnoDB 和 MyISAM 支持的索引类型相同,但具体实现因为文件结构的不同有很大差异。

  • 增删改查性能方面,如果执行大量的增删改操作,推荐使用 InnoDB 存储引擎,它在删除操作时是对行删除,不会重建表。

3.3 MyISAM 和 InnoDB 存储引擎的对比

  • 锁粒度方面:由于锁粒度不同,InnoDB 比 MyISAM 支持更高的并发;InnoDB 的锁粒度为行锁、MyISAM 的锁粒度为表锁、行锁需要对每一行进行加锁,所以锁的开销更大,但是能解决脏读和不可重复读的问题,相对来说也更容易发生死锁

  • 可恢复性上:由于 InnoDB 是有事务日志的,所以在产生由于数据库崩溃等条件后,可以根据日志文件进行恢复。而 MyISAM 则没有事务日志。

  • 查询性能上:MyISAM 要优于 InnoDB,因为 InnoDB 在查询过程中,是需要维护数据缓存,而且查询过程是先定位到行所在的数据块,然后在从数据块中定位到要查找的行;而 MyISAM 可以直接定位到数据所在的内存地址,可以直接找到数据。

  • 表结构文件上:MyISAM 的表结构文件包括:.frm(表结构定义),.MYI(索引),.MYD(数据);而 InnoDB 的表数据文件为:.ibd和.frm(表结构定义);

四 ACID靠什么保证  

  • A原子性由undo log日志保证,它记录了需要回滚的日志信息,事务回滚时撤销已经执行成功的sql

  • C一致性由其他三大特性保证、程序代码要保证业务上的一致性

  • I隔离性由MVCC(并发版本控制)来保证

  • D持久性由内存+redolog来保证,mysql修改数据同时在内存和redo log记录这次操作,宕机的时候可以从redo log恢复

五 MySQL 基础架构

这道题应该从 MySQL 架构来理解,我们可以把 MySQL 拆解成几个零件,如下图所示

大致上来说,MySQL 可以分为 Server层和 存储引擎层。

5.1 Server层

Server 层包括连接器、查询缓存、分析器、优化器、执行器,包括大多数 MySQL 中的核心功能,所有跨存储引擎的功能也在这一层实现,包括 存储过程、触发器、视图等

5.2 存储引擎层

存储引擎层包括 MySQL 常见的存储引擎,包括 MyISAM、InnoDB 和 Memory 等,最常用的是 InnoDB,也是现在 MySQL 的默认存储引擎。

存储引擎也可以在创建表的时候手动指定,比如下面

CREATE TABLE t (i INT) ENGINE = <Storage Engine>;

5.3 MySQL 的执行过程

创建连接 -> 查询缓存 -> 分析sql -> 优化sql -> 执行sql

5.3.1 连接器

首先需要在 MySQL 客户端登陆才能使用,所以需要一个连接器来连接用户和 MySQL 数据库,我们一般是使用

mysql -u 用户名 -p 密码

来进行 MySQL 登陆,和服务端建立连接。在完成 TCP 握手 后,连接器会根据你输入的用户名和密码验证你的登录身份。

如果用户名或者密码错误,MySQL 就会提示 Access denied for user,来结束执行。

如果登录成功后,MySQL 会根据权限表中的记录来判定你的权限。

5.3.2 查询缓存

连接完成后,你就可以执行 SQL 语句了,这行逻辑就会来到第二步:查询缓存。

MySQL 在得到一个执行请求后,会首先去 查询缓存 中查找,是否执行过这条 SQL 语句,之前执行过的语句以及结果会以 key-value 对的形式,被直接放在内存中。

key 是查询语句,value 是查询的结果。如果通过 key 能够查找到这条 SQL 语句,就直接返回 SQL 的执行结果。如果语句不在查询缓存中,就会继续后面的执行阶段。

执行完成后,执行结果就会被放入查询缓存中。可以看到,如果查询命中缓存,MySQL 不需要执行后面的复杂操作,就可以直接返回结果,效率会很高。

但是查询缓存不建议使用

为什么呢?因为只要在 MySQL 中对某一张表执行了更新操作,那么所有的查询缓存就会失效,对于更新频繁的数据库来说,查询缓存的命中率很低。

5.3.3 分析器

如果没有命中查询,就开始执行真正的 SQL 语句。

  • 首先,MySQL 会根据你写的 SQL 语句进行解析,分析器会先做 词法分析,你写的 SQL 就是由多个字符串和空格组成的一条 SQL 语句,MySQL 需要识别出里面的字符串是什么,代表什么。

  • 然后进行 语法分析,根据词法分析的结果, 语法分析器会根据语法规则,判断你输入的这个 SQL 语句是否满足 MySQL 语法。如果 SQL 语句不正确,就会提示 You have an error in your SQL syntax

5.3.4 优化器

经过分析器的词法分析和语法分析后,你这条 SQL 就合法了,MySQL 就知道你要做什么了。但是在执行前,还需要进行优化器的处理,优化器会判断你使用了哪种索引,使用了何种连接,优化器的作用就是确定效率最高的执行方案。

5.3.5 执行器

MySQL 通过分析器知道了你的 SQL 语句是否合法,你想要做什么操作,通过优化器知道了该怎么做效率最高,然后就进入了执行阶段,开始执行这条 SQL 语句在执行阶段,MySQL 首先会判断你有没有执行这条语句的权限,没有权限的话,就会返回没有权限的错误。如果有权限,就打开表继续执行。打开表的时候,执行器就会根据表的引擎定义,去使用这个引擎提供的接口。对于有索引的表,执行的逻辑也差不多。至此,MySQL 对于一条语句的执行过程也就完成了。

5.4 SQL语句类型

数据定义语言DDL(Data Ddefinition Language)CREATE,DROP,ALTER 主要为以上操作 即对逻辑结构等有操作的,其中包括表结构,视图和索引。

数据查询语言DQL(Data Query Language)SELECT 这个较为好理解 即查询操作,以select关键字。各种简单查询,连接查询等 都属于DQL。

数据操纵语言DML(Data Manipulation Language)INSERT,UPDATE,DELETE 主要为以上操作即对数据进行操作的,对应上面所说的查询操作 DQL与DML共同构建了多数初级程序员常用的增删改查操作。而查询是较为特殊的一种 被划分到DQL中。

数据控制功能DCL(Data Control Language)GRANT,REVOKE,COMMIT,ROLLBACK 主要为以上操作 即对数据库安全性完整性等有操作的,可以简单的理解为权限控制等。

5.5 SQL的生命周期

  1. 应用服务器与数据库服务器建立一个连接

  2. 数据库进程拿到请求sql

  3. 解析并生成执行计划,执行

  4. 读取数据到内存并进行逻辑处理

  5. 通过步骤一的连接,发送结果到客户端

  6. 关掉连接,释放资源

六 SQL 的执行顺序

我们在编写一个查询语句的时候

SELECT DISTINCT < select_list > FROM < left_table > < join_type > JOIN < right_table > ON < join_condition > WHERE < where_condition > GROUP BY < group_by_list > HAVING < having_condition > ORDER BY < order_by_condition > LIMIT < limit_number >

它的执行顺序你知道吗?这道题就给你一个回答。

6.1 FROM 连接

首先,对 SELECT 语句执行查询时,对FROM 关键字两边的表执行连接,会形成笛卡尔积,这时候会产生一个虚表VT1(virtual table)

解释一下什么是虚表

在 MySQL 中,有三种类型的表

一种是永久表,永久表就是创建以后用来长期保存数据的表

一种是临时表,临时表也有两类,

          一种是和永久表一样,只保存临时数据,但是能够长久存在的;

          还有一种是临时创建的,SQL 语句执行完成就会删除。

一种是虚表,虚表其实就是视图,数据可能会来自多张表的执行结果。

6.2 ON 过滤

然后对 FROM 连接的结果进行 ON 筛选,创建 VT2,把符合记录的条件存在 VT2 中。

6.3 JOIN 连接

第三步,如果是 OUTER JOIN(left join、right join) ,那么这一步就将添加外部行,

如果是 left join 就把 ON 过滤条件的左表添加进来,

如果是 right join ,就把右表添加进来,从而生成新的虚拟表 VT3。

6.4 WHERE 过滤

第四步,执行 WHERE 过滤器,对上一步生产的虚拟表引用 WHERE 筛选,生成虚拟表 VT4。

WHERE 和 ON 的区别

  • 如果有外部列,ON 针对过滤的是关联表,主表(保留表)会返回所有的列;

  • 如果没有添加外部列,两者的效果是一样的;

应用

  • 对主表的过滤应该使用 WHERE;

  • 对于关联表,先条件查询后连接则用 ON,先连接后条件查询则用 WHERE;

6.5 GROUP BY 分组

第五步,根据 group by 字句中的列,会对 VT4 中的记录进行分组操作,产生虚拟机表 VT5。

如果应用了group by,那么后面的所有步骤都只能得到的 VT5 的列或者是聚合函数(count、sum、avg等)。

6.6 HAVING 过滤

紧跟着 GROUP BY 字句后面的是 HAVING,使用 HAVING 过滤,会把符合条件的放在 VT6

6.7 SELECT 查询

第七步才会执行 SELECT 语句,将 VT6 中的结果按照 SELECT 进行刷选,生成 VT7

6.8 DISTINCT 去重

在第八步中,会对 TV7 生成的记录进行去重操作,生成 VT8。

事实上如果应用了 group by 子句那么 distinct 是多余的,

原因同样在于分组的时候是将列中唯一的值分成一组,同时只为每一组返回一行记录,那么所以的记录都将是不相同的。

6.9 ORDER BY

应用 order by 子句。按照 order_by_condition 排序 VT8,此时返回的一个游标,而不是虚拟表。

sql 是基于集合的理论的,集合不会预先对他的行排序,它只是成员的逻辑集合,成员的顺序是无关紧要的。

SQL 语句执行的过程如下

七 什么是临时表,何时删除临时表

MySQL 在执行 SQL 语句的过程中,通常会临时创建一些存储中间结果集的表,临时表只对当前连接可见,在连接关闭时,临时表会被删除并释放所有表空间。

临时表分为两种:一种是内存临时表,一种是磁盘临时表,什么区别呢?

内存临时表使用的是 MEMORY 存储引擎,而临时表采用的是 MyISAM 存储引擎。

MEMORY 存储引擎:

memory 是 MySQL 中一类特殊的存储引擎,它使用存储在内容中的内容来创建表,而且数据全部放在内存中。

每个基于 MEMORY 存储引擎的表实际对应一个磁盘文件。

该文件的文件名与表名相同,类型为 frm 类型。

而其数据文件,都是存储在内存中,这样有利于数据的快速处理,提高整个表的效率。

MEMORY 用到的很少,因为它是把数据存到内存中,如果内存出现异常就会影响数据。

如果重启或者关机,所有数据都会消失。

因此,基于 MEMORY 的表的生命周期很短,一般是一次性的。

MySQL 会在下面这几种情况产生临时表

  • 使用 UNION 查询:UNION 有两种,一种是UNION ,一种是 UNION ALL ,它们都用于联合查询;

    • 使用 UNION 会去掉两个表中的重复数据,相当于对结果集做了一下去重(distinct)。

    • 使用 UNION ALL,则不会排重,返回所有的行。使用 UNION 查询会产生临时表。

  • 使用 TEMPTABLE 算法或者是 UNION 查询中的视图。TEMPTABLE 算法是一种创建临时表的算法,它是将结果放置到临时表中,意味这要 MySQL 要先创建好一个临时表,然后将结果放到临时表中去,然后再使用这个临时表进行相应的查询。

  • ORDER BY 和 GROUP BY 的子句不一样时也会产生临时表。

  • DISTINCT 查询并且加上 ORDER BY 时;

  • SQL 用到 SQL_SMALL_RESULT 选项时;如果查询结果比较小的时候,可以加上 SQL_SMALL_RESULT 来优化,产生临时表

  • FROM 中的子查询;

  • EXPLAIN 查看执行计划结果的 Extra 列中,如果使用 Using Temporary 就表示会用到临时表。

八 MySQL 常见索引类型

索引是存储在一张表中特定列上的数据结构,索引是在列上创建的。

并且,索引是一种数据结构。在 MySQL 中,主要有下面这几种索引

  • 全局索引(FULLTEXT):全局索引,目前只有 MyISAM 引擎支持全局索引,它的出现是为了解决针对文本的模糊查询效率较低的问题。

  • 哈希索引(HASH):哈希索引是 MySQL 中用到的唯一 key-value 键值对的数据结构,很适合作为索引。HASH 索引具有一次定位的好处,不需要像树那样逐个节点查找,但是这种查找适合应用于查找单个键的情况,对于范围查找,HASH 索引的性能就会很低。

  • B-Tree 索引:B 就是 Balance 的意思,BTree 是一种平衡树,它有很多变种,最常见的就是 B+ Tree,它被 MySQL 广泛使用。

  • R-Tree 索引:R-Tree 在 MySQL 很少使用,仅支持 geometry 数据类型,支持该类型的存储引擎只有MyISAM、BDb、InnoDb、NDb、Archive几种,相对于 B-Tree 来说,R-Tree 的优势在于范围查找。

九 varchar 和 char 的区别和使用场景

MySQL 中没有 varchar2 数据类型,所以直接比较的是 varchar 和 char 的区别

char :表示的是定长的字符串,当你输入小于指定的数目,比如你指定的数目是 char(6),当你输入小于 6 个字符的时候,char 会在你最后一个字符后面补空值。

当你输入超过指定允许最大长度后,MySQL 会报错

varchar:varchar 指的是长度为 n 个字节的可变长度,并且是非Unicode的字符数据。n 值是介于 1 - 8000 之间的数值。存储大小为实际大小。

Unicode 是一种字符编码方案,它为每种语言中的每个字符都设定了统一唯一的二进制编码,以实现跨语言、跨平台进行文本转换、处理的要求

使用 char 存储定长的数据非常方便、char 检索效率高,无论你存储的数据是否到了 10 个字节,都要去占用 10 字节的空间使用 varchar 可以存储变长的数据,但存储效率没有 char 高。

十 什么是 内外连接、交叉连接、笛卡尔积

连接的方式主要有三种:外连接、内链接、交叉连接

外连接

外连接(OUTER JOIN):外连接分为三种,

左外连接(LEFT OUTER JOIN 或 LEFT JOIN)、又称为左连接,这种连接方式会显示左表不符合条件的数据行,右边不符合条件的数据行直接显示 NULL

右外连接(RIGHT OUTER JOIN 或 RIGHT JOIN) 、也被称为右连接,他与左连接相对,这种连接方式会显示右表不      符合条件的数据行,左表不符合条件的数据行直接显示 NULL

全外连接(FULL OUTER JOIN 或 FULL JOIN)

MySQL 暂不支持全外连接

内连接

内连接(INNER JOIN):结合两个表中相同的字段,返回关联字段相符的记录。

笛卡尔积(Cartesian product):

现在我们有两个集合 A = {0,1} , B = {2,3,4}那么,集合 A * B 得到的结果就是

A * B = {(0,2)、(1,2)、(0,3)、(1,3)、(0,4)、(1,4)};

B * A = {(2,0)、{2,1}、{3,0}、{3,1}、{4,0}、(4,1)};

上面 A * B 和 B * A 的结果就可以称为两个集合相乘的 笛卡尔积

我们可以得出结论,A 集合和 B 集合相乘,包含了集合 A 中的元素和集合 B 中元素之和,也就是 A 元素的个数 * B 元素的个数

交叉连接

交叉连接的原文是Cross join ,就是笛卡尔积在 SQL 中的实现,SQL中使用关键字CROSS JOIN来表示交叉连接,在交叉连接中,随便增加一个表的字段,都会对结果造成很大的影响。

SELECT * 
FROM t_Class a 
CROSS JOIN t_Student b 
WHERE a.classid=b.classid

或者不用 CROSS JOIN,直接用 FROM 也能表示交叉连接的效果

SELECT * 
FROM t_Class a ,t_Student b 
WHERE a.classid=b.classid

如果表中字段比较多,不适宜用交叉连接,交叉连接的效率比较差。

全连接

全连接也就是 full join,MySQL 中不支持全连接,但是可以使用其他连接查询来模拟全连接,可以使用 UNION 和 UNION ALL 进行模拟。

# 例如
(select colum1,colum2...columN from tableA ) 
union 
(select colum1,colum2...columN from tableB )
# 或
(select colum1,colum2...columN from tableA ) 
union all 
(select colum1,colum2...columN from tableB );

使用 UNION 和 UNION ALL 的注意事项

通过 union 连接的 SQL 分别单独取出的列数必须相同

使用 union 时,多个相等的行将会被合并

由于合并比较耗时,一般不直接使用 union 进行合并,而是通常采用 union all 进行合并

十一 谈谈 SQL 优化的经验

  • 查询语句无论是使用哪种判断条件 等于、小于、大于, WHERE 左侧的条件查询字段不要使用函数或者表达式

  • 使用 EXPLAIN 命令优化你的 SELECT 查询,对于复杂、效率低的 sql 语句,我们通常是使用 explain sql 来分析这条 sql 语句,这样方便我们分析,进行优化。

  • 当你的 SELECT 查询语句只需要使用一条记录时,要使用 LIMIT 1

  • 不要直接使用 SELECT *,而应该使用具体需要查询的表字段,因为使用 EXPLAIN 进行分析时,SELECT * 使用的是全表扫描,也就是 type = all。

  • 为每一张表设置一个 ID 属性

  • 避免在 WHERE 字句中对字段进行 NULL 判断

  • 避免在 WHERE 中使用 != 或 <> 操作符

  • 使用 BETWEEN AND 替代 IN

  • 为搜索字段创建索引

  • 选择正确的存储引擎,InnoDB 、MyISAM 、MEMORY 等

  • 使用 LIKE %abc% 不会走索引,而使用 LIKE abc% 会走索引

  • 对于枚举类型的字段(即有固定罗列值的字段),建议使用ENUM而不是VARCHAR,如性别、星期、类型、类别等

  • 拆分大的 DELETE 或 INSERT 语句

  • 选择合适的字段类型,选择标准是 尽可能小、尽可能定长、尽可能使用整数。

  • 字段设计尽可能使用 NOT NULL

  • 进行水平切割或者垂直分割

水平分割:通过建立结构相同的几张表分别存储数据

垂直分割:将经常一起使用的字段放在一个单独的表中,分割后的表记录之间是一一对应关系。

十二  数据库三大范式

第一范式:每个列都不可以再拆分。

第二范式:在第一范式的基础上,非主键列完全依赖于主键,而不能是依赖于主键的一部分。

第三范式:在第二范式的基础上,非主键列只依赖于主键,不依赖于其他非主键。

在设计数据库结构的时候,要尽量遵守三范式,如果不遵守,必须有足够的理由。比如性能。事实上我们经常会为了性能而妥协数据库的设计。

十三 mysql有关权限的表有哪些

MySQL服务器通过权限表来控制用户对数据库的访问,权限表存放在mysql数据库里,由mysql_install_db脚本初始化。

这些权限表分别user,db,table_priv,columns_priv和host。

  • user 权限表:记录允许连接到服务器的用户帐号信息,里面的权限是全局级的。

  • db 权限表:记录各个帐号在各个数据库上的操作权限。

  • table_priv 权限表:记录数据表级的操作权限。

  • columns_priv 权限表:记录数据列级的操作权限。

  • host 权限表:配合db权限表对给定主机上数据库级操作权限作更细致的控制。这个权限表不受GRANT和REVOKE语句的影响。

十四 分库分表的目的

分库分表就是为了解决由于数据量过大而导致数据库性能降低的问题

将原来独立的数据库拆分成若干数据库组成,将数据大表拆分成若干数据表组成,

使得单一数据库、单一数据表的数据量变小,从而达到提升数据库性能的目的。

分库分表常用的中间件如下:

十五 视图有哪些特点?

视图的特点如下: 视图的列可以来自不同的表,是表的抽象和在逻辑意义上建立的新关系。

视图是由基本表(实表)产生的表(虚表)。视图的建立和删除不影响基本表。

对视图内容的更新(添加,删除和修改)直接影响基本表。

当视图来自多个基本表时,不允许添加和删除数据。

视图的操作包括创建视图,查看视图,删除视图和修改视图。

十六 主键使用自增ID还是UUID?

推荐使用自增ID,不要使用UUID。

因为在InnoDB存储引擎中,主键索引是作为聚簇索引存在的,也就是说, 主键索引的B+树叶子节点上存储了主键索引以及全部的数据(按照顺序),

如果主键索引是自增ID,那么只需要不断向后排列即可,

如果是UUID, 由于到来的ID与原来的大小不确定,会造成非常多的数据插入,数据移动,然后导致产生很多的内存碎片,进而造成插入性能的下降。

总之,在数据量大一些的情况下,用自增主键性能会好一些。

关于主键是聚簇索引,如果没有主键,InnoDB会选择一个唯一键来作为聚簇索引,如果没有唯一键,会生成一个隐式的主键。

十七 MySQL数据库cpu飙升到100%的话怎么处理?

当 cpu 飙升到 100%时,先用操作系统命令 top 命令观察是不是 mysqld 占用导致的。

如果不是,找出占用高的进程,并进行相关处理。

如果是 mysqld 造成的, show processlist,看看里面跑的 session 情况,是不是有消耗资源的 sql 在运行。找出消耗高的 sql,看看执行计划是否准确,index 是否缺失,或者实在是数据量太大造成。

一般来说,肯定要 kill 掉这些线程(同时观察 cpu 使用率是否下降), 等进行相应的调整(比如说加索引、改 sql、改内存参数)之后,再重新跑这些 SQL。

也有可能是每个 sql 消耗资源并不多,但是突然之间,有大量的 session 连进来导致 cpu 飙升, 这种情况就需要跟应用一起来分析为何连接数会激增, 再做出相应的调整,比如说限制连接数等。

十八 MySQL主从复制解决了哪些问题?

主从复制的作用是:

主数据库出现问题,可以切换到从数据库。可以进行数据库层面的读写分离。可以在从数据库上进行日常备份。

数据分布:随意开始或停止复制,并在不同地理位置分布数据备份

负载均衡:降低单个服务器的压力

高可用和故障切换:帮助应用程序避免单点失败

升级测试:可以用更高版本的MySQL作为从库

十九 什么是MySQL的GTID?

GTID(Global Transaction ID,全局事务ID)是全局事务标识符, 是一个已提交事务的编号,并且是一个全局唯一的编号。

GTID是从MySQL 5.6版本开始在主从复制方面推出的重量级特性。

GTID实际上是由UUID+TID组成的。其中UUID是一个MySQL实例的唯一标识。

GTID代表了该实例上已经提交的事务数量,并且随着事务提交单调递增。

GTID有如下几点作用:

  1. 根据GTID可以知道事务最初是在哪个实例上提交的。

  2. GTID的存在方便了Replication的Failover。因为不用像传统模式复制那样去找master_log_file和master_log_pos。

  3. 基于GTID搭建主从复制更加简单, 确保每个事务只会被执行一次。

二十 MySQL常用的备份工具有哪些?

常用备份工具mysql复制

逻辑备份(mysqldump,mydumper)

物理备份(copy,xtrabackup)

备份工具差异对比:

  1. mysql复制相对于其他的备份来说,得到的备份数据比较实时。

  2. 逻辑备份:分表比较容易。mysqldump备份数据时是将所有sql语句整合在同一个文件中;mydumper备份数据时是将SQL语句按照表拆分成单个的sql文件, 每个sql文件对应一个完整的表。

  3. 物理备份:拷贝即可用,速度快。

copy:直接拷贝文件到数据目录下,可能引起表损坏或者数据不一致。

xtrabackup对于innodb表是不需要锁表的,对于myisam表仍然需要锁表。

二十一 MySQL备份计划如何制定

视库的大小来定,一般来说 100G 内的库,可以考虑使用 mysqldump 来做, 因为 mysqldump更加轻巧灵活,备份时间选在业务低峰期, 可以每天进行都进行全量备份(mysqldump 备份出来的文件比较小,压缩之后更小)。

100G 以上的库,可以考虑用 xtranbackup 来做,备份速度明显要比 mysqldump 要快。

一般是选择一周一个全备,其余每天进行增量备份,备份时间为业务低峰期。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

封神尘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值