【数据库01】数据库大厂高频面试题和答案

数据库基础知识

为什么要使用数据库

数据保存在内存:

优点:存取速度快

缺点:数据不能永久保存

 

数据保存在文件:

优点:数据永久保存

缺点:1)速度比内存操作慢,频繁的IO操作。2)查询数据不方便

 

数据保存在数据库:

1)数据永久保存

2)使用SQL语句,查询方便效率高。

3)管理数据方便

 

什么是SQL?

结构化查询语言(Structured Query Language)简称SQL,是一种数据库查询语言。

 

作用:用于存取数据、查询、更新和管理关系数据库系统。

 

什么是MySQL?

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。在Java企业级开发中非常常用,因为 MySQL 是开源免费的,并且方便扩展。

 

数据库三大范式是什么?

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

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

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

 

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

 

mysql有关权限的表都有哪几个

MySQL服务器通过权限表来控制用户对数据库的访问,权限表存放在mysql数据库里,由mysql_install_db脚本初始化。这些权限表分别user,db,table_priv,columns_priv和host。下面分别介绍一下这些表的结构和内容:

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

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

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

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

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

 

MySQL的binlog有有几种录入格式?分别有什么区别?

有三种格式,statement,row和mixed。

 

1、statement模式下,每一条会修改数据的sql都会记录在binlog中。不需要记录每一行的变化,减少了binlog日志量,节约了IO,提高性能。由于sql的执行是有上下文的,因此在保存的时候需要保存相关的信息,同时还有一些使用了函数之类的语句无法被记录复制。

 

2、row级别下,不记录sql语句上下文相关信息,仅保存哪条记录被修改。记录单元为每一行的改动,基本是可以全部记下来但是由于很多操作,会导致大量行的改动(比如alter table),因此这种模式的文件保存的信息太多,日志量太大。

 

3、mixed,一种折中的方案,普通操作使用statement记录,当无法使用statement的时候使用row。

 

此外,新版的MySQL中对row级别也做了一些优化,当表结构发生变化的时候,会记录语句而不是逐行记录。

 

数据类型

mysql有哪些数据类型

1、整数类型,包括TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT,分别表示1字节、2字节、3字节、4字节、8字节整数。任何整数类型都可以加上UNSIGNED属性,表示数据是无符号的,即非负整数。

 

长度:整数类型可以被指定长度,例如:INT(11)表示长度为11的INT类型。长度在大多数场景是没有意义的,它不会限制值的合法范围,只会影响显示字符的个数,而且需要和UNSIGNED ZEROFILL属性配合使用才有意义。

 

例子,假定类型设定为INT(5),属性为UNSIGNED ZEROFILL,如果用户插入的数据为12的话,那么数据库实际存储数据为00012。

 

2、实数类型,包括FLOAT、DOUBLE、DECIMAL。

DECIMAL可以用于存储比BIGINT还大的整型,能存储精确的小数。

 

而FLOAT和DOUBLE是有取值范围的,并支持使用标准的浮点进行近似计算。

 

计算时FLOAT和DOUBLE相比DECIMAL效率更高一些,DECIMAL你可以理解成是用字符串进行处理。

 

3、字符串类型,包括VARCHAR、CHAR、TEXT、BLOB

VARCHAR用于存储可变长字符串,它比定长类型更节省空间。

 

VARCHAR使用额外1或2个字节存储字符串长度。列长度小于255字节时,使用1字节表示,否则使用2字节表示。

 

VARCHAR存储的内容超出设置的长度时,内容会被截断。

 

CHAR是定长的,根据定义的字符串长度分配足够的空间。

 

CHAR会根据需要使用空格进行填充方便比较。

 

CHAR适合存储很短的字符串,或者所有值都接近同一个长度。

 

CHAR存储的内容超出设置的长度时,内容同样会被截断。

 

使用策略:

对于经常变更的数据来说,CHAR比VARCHAR更好,因为CHAR不容易产生碎片。

 

对于非常短的列,CHAR比VARCHAR在存储空间上更有效率。

 

使用时要注意只分配需要的空间,更长的列排序时会消耗更多内存。

 

尽量避免使用TEXT/BLOB类型,查询时会使用临时表,导致严重的性能开销。

 

4、枚举类型(ENUM),把不重复的数据存储为一个预定义的集合。

有时可以使用ENUM代替常用的字符串类型。

 

ENUM存储非常紧凑,会把列表值压缩到一个或两个字节。

 

ENUM在内部存储时,其实存的是整数。

 

尽量避免使用数字作为ENUM枚举的常量,因为容易混乱。

 

排序是按照内部存储的整数

 

5、日期和时间类型,尽量使用timestamp,空间效率高于datetime,

用整数保存时间戳通常不方便处理。

如果需要存储微妙,可以使用bigint存储。

 

看到这里,这道真题是不是就比较容易回答了。

 

引擎

MySQL存储引擎MyISAM与InnoDB区别

存储引擎Storage engine:MySQL中的数据、索引以及其他对象是如何存储的,是一套文件系统的实现。

 

常用的存储引擎有以下:

 

Innodb引擎:Innodb引擎提供了对数据库ACID事务的支持。并且还提供了行级锁和外键的约束。它的设计的目标就是处理大数据容量的数据库系统。

 

MyIASM引擎(原本Mysql的默认引擎):不提供事务的支持,也不支持行级锁和外键。

 

MEMORY引擎:所有的数据都在内存中,数据的处理速度快,但是安全性不高。

 

MyISAM索引与InnoDB索引的区别?

1、InnoDB索引是聚簇索引,MyISAM索引是非聚簇索引。

2、InnoDB的主键索引的叶子节点存储着行数据,因此主键索引非常高效。

3、MyISAM索引的叶子节点存储的是行数据地址,需要再寻址一次才能得到数据。

