天天看点

【搞定MySQL数据库】面试题整理

博主秋招提前批已拿百度、字节跳动、拼多多、顺丰等公司的offer,可加微信一起交流秋招面试经验。

【搞定MySQL数据库】面试题整理

事务的隔离级别

具体讲解:https://blog.csdn.net/pcwl1206/article/details/84478127

1、读未提交  READ  UNCOMMITED    ----> 引发脏读

2、读已提交  READ  COMMITED         -----> 引发不可重复读

3、可重复读  REPEATABLE  READ     -----> 引发幻读

4、序列化  SERIALIZABLE   

触发器的作用?

触发器是一中特殊的存储过程,主要是通过事件来触发而被执行的。它可以强化约束,来维护数据的完整性和一致性,可以跟踪数据库内的操作从而不允许未经许可的更新和变化。可以联级运算。如,某表上的触发器上包含对另一个表的数据操作,而该操作又会导致该表触发器被触发。

MySQL触发器简单实例

1、CREATE TRIGGER <触发器名称>  --触发器必须有名字,最多64个字符,可能后面会附有分隔符.它和MySQL中其他对象的命名方式基本相象.

2、{ BEFORE | AFTER }  --触发器有执行的时间设置:可以设置为事件发生前或后。

3、{ INSERT | UPDATE | DELETE }  --同样也能设定触发的事件:它们可以在执行insert、update或delete的过程中触发。

4、ON <表名称>  --触发器是属于某一个表的:当在这个表上执行插入、 更新或删除操作的时候就导致触发器的激活. 我们不能给同一张表的同一个事件安排两个触发器。

5、FOR EACH ROW  --触发器的执行间隔:FOR EACH ROW子句通知触发器 每隔一行执行一次动作,而不是对整个表执行一次。

6、<触发器SQL语句>  --触发器包含所要触发的SQL语句:这里的语句可以是任何合法的语句, 包括复合语句,但是这里的语句受的限制和函数的一样。

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

存储过程是一个预编译的SQL语句,优点是允许模块化的设计,就是说只需创建一次,以后在该程序中就可以调用多次。如果某次操作需要执行多次SQL,使用存储过程比单纯SQL语句执行要快。

调用: 1)可以用一个命令对象来调用存储过程。 2)可以供外部程序调用,比如:java程序。

  • 特性:

1、有输入输出参数,可以声明变量,有if/else, case,while等控制语句,通过编写存储过程,可以实现复杂的逻辑功能;

2、函数的普遍特性:模块化,封装,代码复用;

3、速度快,只有首次执行需经过编译和优化步骤,后续被调用可以直接执行,省去以上步骤。

存储过程的优缺点?

优点:

1)存储过程是预编译过的,执行效率高。

2)存储过程的代码直接存放于数据库中,通过存储过程名直接调用,减少网络通讯。

3)安全性高,执行存储过程需要有一定权限的用户。

4)存储过程可以重复使用,可减少数据库开发人员的工作量。

缺点:

移植性差

存储过程与函数的区别

存储过程

1、用于在数据库中完成特定的操作或者任务(如插入、删除等)

2、程序头部声明用procedure

3、程序头部声明时不需描述返回类型可以使用in/out/in out 三种模式的参数

4、可作为一个独立的PL/SQL语句来执行

5、可以通过out/in out 返回零个或多个值

6、SQL语句(DML 或SELECT)中不可调用存储过程

函数

1、用于特定的数据(如选择)

2、程序头部声明用function

3、程序头部声明时要描述返回类型,而且PL/SQL块中至少要包括一个有效的return语句

4、可以使用in/out/in out 三种模式的参数

5、不能独立执行,必须作为表达式的一部分调用

6、通过return语句返回一个值,且改值要与声明部分一致,也可以是通过out类型的参数带出的变量

7、SQL语句(DML 或SELECT)中可以调用函数

索引的作用?和它的优点缺点是什么?

