后台JAVA面试-数据库部分(二)


后台JAVA面试-数据库部分(二)

许多面试过开发岗位的小伙伴都知道,数据库在后台开发面试中是必问的问题,树懒君特意收集了最新的后台开发-数据库部分面试题目。

一、MySQL的存储引擎分类

具体可看下图

数据库面试题目,JAVA面试,MySQL的存储引擎,数据库基础,数据库语句执行顺序

重点介绍经常使用的四种存储引擎:InnoDB、MyISAM、MEMORY、MERGE

InnoDB

InnoDB存储表和索引有以下两种方式:

使用共享表空间存储,这种方式创建的表的表结构保存在.frm文件中,数据和索引保存在innodb_data_home_dir和innodb_data_file_path定义的表空间中,可以是多个文件。

使用多表空间存储,这种方式创建的表的表结构仍然存在.frm文件中,但是每个表的数据和索引单独保存在.ibd中。

MyISAM

MyISAM不支持事务、也不支持外键,其优势是访问的速度快,对事务的完整性没有要求或者以SELECT、INSERT为主的应用基本上都可以使用这个引擎来创建表。有以下两个比较重要的特点:

不支持事务

文件存储方式

每个MyISAM在磁盘上存储成3个文件,其文件名都和表名相同,但拓展名分别是:

.frm(存储表定义);

.MYD(MYData,存储数据);

.MYI(MYIndex,存储索引);

MEMORY

​Memory存储引擎将表的数据存放在内存中。每个MEMORY表实际对应一个磁盘文件,格式是.frm,该文件中只存储表的结构,而其数据文件,都是存储在内存中,这样有利于数据的快速处理,提高整个表的效率。MEMORY类型的表访问非常地快,因为他的数据是存放在内存中的,并且默认使用HASH索引,但是服务一旦关闭,表中的数据就会丢失。

MERGE

MERGE存储引擎是一组MyISAM表的组合,这些MyISAM表必须结构完全相同,MERGE表本身并没有存储数据,对MERGE类型的表可以进行查询、更新、删除操作,这些操作实际上是对内部的MyISAM表进行的。

​对于MERGE类型表的插入操作,是通过INSERT_METHOD子句定义插入的表,可以有3个不同的值,使用FIRST或LAST值使得插入操作被相应地作用在第一或者最后一个表上,不定义这个子句或者定义为NO,表示不能对这个MERGE表执行插入操作。

​可以对MERGE表进行DROP操作,但是这个操作只是删除MERGE表的定义,对内部的表是没有任何影响的。

二、如何选择MySQL的存储引擎?

根据系统的业务要求选择,首先要了解索引的特点
InnoDB: 如果对数据的完整性要求比较高,且除了插入和查询外,还存在着许多更新和删除操作的,适用于选择InnoDB,InnoDB也是Mysql现在默认的存储引擎。
MyISAM: 以只读或者插入操作为主,很少的更新和删除操作的,并且对数据完整性要求不高的可以选择。

三、InnoDB和MyISAM的区别

MySQL默认采用的是MyISAM。

MyISAM不支持事务,而InnoDB支持。InnoDB的AUTOCOMMIT默认是打开的,即每条SQL语句会默认被封装成一个事务,自动提交,这样会影响速度,所以最好是把多条SQL语句显示放在begin和commit之间,组成一个事务去提交。

InnoDB支持数据行锁定,MyISAM不支持行锁定,只支持锁定整个表。即MyISAM同一个表上的读锁和写锁是互斥的,MyISAM并发读写时如果等待队列中既有读请求又有写请求,默认写请求的优先级高,即使读请求先到,所以MyISAM不适合于有大量查询和修改并存的情况,那样查询进程会长时间阻塞。因为MyISAM是锁表,所以某项读操作比较耗时会使其他写进程饿死。

InnoDB支持外键,MyISAM不支持。

InnoDB的主键范围更大,最大是MyISAM的2倍。

InnoDB不支持全文索引,而MyISAM支持。全文索引是指对char、varchar和text中的每个词(停用词除外)建立倒排序索引。MyISAM的全文索引其实没啥用,因为它不支持中文分词,必须由使用者分词后加入空格再写到数据表里,而且少于4个汉字的词会和停用词一样被忽略掉。

MyISAM支持GIS数据,InnoDB不支持。即MyISAM支持以下空间数据对象:Point,Line,Polygon,Surface等。

没有where的count(*)使用MyISAM要比InnoDB快得多。因为MyISAM内置了一个计数器,count(*)时它直接从计数器中读,而InnoDB必须扫描全表。所以在InnoDB上执行count(*)时一般要伴随where,且where中要包含主键以外的索引列。为什么这里特别强调“主键以外”?因为InnoDB中primaryindex是和rawdata存放在一起的,而secondaryindex则是单独存放,然后有个指针指向primarykey。所以只是count(*)的话使用secondaryindex扫描更快,而primarykey则主要在扫描索引同时要返回rawdata时的作用较大。

四、数据库语句的执行顺序

开始->FROM子句->WHERE子句->GROUPBY子句->HAVING子句->ORDERBY子句->SELECT子句->LIMIT子句->最终结果

每个子句执行后都会产生一个中间结果,供接下来的子句使用,如果不存在某个子句,就跳过

select考生姓名,max(总成绩)asmax总成绩

fromtb_Grade

where考生姓名isnotnull

groupby考生姓名

havingmax(总成绩)>600

orderbymax总成绩

在上面的示例中SQL语句的执行顺序如下:

首先执行FROM子句,从tb_Grade表组装数据源的数据

执行WHERE子句,筛选tb_Grade表中所有数据不为NULL的数据

执行GROUPBY子句,把tb_Grade表按”学生姓名”列进行分组(注:这一步开始才可以使用select中的别名,他返回的是一个游标,而不是一个表,所以在where中不可以使用select中的别名,而having却可以使用,感谢网友zyt1369提出这个问题)

计算max()聚集函数,按”总成绩”求出总成绩中最大的一些数值

执行HAVING子句,筛选课程的总成绩大于600分的.

执行ORDERBY子句,把最后的结果按”Max成绩”进行排序.