4、InnoDB非主键索引的叶子节点存储的是主键和其他带索引的列数据,因此查询时做到覆盖索引会非常高效。

 

InnoDB引擎的4大特性

1、插入缓冲(insert buffer)

2、二次写(double write)

3、自适应哈希索引(ahi)

4、预读(read ahead)

 

存储引擎选择

如果没有特别的需求,使用默认的Innodb即可。

MyISAM:以读写插入为主的应用程序,比如博客系统、新闻门户网站。

Innodb:更新(删除)操作频率也高,或者要保证数据的完整性;并发量高,支持事务和外键。比如OA自动化办公系统。

 

索引

什么是索引?

索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。

 

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

 

更通俗的说,索引就相当于目录。为了方便查找书中的内容,通过对内容建立索引形成目录。索引是一个文件,它是要占据物理空间的。

 

索引有哪些优缺点?

索引的优点:

可以大大加快数据的检索速度,这也是创建索引的最主要的原因。

通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。

 

索引的缺点:

时间方面:创建索引和维护索引要耗费时间,具体地,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,会降低增/改/删的执行效率;

空间方面:索引需要占物理空间。

 

索引使用场景(重点)

where

上图中,根据id查询记录,因为id字段仅建立了主键索引,因此此SQL执行可选的索引只有主键索引,如果有多个,最终会选一个较优的作为检索的依据。

 

order by

 

当我们使用order by将查询结果按照某个字段排序时,如果该字段没有建立索引,那么执行计划会将查询出的所有数据使用外部排序(将数据从硬盘分批读取到内存使用内部排序,最后合并排序结果),这个操作是很影响性能的,因为需要将查询涉及到的所有数据从磁盘中读到内存(如果单条数据过大或者数据量过多都会降低效率),更无论读到内存之后的排序了。

 

但是如果我们对该字段建立索引alter table 表名 add index(字段名),那么由于索引本身是有序的,因此直接按照索引的顺序和映射关系逐条取出数据即可。而且如果分页的,那么只用取出索引表某个范围内的索引对应的数据,而不用像上述那取出所有数据进行排序再返回某个范围内的数据。(从磁盘取数据是最影响性能的)

 

join

 

对join语句匹配关系(on)涉及的字段建立索引能够提高效率

 

索引覆盖

 

如果要查询的字段都建立过索引,那么引擎会直接在索引表中查询而不会访问原始数据(否则只要有一个字段没有建立索引就会做全表扫描),这叫索引覆盖。因此我们需要尽可能的在select后只写必要的查询字段,以增加索引覆盖的几率。

 

这里值得注意的是不要想着为每个字段建立索引,因为优先使用索引的优势就在于其体积小。

 

索引有哪几种类型?

主键索引: 数据列不允许重复,不允许为NULL,一个表只能有一个主键。

 

唯一索引: 数据列不允许重复,允许为NULL值,一个表允许多个列创建唯一索引。

 

1、可以通过 ALTER TABLE table_name ADD UNIQUE (column);创建唯一索引

 

2、可以通过 ALTER TABLE table_name ADD UNIQUE (column1,column2);创建唯一组合索引

 

普通索引: 基本的索引类型,没有唯一性的限制,允许为NULL值。

 

1、可以通过ALTER TABLE table_name ADD INDEX index_name (column);创建普通索引

 

2、可以通过ALTER TABLE table_name ADD INDEX index_name(column1, column2, column3);创建组合索引

 

全文索引:是目前搜索引擎使用的一种关键技术。

 

可以通过ALTER TABLE table_name ADD FULLTEXT (column);创建全文索引

 

索引的数据结构(b树,hash)

索引的数据结构和具体存储引擎的实现有关,在MySQL中使用较多的索引有Hash索引,B+树索引等,而我们经常使用的InnoDB存储引擎的默认索引实现为:B+树索引。对于哈希索引来说,底层的数据结构就是哈希表,因此在绝大多数需求为单条记录查询的时候,可以选择哈希索引,查询性能最快;其余大部分场景,建议选择BTree索引。

 

1)B树索引

mysql通过存储引擎取数据,基本上90%的人用的就是InnoDB了,按照实现方式分,InnoDB的索引类型目前只有两种:BTREE(B树)索引和HASH索引。B树索引是Mysql数据库中使用最频繁的索引类型,基本所有存储引擎都支持BTree索引。通常我们说的索引不出意外指的就是(B树)索引(实际是用B+树实现的,因为在查看表索引时,mysql一律打印BTREE,所以简称为B树索引)

查询方式:

主键索引区:PI(关联保存的时数据的地址)按主键查询,

普通索引区:si(关联的id的地址,然后再到达上面的地址)。所以按主键查询,速度最快

 

B+tree性质:

 

1.)n棵子tree的节点包含n个关键字,不用来保存数据而是保存数据的索引。

 

2.)所有的叶子结点中包含了全部关键字的信息,及指向含这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大顺序链接。

 

3.)所有的非终端结点可以看成是索引部分,结点中仅含其子树中的最大(或最小)关键字。

 

4.)B+ 树中,数据对象的插入和删除仅在叶节点上进行。

 

5.)B+树有2个头指针,一个是树的根节点,一个是最小关键码的叶节点。

 

2)哈希索引

简要说下,类似于数据结构中简单实现的HASH表(散列表)一样,当我们在mysql中用哈希索引时,主要就是通过Hash算法(常见的Hash算法有直接定址法、平方取中法、折叠法、除数取余法、随机数法),将数据库字段数据转换成定长的Hash值,与这条数据的行指针一并存入Hash表的对应位置;如果发生Hash碰撞(两个不同关键字的Hash值相同),则在对应Hash键下以链表形式存储。

 

索引的基本原理

索引用来快速地寻找那些具有特定值的记录。如果没有索引,一般来说执行查询时遍历整张表。

 

索引的原理很简单,就是把无序的数据变成有序的查询

 