索引就一种特殊的查询表,数据库的搜索可以利用它加速对数据的检索。它很类似与现实生活中书的目录,不需要查询整本书内容就可以找到想要的数据。索引可以是唯一的,创建索引允许指定单个列或者是多个列。缺点是它减慢了数据录入的速度,同时也增加了数据库的尺寸大小。

什么样的字段适合建索引

唯一、不为空、经常被查询的字段

索引类型有哪些?

逻辑上:

Single column 单行索引

Concatenated 多行索引

Unique 唯一索引

NonUnique 非唯一索引

Function-based 函数索引

Domain 域索引 物理上:

Partitioned 分区索引

NonPartitioned 非分区索引

B-tree :

Normal 正常型B树

Rever Key 反转型B树 Bitmap 位图索引

什么是事务?什么是锁?

事务就是被绑定在一起作为一个逻辑工作单元的SQL语句分组,如果任何一个语句操作失败那么整个操作就被失败,以后操作就会回滚到操作前状态,或者是上有个节点。为了确保要么执行,要么不执行,就可以使用事务。要将有组语句作为事务考虑,就需要通过ACID测试,即原子性,一致性,隔离性和持久性。 锁:在所以的DBMS中,锁是实现事务的关键,锁可以保证事务的完整性和并发性。与现实生活中锁一样,它可以使某些数据的拥有者,在某段时间内不能使用某些数据或数据结构。当然锁还分级别的。

什么叫视图?游标是什么?

视图:是一种虚拟的表,具有和物理表相同的功能。可以对视图进行增,改,查,操作,试图通常是有一个表或者多个表的行或列的子集。对视图的修改会影响基本表。它使得我们获取数据更容易,相比多表查询。

游标:是对查询出来的结果集作为一个单元来有效的处理。游标可以定在该单元中的特定行,从结果集的当前行检索一行或多行。可以对结果集当前行做修改。一般不使用游标,但是需要逐条处理数据的时候,游标显得十分重要。

视图的优缺点

优点: 1)对数据库的访问,因为视图可以有选择性的选取数据库里的一部分。 2 )用户通过简单的查询可以从复杂查询中得到结果。 3 )维护数据的独立性,试图可从多个表检索数据。 4 )对于相同的数据可产生不同的视图。

缺点: 性能:查询视图时,必须把视图的查询转化成对基本表的查询,如果这个视图是由一个复杂的多表查询所定义,那么,那么就无法更改数据

列举几种表连接方式,有什么区别?

内连接、自连接、外连接(左、右、全)、交叉连接

内连接:只有两个元素表相匹配的才能在结果集中显示。

外连接: 左外连接:左边为驱动表,驱动表的数据全部显示,匹配表的不匹配的不会显示。

右外连接:右边为驱动表,驱动表的数据全部显示,匹配表的不匹配的不会显示。

全外连接:连接的表中不匹配的数据全部会显示出来。

交叉连接: 笛卡尔效应,显示的结果是链接表数的乘积。

主键和外键的区别?

主键在本表中是唯一的、不可唯空的,外键可以重复可以唯空;外键和另一张表的主键关联,不能创建对应表中不存在的外键。

在数据库中查询语句速度很慢,如何优化?

1.建索引 ;

2.减少表之间的关联 ;

3.优化sql,尽量让sql很快定位数据,不要让sql做全表查询,应该走索引,把数据 量大的表排在前面 ;

4.简化查询字段,没用的字段不要,已经对返回结果的控制,尽量返回少量数据 ;

5.尽量用PreparedStatement来查询,不要用Statement;

数据库三范式是什么?

第一范式:列不可再分;

第二范式:行可以唯一区分,主键约束 ;

第三范式:表的非主属性不能依赖与其他表的非主属性外键约束 。

三大范式是一级一级依赖的,第二范式建立在第一范式上,第三范式建立第一第二范式上

union和union all有什么不同?

UNION在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果。实际大部分应用中是不会产生重复的记录,最常见的是过程表与历史表UNION。 UNION ALL只是简单的将两个结果合并后就返回。这样,如果返回的两个结果集中有重复的数据,那么返回的结果集就会包含重复的数据了。 从效率上说,UNION ALL 要比UNION快很多,所以,如果可以确认合并的两个结果集中不包含重复的数据的话,那么就使用UNION ALL。