1、把创建了索引的列的内容进行排序

2、对排序结果生成倒排表

3、在倒排表内容上拼上数据地址链

4、在查询的时候,先拿到倒排表内容,再取出数据地址链,从而拿到具体数据

 

索引算法有哪些?

索引算法有 BTree算法和Hash算法

 

BTree算法

BTree是最常用的mysql数据库索引算法,也是mysql默认的算法。因为它不仅可以被用在=,>,>=,<,<=和between这些比较操作符上,而且还可以用于like操作符,只要它的查询条件是一个不以通配符开头的常量, 例如:

  •  
  •  
  •  
  •  
-- 只要它的查询条件是一个不以通配符开头的常量select * from user where name like 'jack%'; -- 如果一通配符开头,或者没有使用常量,则不会使用索引,例如:select * from user where name like '%jack'; 

Hash算法

Hash Hash索引只能用于对等比较,例如=,<=>(相当于=)操作符。由于是一次定位数据,不像BTree索引需要从根节点到枝节点,最后才能访问到页节点这样多次IO访问,所以检索效率远高于BTree索引。

 

索引设计的原则?

1、适合索引的列是出现在where子句中的列,或者连接子句中指定的列

2、基数较小的类,索引效果较差,没有必要在此列建立索引

3、使用短索引,如果对长字符串列进行索引,应该指定一个前缀长度,这样能够节省大量索引空间

4、不要过度索引。索引需要额外的磁盘空间,并降低写操作的性能。在修改表内容的时候,索引会进行更新甚至重构,索引列越多,这个时间就会越长。所以只保持需要的索引有利于查询即可。

 

创建索引的原则(重中之重)

索引虽好,但也不是无限制的使用,最好符合一下几个原则

 

1) 最左前缀匹配原则,组合索引非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。

 

2)较频繁作为查询条件的字段才去创建索引

 

3)更新频繁字段不适合创建索引

 

4)若是不能有效区分数据的列不适合做索引列(如性别,男女未知,最多也就三种,区分度实在太低)

 

5)尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。

 

6)定义有外键的数据列一定要建立索引。

 

7)对于那些查询中很少涉及的列,重复值比较多的列不要建立索引。

 

8)对于定义为text、image和bit的数据类型的列不要建立索引。

 

创建索引的三种方式

第一种方式:在执行CREATE TABLE时创建索引

第二种方式:使用ALTER TABLE命令去增加索引

第三种方式:使用CREATE INDEX命令创建

 

删除索引

根据索引名删除普通索引、唯一索引、全文索引:alter table 表名 drop KEY 索引名

 

删除主键索引:alter table 表名 drop primary key(因为主键只有一个)。这里值得注意的是,如果主键自增长,那么不能直接执行此操作(自增长依赖于主键索引)

 

创建索引时需要注意什么?

非空字段:应该指定列为NOT NULL,除非你想存储NULL。在mysql中,含有空值的列很难进行查询优化,因为它们使得索引、索引的统计信息以及比较运算更加复杂。你应该用0、一个特殊的值或者一个空串代替空值;

 

取值离散大的字段:(变量各个取值之间的差异程度)的列放到联合索引的前面,可以通过count()函数查看字段的差异值,返回值越大说明字段的唯一值越多字段的离散程度高;

 

索引字段越小越好:数据库的数据存储以页为单位一页存储的数据越多一次IO操作获取的数据越大效率越高。

 

使用索引查询一定能提高查询的性能吗?为什么

通常,通过索引查询数据比全表扫描要快。但是我们也必须注意到它的代价。

 

索引需要空间来存储,也需要定期维护, 每当有记录在表中增减或索引列被修改时,索引本身也会被修改。这意味着每条记录的INSERT,DELETE,UPDATE将为此多付出4,5 次的磁盘I/O。因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢。使用索引查询不一定能提高查询性能,索引范围查询(INDEX RANGE SCAN)适用于两种情况:

基于一个范围的检索,一般查询返回结果集小于表中记录数的30%

基于非唯一性索引的检索

 

百万级别或以上的数据如何删除

关于索引:由于索引需要额外的维护成本,因为索引文件是单独存在的文件,所以当我们对数据的增加,修改,删除,都会产生额外的对索引文件的操作,这些操作需要消耗额外的IO,会降低增/改/删的执行效率。所以,在我们删除数据库百万级别数据的时候,查询MySQL官方手册得知删除数据的速度和创建的索引数量是成正比的。

 

1、所以我们想要删除百万数据的时候可以先删除索引(此时大概耗时三分多钟)

2、然后删除其中无用数据(此过程需要不到两分钟)

3、删除完成后重新创建索引(此时数据较少了)创建索引也非常快,约十分钟左右。

4、与之前的直接删除绝对是要快速很多,更别说万一删除中断,一切删除会回滚。那更是坑了。

 

前缀索引

语法:index(field(10)),使用字段值的前10个字符建立索引,默认是使用字段的全部内容建立索引。

 

前提:前缀的标识度高。比如密码就适合建立前缀索引,因为密码几乎各不相同。

 

实操的难度:在于前缀截取的长度。

 

我们可以利用select count(*)/count(distinct left(password,prefixLen));,通过从调整prefixLen的值(从1自增)查看不同前缀长度的一个平均匹配度,接近1时就可以了(表示一个密码的前prefixLen个字符几乎能确定唯一一条记录)

 

什么是最左前缀原则?什么是最左匹配原则

顾名思义,就是最左优先,在创建多列索引时,要根据业务需求,where子句中使用最频繁的一列放在最左边。

 

最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。

 

=和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式

 

B树和B+树的区别

1、在B树中,你可以将键和值存放在内部节点和叶子节点;但在B+树中,内部节点都是键,没有值,叶子节点同时存放键和值。

 

2、B+树的叶子节点有一条链相连,而B树的叶子节点各自独立。

 

使用B树的好处

B树可以在内部节点同时存储键和值,因此,把频繁访问的数据放在靠近根节点的地方将会大大提高热点数据的查询效率。这种特性使得B树在特定数据重复多次查询的场景中更加高效。

 

使用B+树的好处

由于B+树的内部节点只存放键,不存放值,因此,一次读取,可以在内存页中获取更多的键,有利于更快地缩小查找范围。B+树的叶节点由一条链相连,因此,当需要进行一次全数据遍历的时候,B+树只需要使用O(logN)时间找到最小的一个节点,然后通过链进行O(N)的顺序遍历即可。而B树则需要对树的每一层进行遍历,这会需要更多的内存置换次数,因此也就需要花费更多的时间

 

Hash索引和B+树所有有什么区别或者说优劣呢?

首先要知道Hash索引和B+树索引的底层实现原理:

 

hash索引底层就是hash表,进行查找时,调用一次hash函数就可以获取到相应的键值,之后进行回表查询获得实际数据。B+树底层实现是多路平衡查找树。对于每一次的查询都是从根节点出发,查找到叶子节点方可以获得所查键值,然后根据查询判断是否需要回表查询数据。

 

那么可以看出他们有以下的不同:

 

hash索引进行等值查询更快(一般情况下),但是却无法进行范围查询。

 

因为在hash索引中经过hash函数建立索引之后,索引的顺序与原顺序无法保持一致,不能支持范围查询。而B+树的的所有节点皆遵循(左节点小于父节点,右节点大于父节点,多叉树也类似),天然支持范围。

 

1、hash索引不支持使用索引进行排序,原理同上。

2、hash索引不支持模糊查询以及多列索引的最左前缀匹配。原理也是因为hash函数的不可预测。AAAA和AAAAB的索引没有相关性。

3、hash索引任何时候都避免不了回表查询数据,而B+树在符合某些条件(聚簇索引,覆盖索引等)的时候可以只通过索引完成查询。

4、hash索引虽然在等值查询上较快,但是不稳定。性能不可预测,当某个键值存在大量重复的时候,发生hash碰撞,此时效率可能极差。而B+树的查询效率比较稳定,对于所有的查询都是从根节点到叶子节点,且树的高度较低。

 

因此,在大多数情况下,直接选择B+树索引可以获得稳定且较好的查询速度。而不需要使用hash索引。

 

数据库为什么使用B+树而不是B树

1、B树只适合随机检索,而B+树同时支持随机检索和顺序检索;

 

2、B+树空间利用率更高,可减少I/O次数,磁盘读写代价更低。一般来说,索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上。这样的话,索引查找过程中就要产生磁盘I/O消耗。B+树的内部结点并没有指向关键字具体信息的指针,只是作为索引使用,其内部结点比B树小,盘块能容纳的结点中关键字数量更多,一次性读入内存中可以查找的关键字也就越多,相对的,IO读写次数也就降低了。而IO读写次数是影响索引检索效率的最大因素;

 

3、B+树的查询效率更加稳定。B树搜索有可能会在非叶子结点结束,越靠近根节点的记录查找时间越短,只要找到关键字即可确定记录的存在,其性能等价于在关键字全集内做一次二分查找。而在B+树中,顺序检索比较明显,随机检索时,任何关键字的查找都必须走一条从根节点到叶节点的路,所有关键字的查找路径长度相同,导致每一个关键字的查询效率相当。

 

4、B-树在提高了磁盘IO性能的同时并没有解决元素遍历的效率低下的问题。B+树的叶子节点使用指针顺序连接在一起,只要遍历叶子节点就可以实现整棵树的遍历。而且在数据库中基于范围的查询是非常频繁的,而B树不支持这样的操作。

 

5、增删文件(节点)时,效率更高。因为B+树的叶子节点包含所有关键字,并以有序的链表结构存储,这样可很好提高增删效率。

 

B+树在满足聚簇索引和覆盖索引的时候不需要回表查询数据,

在B+树的索引中,叶子节点可能存储了当前的key值,也可能存储了当前的key值以及整行的数据,这就是聚簇索引和非聚簇索引。在InnoDB中,只有主键索引是聚簇索引,如果没有主键,则挑选一个唯一键建立聚簇索引。如果没有唯一键,则隐式的生成一个键来建立聚簇索引。

 

当查询使用聚簇索引时,在对应的叶子节点,可以获取到整行数据,因此不用再次进行回表查询。

 

什么是聚簇索引?何时使用聚簇索引与非聚簇索引

1、聚簇索引:将数据存储与索引放到了一块,找到索引也就找到了数据

2、非聚簇索引:将数据存储于索引分开结构,索引结构的叶子节点指向了数据的对应行,myisam通过key_buffer把索引先缓存到内存中,当需要访问数据时(通过索引访问数据),在内存中直接搜索索引,然后通过索引找到磁盘相应数据,这也就是为什么索引不在key buffer命中时,速度慢的原因

 

澄清一个概念:innodb中,在聚簇索引之上创建的索引称之为辅助索引,辅助索引访问数据总是需要二次查找,非聚簇索引都是辅助索引,像复合索引、前缀索引、唯一索引,辅助索引叶子节点存储的不再是行的物理位置,而是主键值

 

非聚簇索引一定会回表查询吗?

不一定,这涉及到查询语句所要求的字段是否全部命中了索引,如果全部命中了索引,那么就不必再进行回表查询。

 

举个简单的例子,假设我们在员工表的年龄上建立了索引,那么当进行select age from employee where age < 20的查询时,在索引的叶子节点上,已经包含了age信息,不会再次进行回表查询。

 

联合索引是什么?为什么需要注意联合索引中的顺序?

MySQL可以使用多个字段同时建立一个索引,叫做联合索引。在联合索引中,如果想要命中索引,需要按照建立索引时的字段顺序挨个使用,否则无法命中索引。

 