Varchar2和varchar有什么区别?

char的长度是固定的,而varchar2的长度是可以变化的。比如,存储字符串“abc”对于char(20),表示你存储的字符将占20个字节,包含17个空,而同样的varchar2(20)只占了3个字节,20只是最大值,当你存储的字符小于20时,按实际长度存储。

char的效率要被varchar2的效率高。 目前varchar是varchar2的同义词,工业标准的varchar类型可以存储空字符串,但是oracle不能这样做,尽管它保留以后这样做的权利。Oracle自己开发了一个数据类型varchar2,这个类型不是一个标准的varchar,他将在数据库中varchar列可以存储空字符串的特性改为存储null值,如果你想有向后兼容的能力,oracle建议使用varchar2而不是varchar

Oracle和MySQL的区别?

1)库函数不同;

 2)Oracle是用表空间来管理的,Mysql不是。;

3)显示当前所有的表、用户、改变连接用户、显示当前连接用户、执行外部脚本的语句的不同;

4)分页查询时候时候,mysql用limit而oracle用rownum。

mysql> SELECT * FROM table LIMIT 5,10;   // 检索记录行 6-15 
           

为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1:

mysql> SELECT * FROM table LIMIT 95,-1;  // 检索记录行 96-last. 
           

如果只给定一个参数,它表示返回最大的记录行数目:

mysql> SELECT * FROM table LIMIT 5; // 检索前 5 个记录行 
           

为什么用自增列作为主键?

1、如果我们定义了主键(PRIMARY KEY),那么InnoDB会选择主键作为聚集索引、如果没有显式定义主键,则InnoDB会选择第一个不包含有NULL值的唯一索引作为主键索引、如果也没有这样的唯一索引,则InnoDB会选择内置6字节长的ROWID作为隐含的聚集索引(ROWID随着行记录的写入而主键递增,这个ROWID不像ORACLE的ROWID那样可引用,是隐含的)。

2、数据记录本身被存于主索引(一颗B+Tree)的叶子节点上。这就要求同一个叶子节点内(大小为一个内存页或磁盘页)的各条数据记录按主键顺序存放,因此每当有一条新的记录插入时,MySQL会根据其主键将其插入适当的节点和位置,如果页面达到装载因子(InnoDB默认为15/16),则开辟一个新的页(节点);

3、如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页;

4、如果使用非自增主键(如果身份证号或学号等),由于每次插入主键的值近似于随机,因此每次新纪录都要被插到现有索引页得中间某个位置,此时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多开销,同时频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE TABLE来重建表并优化填充页面。

为什么使用数据索引能够提高效率?

1、数据索引的存储是有序的;

2、在有序的情况下,通过索引查询一个数据是无需遍历索引记录的;

3、极端情况下,数据索引的查询效率为二分法查询效率,趋近于 log2(N)。

B+ 树索引和哈希索引的区别?

 B+树是一个平衡的多叉树,从根节点到每个叶子节点的高度差值不超过1,而且同层级的节点间有指针相互链接,是有序的。

【搞定MySQL数据库】面试题整理

哈希索引就是采用一定的哈希算法,把键值换算成新的哈希值,检索时不需要类似B+树那样从根节点到叶子节点逐级查找,只需一次哈希算法即可,是无序的。

【搞定MySQL数据库】面试题整理
  • 哈希索引的优势:

1、等值查询。哈希索引具有绝对优势(前提是:没有大量重复键值,如果大量重复键值时,哈希索引的效率很低,因为存在所谓的哈希碰撞问题。) 

  • 哈希索引不适用的场景:

1、不支持范围查询;

2、不支持索引完成排序;

3、不支持联合索引的最左前缀匹配规则。

通常,B+树索引结构适用于绝大多数场景,像下面这种场景用哈希索引才更有优势:

在HEAP表中,如果存储的数据重复度很低(也就是说基数很大),对该列数据以等值查询为主,没有范围查询、没有排序的时候,特别适合采用哈希索引,例如这种SQL:

select id, name from table where name = '李明';  -- 仅等值查询
           

而常用的InnoDB引擎中默认使用的是B+树索引,它会实时监控表上索引的使用情况,如果认为建立哈希索引可以提高查询效率,则自动在内存中的“自适应哈希索引缓冲区”建立哈希索引(在InnoDB中默认开启自适应哈希索引),通过观察搜索模式,MySQL会利用 index key 的前缀建立哈希索引,如果一个表几乎大部分都在缓冲池中,那么建立一个哈希索引能够加快等值查询。

注意:在某些工作负载下,通过哈希索引查找带来的性能提升远大于额外的监控索引搜索情况和保持这个哈希表结构所带来的开销。但某些时候,在负载高的情况下,自适应哈希索引中添加的 read/write 锁也会带来竞争,比如高并发的 join 操作。like 操作和 % 的通配符操作也不适用于自适应哈希索引,可能要关闭自适应哈希索引。

B树和B+树的区别?

1、B树,每个节点都存储 key 和 data,所有节点组成这棵树,并且叶子节点指针为null,叶子结点不包含任何关键字信息。

【搞定MySQL数据库】面试题整理

2、B+树,所有的叶子结点中包含了全部关键字的信息,及指向含有这些关键字记录的指针,且叶子结点本身以关键字的大小自小而大的顺序链接,所有的非终端结点可以看成是索引部分,结点中仅含有其子树根结点中最大(或最小)关键字。 (而B 树的非终节点包含需要查找的有效信息)。

【搞定MySQL数据库】面试题整理

为什么说B+比B树更适合实际应用中操作系统的文件索引和数据库索引?

1、B+的磁盘读写代价更低。B+的内部结点并没有指向关键字具体信息的指针。因此其内部结点相对B树更小。如果把所有同一内部结点的关键字存放在同一盘块中,那么磁盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多。相对来说IO读写次数也就降低了。

2、B+-tree的查询效率更加稳定。由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。

MySQL联合索引

1、联合索引是两个或更多个列上的索引。对于联合索引:MySQL从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分。例如索引是key index (a,b,c). 可以支持a、 a,b 、a,b,c 3种组合进行查找,但不支持 b,c进行查找 ,当最左侧字段是常量引用时,索引就十分有效。

2、利用索引中的附加列,您可以缩小搜索的范围,但使用一个具有两列的索引,不同于使用两个单独的索引。复合索引的结构与电话簿类似,人名由姓和名构成,电话簿首先按姓氏对进行排序,然后按名字对有相同姓氏的人进行排序。如果您知道姓,电话簿将非常有用;如果您知道姓和名,电话簿则更为有用,但如果您只知道名不姓,电话簿将没有用处。

什么情况下应不建或少建索引?

1、表记录太少;

2、经常插入、删除、修改的表;

3、数据重复且分布平均的表字段,假如一个表有10万行记录,有一个字段A只有T和F两种值,且每个值的分布概率大约为50%,那么对这种表A字段建索引一般不会提高数据库的查询速度;

4、经常和主字段一块查询,但主字段索引值比较多的表字段。

MySQL分区

1. 什么是表分区?

表分区,是指根据一定规则,将数据库中的一张表分解成多个更小的,容易管理的部分。从逻辑上看,只有一张表,但是底层却是由多个物理分区组成。

2. 表分区与分表的区别?

分表:指的是通过一定规则,将一张表分解成多张不同的表。比如将用户订单记录根据时间成多个表。

分表与分区的区别在于:分区从逻辑上来讲只有一张表,而分表则是将一张表分解成多张表。

3. 表分区有什么好处?

1、分区表的数据可以分布在不同的物理设备上,从而高效地利用多个硬件设备。 

2、和单个磁盘或者文件系统相比,可以存储更多数据。