具体原因为:

 

MySQL使用索引时需要索引有序,假设现在建立了"name,age,school"的联合索引,那么索引的排序为: 先按照name排序,如果name相同,则按照age排序,如果age的值也相等,则按照school进行排序。

 

当进行查询时,此时索引仅仅按照name严格有序,因此必须首先使用name字段进行等值查询,之后对于匹配到的列而言,其按照age字段严格有序,此时可以使用age字段用做索引查找,以此类推。因此在建立联合索引的时候应该注意索引列的顺序,一般情况下,将查询需求频繁或者字段选择性高的列放在前面。此外可以根据特例的查询或者表结构进行单独的调整。

 

事务

什么是数据库事务?

事务是一个不可分割的数据库操作序列,也是数据库并发控制的基本单位,其执行的结果必须使数据库从一种一致性状态变到另一种一致性状态。事务是逻辑上的一组操作,要么都执行,要么都不执行。

 

事务最经典也经常被拿出来说例子就是转账了。

 

假如小明要给小红转账1000元,这个转账会涉及到两个关键操作就是:将小明的余额减少1000元,将小红的余额增加1000元。万一在这两个操作之间突然出现错误比如银行系统崩溃,导致小明余额减少而小红的余额没有增加,这样就不对了。事务就是保证这两个关键操作要么都成功,要么都要失败。

 

事物的四大特性(ACID)介绍一下?

关系性数据库需要遵循ACID规则,具体内容如下:

 

原子性:事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;

 

一致性:执行事务前后,数据保持一致,多个事务对同一个数据读取的结果是相同的;

 

隔离性:并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;

 

持久性:一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

 

什么是脏读?幻读?不可重复读?

脏读(Drity Read):某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因,前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的。

 

不可重复读(Non-repeatable read):在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新的原有的数据。

 

幻读(Phantom Read):在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。

 

什么是事务的隔离级别?MySQL的默认隔离级别是什么?

为了达到事务的四大特性,数据库定义了4种不同的事务隔离级别,由低到高依次为Read uncommitted、Read committed、Repeatable read、Serializable,这四个级别可以逐个解决脏读、不可重复读、幻读这几类问题。

隔离级别脏读不可重复读幻影读
READ-UNCOMMITTED
READ-COMMITTED×
REPEATABLE-READ××
SERIALIZABLE×××

SQL 标准定义了四个隔离级别:

 

1、READ-UNCOMMITTED(读取未提交):最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。

 

2、READ-COMMITTED(读取已提交):允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。

 

3、REPEATABLE-READ(可重复读):对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。

 

4、SERIALIZABLE(可串行化):最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。

 

这里需要注意的是:Mysql 默认采用的 REPEATABLE_READ隔离级别 Oracle 默认采用的 READ_COMMITTED隔离级别

 

事务隔离机制的实现基于锁机制和并发调度。其中并发调度使用的是MVVC(多版本并发控制),通过保存修改的旧版本信息来支持并发一致性读和回滚等特性。

 

因为隔离级别越低,事务请求的锁越少,所以大部分数据库系统的隔离级别都是READ-COMMITTED(读取提交内容),但是你要知道的是InnoDB 存储引擎默认使用REPEATABLE-READ(可重读)并不会有任何性能损失。

 

InnoDB 存储引擎在分布式事务的情况下一般会用到SERIALIZABLE(可串行化)隔离级别。

 

对MySQL的锁了解吗

当数据库有并发事务的时候,可能会产生数据的不一致,这时候需要一些机制来保证访问的次序,锁机制就是这样的一个机制。

 

就像酒店的房间,如果大家随意进出,就会出现多人抢夺同一个房间的情况,而在房间上装上锁,申请到钥匙的人才可以入住并且将房间锁起来,其他人只有等他使用完毕才可以再次使用。

 

隔离级别与锁的关系

在Read Uncommitted级别下,读取数据不需要加共享锁,这样就不会跟被修改的数据上的排他锁冲突

 

在Read Committed级别下,读操作需要加共享锁,但是在语句执行完以后释放共享锁;

 

在Repeatable Read级别下,读操作需要加共享锁,但是在事务提交之前并不释放共享锁,也就是必须等待事务执行完毕以后才释放共享锁。

 

SERIALIZABLE 是限制性最强的隔离级别,因为该级别锁定整个范围的键,并一直持有锁,直到事务完成。

 

按照锁的粒度分数据库锁有哪些?锁机制与InnoDB锁算法

在关系型数据库中,可以按照锁的粒度把数据库锁分为行级锁(INNODB引擎)、表级锁(MYISAM引擎)和页级锁(BDB引擎 )。

 

MyISAM和InnoDB存储引擎使用的锁:

 

1、MyISAM采用表级锁(table-level locking)。

2、InnoDB支持行级锁(row-level locking)和表级锁,默认为行级锁

行级锁,表级锁和页级锁对比

 

行级锁 行级锁是Mysql中锁定粒度最细的一种锁,表示只针对当前操作的行进行加锁。行级锁能大大减少数据库操作的冲突。其加锁粒度最小,但加锁的开销也最大。行级锁分为共享锁 和 排他锁。

 

特点:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

 

表级锁 表级锁是MySQL中锁定粒度最大的一种锁,表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大部分MySQL引擎支持。最常使用的MYISAM与INNODB都支持表级锁定。表级锁定分为表共享读锁(共享锁)与表独占写锁(排他锁)。

 

特点:开销小,加锁快;不会出现死锁;锁定粒度大,发出锁冲突的概率最高,并发度最低。

 

页级锁 页级锁是MySQL中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但冲突多,行级冲突少,但速度慢。所以取了折衷的页级,一次锁定相邻的一组记录。

 

特点:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般

 