3、优化查询。在where语句中包含分区条件时,可以只扫描一个或多个分区表来提高查询效率;涉及sum和count语句时,也可以在多个分区上并行处理,最后汇总结果。

4、分区表更容易维护。例如:想批量删除大量数据可以清除整个分区。

5、可以使用分区表来避免某些特殊的瓶颈,例如InnoDB的单个索引的互斥访问,ext3问价你系统的inode锁竞争等。

4. 分区表的限制因素?

1、一个表最多只能有1024个分区;

2、MySQL5.1中,分区表达式必须是整数,或者返回整数的表达式。在MySQL5.5中提供了非整数表达式分区的支持;

3、如果分区字段中有主键或者唯一索引的列,那么有主键列和唯一索引列都必须包含进来。即:分区字段要么不包含主键或者索引列,要么包含全部主键和索引列。

4、分区表中无法使用外键约束;

5、MySQL的分区适用于一个表的所有数据和索引,不能只对表数据分区而不对索引分区,也不能只对索引分区而不对表分区,也不能只对表的一部分数据分区。

5. 如何判断当前MySQL是否支持分区?

输入以下命令,如果 hava_partintioning 的值为 YES,表示支持分区。

show variables like '%partition%';
           

6. MySQL支持的分区类型有哪些?

1、RANGE分区: 这种模式允许将数据划分不同范围。例如可以将一个表通过年份划分成若干个分区;

2、LIST分区: 这种模式允许系统通过预定义的列表的值来对数据进行分割。按照List中的值分区,与RANGE的区别是,range分区的区间范围值是连续的;

3、HASH分区 :这中模式允许通过对表的一个或多个列的Hash Key进行计算,最后通过这个Hash码不同数值对应的数据区域进行分区。例如可以建立一个对表主键进行分区的表;

4、KEY分区 :上面Hash模式的一种延伸,这里的Hash Key是MySQL系统产生的。

关于MVVC

MySQL InnoDB存储引擎,实现的是基于多版本的并发控制协议——MVCC (Multi-Version Concurrency Control) (注:与MVCC相对的,是基于锁的并发控制,Lock-Based Concurrency Control)。MVCC最大的好处:读不加锁,读写不冲突。在读多写少的OLTP应用中,读写不冲突是非常重要的,极大的增加了系统的并发性能,现阶段几乎所有的RDBMS,都支持了MVCC。

1、LBCC:Lock-Based Concurrency Control,基于锁的并发控制。

2、MVCC:Multi-Version Concurrency Control,基于多版本的并发控制协议。纯粹基于锁的并发机制并发量低,MVCC是在基于锁的并发控制上的改进,主要是在读操作上提高了并发量。

在MVCC并发控制中,读操作可以分成两类:

1、快照读 (snapshot read):读取的是记录的可见版本 (有可能是历史版本),不用加锁(共享读锁s锁也不加,所以不会阻塞其他事务的写)。

2、当前读 (current read):读取的是记录的最新版本,并且,当前读返回的记录,都会加上锁,保证其他事务不会再并发修改这条记录。

行级锁定的优点:

1、当在许多线程中访问不同的行时只存在少量锁冲突;

2、回滚时只有少量的更改;

3、可以长时间锁定单一的行。

行级锁定的缺点:

1、比页级或表级锁定占用更多的内存;

2、当在表的大部分中使用时,比页级或表级锁定速度慢,因为你必须获取更多的锁;

3、如果你在大部分数据上经常进行GROUP BY操作或者必须经常扫描整个表,比其它锁定明显慢很多;

4、用高级别锁定,通过支持不同的类型锁定,你也可以很容易地调节应用程序,因为其锁成本小于行级锁定。

MySQL优化方式有哪些?

1、开启查询缓存,优化查询;

2、explain你的select查询,这可以帮你分析你的查询语句或是表结构的性能瓶颈。EXPLAIN 的查询结果还会告诉你,你的索引主键被如何利用的,你的数据表是如何被搜索和排序的;

3、当只要一行数据时使用 limit 1,MySQL数据库引擎会在找到一条数据后停止搜索,而不是继续往后查少下一条符合记录的数据;

4、为搜索字段建索引;

5、使用 ENUM 而不是 VARCHAR,如果你有一个字段,比如“性别”,“国家”,“民族”,“状态”或“部门”,你知道这些字段的取值是有限而且固定的,那么,你应该使用 ENUM 而不是VARCHAR;

6、Prepared Statements很像存储过程,是一种运行在后台的SQL语句集合,我们可以从使用 prepared statements 获得很多好处,无论是性能问题还是安全问题。Prepared Statements 可以检查一些你绑定好的变量,这样可以保护你的程序不会受到“SQL注入式”攻击;

7、垂直分表;

8、选择正确的存储引擎。

key和index的区别?

1、key 是数据库的物理结构,它包含两层意义和作用,一是约束(偏重于约束和规范数据库的结构完整性),二是索引(辅助查询用的)。包括primary key、unique key、foreign key 等;

2、index是数据库的物理结构,它只是辅助查询的,它创建时会在另外的表空间(mysql中的innodb表空间)以一个类似目录的结构存储。索引要分类的话,分为前缀索引、全文本索引等。

MySQL 中 MyISAM 和 InnoDB 的区别有哪些?

  • 区别:

1、InnoDB支持事务,MyISAM不支持,对于InnoDB每一条SQL语言都默认封装成事务,自动提交,这样会影响速度,所以最好把多条SQL语言放在begin和commit之间,组成一个事务;

2、InnoDB支持外键,而MyISAM不支持。对一个包含外键的InnoDB表转为MYISAM会失败;

3、InnoDB是聚集索引,数据文件是和索引绑在一起的,必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此,主键不应该过大,因为主键太大,其他索引也都会很大。而MyISAM是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的;

4、InnoDB不保存表的具体行数,执行select count(*) from table时需要全表扫描。而MyISAM用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快;

5、Innodb不支持全文索引,而MyISAM支持全文索引,查询效率上MyISAM要高。

  • 如何选择:

1、是否要支持事务,如果要请选择innodb,如果不需要可以考虑MyISAM;

2、如果表中绝大多数都只是读查询,可以考虑MyISAM,如果既有读写也挺频繁,请使用InnoDB;

3、系统奔溃后,MyISAM恢复起来更困难,能否接受;

4、MySQL5.5版本开始Innodb已经成为Mysql的默认引擎(之前是MyISAM),说明其优势是有目共睹的,如果你不知道用什么,那就用InnoDB,至少不会差。

数据库表创建注意事项

1、字段名及字段配制合理性

1、剔除关系不密切的字段;

2、字段命名要有规则及相对应的含义(不要一部分英文,一部分拼音,还有类似a.b.c这样不明含义的字段);

3、字段命名尽量不要使用缩写(大多数缩写都不能明确字段含义);

4、字段不要大小写混用(想要具有可读性,多个英文单词可使用下划线形式连接);

5、字段名不要使用保留字或者关键字;

6、保持字段名和类型的一致性;

7、慎重选择数字类型;

8、给文本字段留足余量。

2、系统特殊字段处理及建成后建议

1、添加删除标记(例如操作人、删除时间);

2、建立版本机制。

3、表结构合理性配置

1、多型字段的处理,就是表中是否存在字段能够分解成更小独立的几部分(例如:人可以分为男人和女人);

2、多值字段的处理,可以将表分为三张表,这样使得检索和排序更加有调理,且保证数据的完整性。

4、其它建议

1、对于大数据字段,独立表进行存储,以便影响性能(例如:简介字段);

2、使用 varchar 类型代替 char,因为 varchar 会动态分配长度,char 指定长度是固定的;

3、给表创建主键,对于没有主键的表,在查询和索引定义上有一定的影响;

4、避免表字段运行为 null,建议设置默认值(例如:int类型设置默认值为0)在索引查询上,效率立显;

5、建立索引,最好建立在唯一和非空的字段上,建立太多的索引对后期插入、更新都存在一定的影响(考虑实际情况来创建)。

继续阅读