从锁的类别上分MySQL都有哪些锁呢?像上面那样子进行锁定岂不是有点阻碍并发效率了

从锁的类别上来讲,有共享锁和排他锁。

 

共享锁: 又叫做读锁。当用户要进行数据的读取时,对数据加上共享锁。共享锁可以同时加上多个。

 

排他锁: 又叫做写锁。当用户要进行数据的写入时,对数据加上排他锁。排他锁只可以加一个,他和其他的排他锁,共享锁都相斥。

 

用上面的例子来说就是用户的行为有两种,一种是来看房,多个用户一起看房是可以接受的。一种是真正的入住一晚,在这期间,无论是想入住的还是想看房的都不可以。

 

锁的粒度取决于具体的存储引擎,InnoDB实现了行级锁,页级锁,表级锁。

 

他们的加锁开销从大到小,并发能力也是从大到小。

 

MySQL中InnoDB引擎的行锁是怎么实现的?

答:InnoDB是基于索引来完成行锁

 

例: select * from tab_with_index where id = 1 for update;

 

for update 可以根据条件来完成行锁锁定,并且 id 是有索引键的列,如果 id 不是索引键那么InnoDB将完成表锁,并发将无从谈起

 

InnoDB存储引擎的锁的算法有三种

Record lock:单个行记录上的锁

Gap lock:间隙锁,锁定一个范围,不包括记录本身

Next-key lock:record+gap 锁定一个范围,包含记录本身

 

相关知识点:

1、innodb对于行的查询使用next-key lock

2、Next-locking keying为了解决Phantom Problem幻读问题

3、当查询的索引含有唯一属性时,将next-key lock降级为record key

4、Gap锁设计的目的是为了阻止多个事务将记录插入到同一范围内,而这会导致幻读问题的产生

5、有两种方式显式关闭gap锁:(除了外键约束和唯一性检查外,其余情况仅使用record lock) A. 将事务隔离级别设置为RC B. 将参数innodb_locks_unsafe_for_binlog设置为1

 

什么是死锁?怎么解决?

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

 

常见的解决死锁的方法

 

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

 

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

 

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

 

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

 

数据库的乐观锁和悲观锁是什么?怎么实现的?

数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性。乐观并发控制(乐观锁)和悲观并发控制(悲观锁)是并发控制主要采用的技术手段。

 

悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。在查询完数据的时候就把事务锁起来,直到提交事务。实现方式:使用数据库中的锁机制

 

乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。在修改数据的时候把事务锁起来,通过version的方式来进行锁定。实现方式:乐一般会使用版本号机制或CAS算法实现。

 

两种锁的使用场景

 

从上面对两种锁的介绍,我们知道两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下(多读场景),即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。

 

但如果是多写的情况,一般会经常产生冲突,这就会导致上层应用会不断的进行retry,这样反倒是降低了性能,所以一般多写的场景下用悲观锁就比较合适。

 

数据库优化

为什么要优化

1、系统的吞吐量瓶颈往往出现在数据库的访问速度上

2、随着应用程序的运行,数据库的中的数据会越来越多,处理时间会相应变慢

3、数据是存放在磁盘上的,读写速度无法和内存相比

 

优化原则:减少系统瓶颈,减少资源占用,增加系统的反应速度。

 

数据库结构优化

一个好的数据库设计方案对于数据库的性能往往会起到事半功倍的效果。

 

需要考虑数据冗余、查询和更新的速度、字段的数据类型是否合理等多方面的内容。

 

将字段很多的表分解成多个表

 

对于字段较多的表,如果有些字段的使用频率很低,可以将这些字段分离出来形成新表。

 

因为当一个表的数据量很大时,会由于使用频率低的字段的存在而变慢。

 

增加中间表

 

对于需要经常联合查询的表,可以建立中间表以提高查询效率。

 

通过建立中间表,将需要通过联合查询的数据插入到中间表中,然后将原来的联合查询改为对中间表的查询。

 

增加冗余字段

 

设计数据表时应尽量遵循范式理论的规约,尽可能的减少冗余字段,让数据库设计看起来精致、优雅。但是,合理的加入冗余字段可以提高查询速度。

 

表的规范化程度越高,表和表之间的关系越多,需要连接查询的情况也就越多,性能也就越差。

 

注意

 

冗余字段的值在一个表中修改了,就要想办法在其他表中更新,否则就会导致数据不一致的问题。

 

MySQL数据库cpu飙升到500%的话他怎么处理?

当 cpu 飙升到 500%时,先用操作系统命令 top 命令观察是不是 mysqld 占用导致的,如果不是,找出占用高的进程,并进行相关处理。

 

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

 

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

 

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

 

大表怎么优化?某个表有近千万数据,CRUD比较慢,如何优化?分库分表了是怎么做的?分表分库了有什么问题?有用到中间件么?他们的原理知道么?

当MySQL单表记录数过大时,数据库的CRUD性能会明显下降,一些常见的优化措施如下:

 

1、限定数据的范围:务必禁止不带任何限制数据范围条件的查询语句。比如:我们当用户在查询订单历史的时候,我们可以控制在一个月的范围内;

2、读/写分离:经典的数据库拆分方案,主库负责写,从库负责读;

3、缓存:使用MySQL的缓存,另外对重量级、更新少的数据可以考虑使用应用级别的缓存;

 

还有就是通过分库分表的方式进行优化,主要有垂直分表和水平分表

 

垂直分区:

 

根据数据库里面数据表的相关性进行拆分。例如,用户表中既有用户的登录信息又有用户的基本信息,可以将用户表拆分成两个单独的表,甚至放到单独的库做分库。

 

简单来说垂直拆分是指数据表列的拆分,把一张列比较多的表拆分为多张表。如下图所示,这样来说大家应该就更容易理解了。

 

垂直拆分的优点:可以使得行数据变小,在查询时减少读取的Block数,减少I/O次数。此外,垂直分区可以简化表的结构,易于维护。

 

垂直拆分的缺点:主键会出现冗余,需要管理冗余列,并会引起Join操作,可以通过在应用层进行Join来解决。此外,垂直分区会让事务变得更加复杂;

 

垂直分表

把主键和一些列放在一个表,然后把主键和另外的列放在另一个表中

垂直拆分的优点:可以使得行数据变小,在查询时减少读取的Block数,减少I/O次数。此外,垂直分区可以简化表的结构,易于维护。

 

垂直拆分的缺点:主键会出现冗余,需要管理冗余列,并会引起Join操作,可以通过在应用层进行Join来解决。此外,垂直分区会让事务变得更加复杂;

 

垂直分表

把主键和一些列放在一个表,然后把主键和另外的列放在另一个表中

适用场景

1、如果一个表中某些列常用,另外一些列不常用

2、可以使数据行变小,一个数据页能存储更多数据,查询时减少I/O次数

 

缺点

1、有些分表的策略基于应用层的逻辑算法,一旦逻辑算法改变,整个分表逻辑都会改变,扩展性较差

2、对于应用层来说,逻辑算法增加开发成本

3、管理冗余列,查询所有数据需要join操作

 

水平分区:

 

保持数据表结构不变,通过某种策略存储数据分片。这样每一片数据分散到不同的表或者库中,达到了分布式的目的。水平拆分可以支撑非常大的数据量。

 

水平拆分是指数据表行的拆分,表的行数超过200万行时,就会变慢,这时可以把一张的表的数据拆成多张表来存放。举个例子:我们可以将用户信息表拆分成多个用户信息表,这样就可以避免单一表数据量过大对性能造成影响。

水品拆分可以支持非常大的数据量。需要注意的一点是:分表仅仅是解决了单一表数据过大的问题,但由于表的数据还是在同一台机器上,其实对于提升MySQL并发能力没有什么意义,所以 水平拆分最好分库 。

 

水平拆分能够 支持非常大的数据量存储,应用端改造也少,但 分片事务难以解决 ,跨界点Join性能较差,逻辑复杂。

 

《Java工程师修炼之道》的作者推荐 尽量不要对数据进行分片,因为拆分会带来逻辑、部署、运维的各种复杂度 ,一般的数据表在优化得当的情况下支撑千万以下的数据量是没有太大问题的。如果实在要分片,尽量选择客户端分片架构,这样可以减少一次和中间件的网络I/O。

 

水平分表:

表很大,分割后可以降低在查询时需要读的数据和索引的页数,同时也降低了索引的层数,提高查询次数

适用场景

1、表中的数据本身就有独立性,例如表中分表记录各个地区的数据或者不同时期的数据,特别是有些数据常用,有些不常用。

2、需要把数据存放在多个介质上。

 

水平切分的缺点

1、给应用增加复杂度,通常查询时需要多个表名,查询所有数据都需UNION操作

2、在许多数据库应用中,这种复杂度会超过它带来的优点,查询时会增加读一个索引层的磁盘次数

 

下面补充一下数据库分片的两种常见方案:

 

1、客户端代理:分片逻辑在应用端,封装在jar包中,通过修改或者封装JDBC层来实现。当当网的 Sharding-JDBC 、阿里的TDDL是两种比较常用的实现。

2、中间件代理:在应用和数据中间加了一个代理层。分片逻辑统一维护在中间件服务中。我们现在谈的 Mycat 、360的Atlas、网易的DDB等等都是这种架构的实现。

 

分库分表后面临的问题

 

事务支持:分库分表后,就成了分布式事务了。如果依赖数据库本身的分布式事务管理功能去执行事务,将付出高昂的性能代价;如果由应用程序去协助控制,形成程序逻辑上的事务,又会造成编程方面的负担。

 

跨库join:只要是进行切分,跨节点Join的问题是不可避免的。但是良好的设计和切分却可以减少此类情况的发生。解决这一问题的普遍做法是分两次查询实现。在第一次查询的结果集中找出关联数据的id,根据这些id发起第二次请求得到关联数据。 分库分表方案产品

 

跨节点的count,order by,group by以及聚合函数问题:这些是一类问题,因为它们都需要基于全部数据集合进行计算。多数的代理都不会自动处理合并工作。解决方案:与解决跨节点join问题的类似,分别在各个节点上得到结果后在应用程序端进行合并。和join不同的是每个结点的查询可以并行执行,因此很多时候它的速度要比单一大表快很多。但如果结果集很大,对应用程序内存的消耗是一个问题。

 

数据迁移,容量规划,扩容等问题:来自淘宝综合业务平台团队,它利用对2的倍数取余具有向前兼容的特性(如对4取余得1的数对2取余也是1)来分配数据,避免了行级别的数据迁移,但是依然需要进行表级别的迁移,同时对扩容规模和分表数量都有限制。总得来说,这些方案都不是十分的理想,多多少少都存在一些缺点,这也从一个侧面反映出了Sharding扩容的难度。

 

ID问题

 

一旦数据库被切分到多个物理结点上,我们将不能再依赖数据库自身的主键生成机制。一方面,某个分区数据库自生成的ID无法保证在全局上是唯一的;另一方面,应用程序在插入数据之前需要先获得ID,以便进行SQL路由. 一些常见的主键生成策略

 

UUID 使用UUID作主键是最简单的方案,但是缺点也是非常明显的。由于UUID非常的长,除占用大量存储空间外,最主要的问题是在索引上,在建立索引和基于索引进行查询时都存在性能问题。Twitter的分布式自增ID算法Snowflake 在分布式系统中,需要生成全局UID的场合还是比较多的,twitter的snowflake解决了这种需求,实现也还是很简单的,除去配置信息,核心代码就是毫秒级时间41位 机器ID 10位 毫秒内序列12位。

 

1、跨分片的排序分页

 

般来讲,分页时需要按照指定字段进行排序。当排序字段就是分片字段的时候,我们通过分片规则可以比较容易定位到指定的分片,而当排序字段非分片字段的时候,情况就会变得比较复杂了。为了最终结果的准确性,我们需要在不同的分片节点中将数据进行排序并返回,并将不同分片返回的结果集进行汇总和再次排序,最后再返回给用户。如下图所示:

MySQL的复制原理以及流程

主从复制:将主数据库中的DDL和DML操作通过二进制日志(BINLOG)传输到从数据库上,然后将这些日志重新执行(重做);从而使得从数据库的数据与主数据库保持一致。

 

主从复制的作用

主数据库出现问题,可以切换到从数据库。

可以进行数据库层面的读写分离。

可以在从数据库上进行日常备份。

 

MySQL主从复制解决的问题

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

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

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

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

 

MySQL主从复制工作原理

在主库上把数据更高记录到二进制日志

从库将主库的日志复制到自己的中继日志

从库读取中继日志的事件,将其重放到从库数据中

 

基本原理流程,3个线程以及之间的关联

主:binlog线程——记录下所有改变了数据库数据的语句,放进master上的binlog中;

 

从:io线程——在使用start slave 之后,负责从master上拉取 binlog 内容,放进自己的relay log中;

 

从:sql执行线程——执行relay log中的语句;

 

复制过程

Binary log:主数据库的二进制日志

Relay log:从服务器的中继日志

 

第一步:master在每个事务更新数据完成之前,将该操作记录串行地写入到binlog文件中。

 

第二步:salve开启一个I/O Thread,该线程在master打开一个普通连接,主要工作是binlog dump process。如果读取的进度已经跟上了master,就进入睡眠状态并等待master产生新的事件。I/O线程最终的目的是将这些事件写入到中继日志中。

 

第三步:SQL Thread会读取中继日志,并顺序执行该日志中的SQL事件,从而与主数据库中的数据保持一致。

 

读写分离有哪些解决方案?

读写分离是依赖于主从复制,而主从复制又是为读写分离服务的。因为主从复制要求slave不能写只能读(如果对slave执行写操作,那么show slave status将会呈现Slave_SQL_Running=NO,此时你需要按照前面提到的手动同步一下slave)。

 

方案一:

使用mysql-proxy代理

 

优点:直接实现读写分离和负载均衡,不用修改代码,master和slave用一样的帐号,mysql官方不建议实际生产中使用

 

缺点:降低性能, 不支持事务

 

方案二

使用AbstractRoutingDataSource+aop+annotation在dao层决定数据源。

如果采用了mybatis, 可以将读写分离放在ORM层,比如mybatis可以通过mybatis plugin拦截sql语句,所有的insert/update/delete都访问master库,所有的select 都访问salve库,这样对于dao层都是透明。plugin实现时可以通过注解或者分析语句是读写方法来选定主从库。不过这样依然有一个问题, 也就是不支持事务, 所以我们还需要重写一下DataSourceTransactionManager, 将read-only的事务扔进读库, 其余的有读有写的扔进写库。

 

方案三

使用AbstractRoutingDataSource+aop+annotation在service层决定数据源,可以支持事务.

 

缺点:类内部方法通过this.xx()方式相互调用时,aop不会进行拦截,需进行特殊处理。

 

 

 

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
面试高级开发的期间整理的面试目,记录我面试遇到过的数据库目以及答案,比如说mvvc还有数据库调优,索引。 目录如下 数据库 数据库事务隔离级别; 事务的并发导致的问; 数据库事务设置不同的隔离级别会导致的不同并发问 当前读和快照读的意义; mvcc:多版本控制: 指的是一种提高并发的技术,其解决问是什么; MVCC实现过程; mvcc三大组件; RC、RR级别下的InnoDB快照读有什么不同:17 mysql面试01.vep 描述一下mysql的乐观锁和悲观锁,以及mysql锁的种类; mysql如何做分库分表的; mysql描述一下mysql主从复制的机制的原理;mysql主从复制主要有几种模式 在mysql开启Binlog(为了其他非事务引擎复制所以引入binlog,比如说主从)后,如何保证binlog和InnoDB redo日志的一致性呢; binlog和redo log和区别; mysql涉及到的log有哪些; 阿里要求尽量少用join,为什么; 索引 索引分类 索引的数据结构; b树和b+树的区别 索引失效的情况: 数据库优化 查询计划的结果中看哪些关键数据; mysql 如何调优; 索引是建的越多越好吗; 在表查询中,一律不要使用 * 作为查询的字段列表,原因是什么; 描述一下InnoDB和MyISAM的区别; 当前读和快照读的意义; 13 mvcc:多版本控制: 指的是一种提高并发的技术,其解决问是什么; 14 MVCC实现过程; 14 mvcc三大组件; 15 RC、RR级别下的InnoDB快照读有什么不同:17 mysql面试01.vep 17 描述一下mysql的乐观锁和悲观锁,以及mysql锁的种类; 17 mysql如何做分库分表的; 18 mysql描述一下mysql主从复制的机制的原理;mysql主从复制主要有几种模式 19 在mysql开启Binlog(为了其他非事务引擎复制所以引入binlog,比如说主从)后,如何保证binlog和InnoDB redo日志的一致性呢; 20 binlog和redo log和区别; 22 mysql涉及到的log有哪些; 23 阿里要求尽量少用join,为什么; 23 索引 24 索引分类 24 索引的数据结构; 24 b树和b+树的区别 26 索引失效的情况: 26 数据库优化 27 查询计划的结果中看哪些关键数据; 27 mysql 如何调优; 27 索引是建的越多越好吗; 29 在表查询中,一律不要使用 * 作为查询的字段列表,原因是什么; 29 描述一下InnoDB和MyISAM的区别; 29

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值