1.关系型数据库和非关系型数据库的区别?
答:1)关系型数据库都有固定的表结构,适合复杂的存储,非关系型数据库没有固定的存储结构,易于扩展,但是只适合一些简单的存储。
2)表与表之间有关联,比如外键进行连接两个表的关系;非关系型数据库没有。
3)关系型数据库读写性能较差,非关系型数据库较好。
2.什么是存储过程?有什么优点?
答:存储过程就是带有逻辑判断的sql语句,一个存储过程可以有多条sql语句。一个存储过程只需要编译一次,效率大有提高。
3.mySQL和SQLServer的区别?
答:mysql是开源的,sqlserver是商业应用。
存储引擎不一样,sqlserver提供Sybase,mysql提供innodb等;
语言兼容性不同,sqlserver更兼容c#。
4.一条SQL执行很慢的原因?
答:可能没有用上索引,数据库很大的情况下,没有索引会进行全表查询,导致查询速度很慢。
5.mysql有哪些存储引擎,有什么区别?
答:innoDB和MyIsam,
1)innoDB支持事务,支持4个事务的隔离级别,而MyISAM不支持事务,但提供高速的存储了检索。
2)innoDB支持外键,MyIsam不支持。
3)InnoDB必须有一个唯一索引,如果用户没指定就会自己创建一个隐藏的列来充当主键,而Myisam可以没有。
4)InnoDB支持表级、行级锁,而MyIsam只支持表级锁,但是InnoDB的行级锁是实现在索引上的,而不是实际的行记录上的。
7、数据库中的锁?
答:按照粒度有表级锁和行级锁。按照级别有共享锁、排它锁、意向锁。
共享锁:是在读取操作上创建的锁,用户可以并发的查询,但是不能对的数据进行修改。
SELECT … LOCK IN SHARE LOCK
排它锁:获得排他锁的事务可以对数据进行读取和修改,其他事务没有锁不能进行操作。
SELECT … FOR UPDATE
意向锁:意向锁是表级锁
8、数据库的四种隔离级别?
答:读未提交:都解决不了,一个事务能够读取到其他事务还没提交的数据。
读提交:解决脏读,一个事务只能读取到其他事务已经提交的数据。(oracle默认)
可重复读:解决脏读,不可重复读;一个事务多次读取同一个数据的结果是一样的。(mysql默认)
串行读:解决脏读,不可重复读,幻读;强制事务串行的执行。一个事务前后发现一条自己没有操作过的数据。幻读:一个事务按先根据某些条件查询出来一些数据,之后又按这些条件查询出来数据发现不一致,发现了一条自己没有操作过的数据。
9、如何优化一个查询?
答:
10、什么是事务?事务的四大特性是什么?
答:事务是数据库执行过程中的一个逻辑单位,是并发控制的基本单位。
四大特性:ACID
Atom原子性:事务中的操作要么全部执行成功,要么全部执行失败。
Consistency一致性:一致性指事务执行结果必须是使数据库从一个一致性状态转换到另一个一致性状态。
Isolation隔离型:一个事务的执行不能被其他事务干扰,各个事务之间相互隔离。
Druability持久性:事务一旦提交,对数据库中的数据的改变是永久的
11、数据库表设计的三大范式?
答:第一范式:数据表中的每一列都是不可拆分的最小单元,比如电话里面有移动电话和固定电话,需要拆分成两列。
第二范式:表中非主键列要完全依赖于主键,而不是部分依赖于主键。比如一个学生表,有一个学号,有课程名,有姓名,有课程分数。键码有学号和课程名,课程分数完全依赖于学号和课程名,而姓名只依赖于学号。
第三范式:表中的非主键列要直接依赖于主键,比如说一个学生表中有学生学号和姓名,和所在城市id,和所在城市,而所在城市至于所在城市id有关,跟学生学号无关。
12、innoDB和Oracle的默认隔离级别?
答:innoDB的默认隔离级别是读提交,Oracle的默认隔离级别是可重复读。
13、表和视图的区别?
答:表占用物理空间,而视图只是逻辑上的一张表,视图是查看数据表的一种方法,在操作上和实际的表一样,当用户想要查看数据的时候我们就可以用视图给他,而不用将整个数据表给他,保护数据隐私。
14、mysql有哪些函数?
答:ABS(x):返回X的绝对值;
MOD(X,Y):X对Y取余
LENGTH(“字符串”):返回字符串的长度
NOW():获得当前时间
DISTINCT():去重
15、where和on的区别?
答:在使用联合查询的时候会用到on,比如left join on 后面接条件,会用右边表中符合条件的去匹配左边表,左边表中会完整的展示。where则是条件过滤,把不符合条件的全部筛掉。
16、Having和where的区别?
答:where作用与表,having作用与分组。where在数据分组前进行过滤,having在数据分组后数据过滤。
17、varchar(10)和varchar(100)的区别?
答:存储相同长度字符串的长度占用的磁盘空间都是相同,但是varchar(100)会消耗更大的内存空间,特别在排序的时候。
18、说下事务隔离级别怎么实现的MVCC?
答:MVCC是多版本并发控制,可以实现读提交和可重复读隔离级别。
MVCC可以实现读提交和可重复读两种隔离级别,在创建事务的时候都会生成一个事务id,也就是数据的版本号,按照创建的顺序递增。在每行数据中会有两个隐藏列,一个是对这行数据修改的事务id,一个是一个指针,指向被修改前的数据,会在undo log中保留事务操作数据的历史版本。在事务查询前会生成一个ReadView,可以理解成是一个数据快照,包含当前活跃的事务id列表。在读数据的时候,如果读到的数据记录的事务id都小于这个活跃事务id列表的id值或者不在这个活跃事务id列表中,说明这个版本数据已经提交,可以访问;如果都大于或在这个列表中,不可访问。
而读提交和可重复读的区别就是生成这个readview和活跃事务id列表的时机,读提交在每一次查询前都会生成一次,而可重复读只会在第一次查询前生成一次。
19、为什么可重复读不能解决幻读?
答:可以解决部分幻读,事务1和事务2开启事务,事务1查询一个条件语句,事务2此时插入一条语句然后提交,事务2如果再查询是查询不到新增语句的,如果事务1更新一下这条新增的数据,然后再查询就会把新增的语句查询出来。因为更新了这条数据这条数据就有了事务1的一个id,查询的时候会获取到。
20、大表怎么优化?
答:1)对表进行分区:
语句:ALTER TABLE 表名 PARTITION BY RANGE(列名)
(PARTITION 分区名 VALUES LESS THAN (定义的值))
range按照分区列的范围将数据进行分区,查询的时候根据分区列到指定的区中去查找就好了。
list与range相似,不过list的列定义是离散的。
hash分区,对数据进行一个取余计算对应区;key差不多。
缺点:每个分区索引都是单独存放的,如果查询不走分区列的话会有过多的查询。之前B+树只用走3次,现在10个分区要走30次。
2)分库分表
分库分表就是把原来存放在一个库的表存放在多个库中,把原来存放在一张表的数据存放在多个表中,不同的库可以存放在不同的服务器,减轻单机服务器的压力,分表让一次查询的时间就变短了。
垂直切分:就是把表按照功能进行分类,分到不同表中。或者说不通功能表分到不同库中。
水平切分:将一个表中的数据按照某种规则切分成更小的表,比如根据性别划分两个表。
分库分表存在问题:范围查询,如果是按我们是按范围来划分表的话还好,但是如果不是就要从多个表中来查找相关的数据。原来一次就可以查询到的现在要查询多次。
21、MySQL执行计划了解吗?
答:用explain命令获取select语句的执行计划,可以看这次查询用到哪些索引,查询到多少行,查询类型(普通查询,联合查询,子查询等)等等。
22、mysql里的日志?
答:bin Log:用于记录数据库操作过程中的修改操作,用于恢复数据库。
redo log:用于记录事务操作的日志,当数据库发生故障,会用redo来恢复数据,是存储引擎层面的日志。redo log会在事务执行过程中写入,而binlog是在事务提交后写入。
undo log:记录数据修改的一个过程,也就是数据的历史版本,用于实现MVCC。
23、讲一些MySQL架构?
答:Server层:主要有连接器、查询缓存、分析器、优化器、执行器等,还有存储过程、触发器、视图等功能都在这层实现。
连接器—对用户进行一个身份认证和权限校验。
查询缓存—当用户执行查询的之后,先查询缓存看有没有该语句对应的数据,有就直接返回,不需要语法语义分析和执行。
分析器—用户执行语句会经过分析器,对语句进行语法分析和语义分析。
优化器—对用户查询语句进行优化,比如选择合适的索引。
执行器—根据用户执行语句调用存储引擎的接口。
存储引擎:主要负责数据的存储和读取,server通过api与存储引擎进行通信。
24、查询语句的执行流程?
答:先检查权限,看用户有没有权限执行语句;然后看查询语句在不在缓存中,如果没有命中就对语句进行语法分析,语义分析;然后优化器再看语句能不能再优化,最后调用存储引擎接口,返回执行结果。
25、更新语句的过程?
答:update
user
set
name
= ``'大彬'
where
id = 1;
先查看缓存有没有id为1的数据,没有就读取出来,从内存中更新该数据,然后更新redo log缓存,之后写入bin log,然后提交事务。
26、IN和=区别?
答:IN是是一个范围选择,比如学生id在一个集合中(1,2,3),而=是用于根据某个值查找。
27、IN和EXITS的区别?
答:IN是先子查询,从子查询里面查出来的每一行带入到外查询中去查找;EXITS则是先进行主查询,从主查询中每一行代入到子查询中,然后根据表中子查询里面条件是否成立来决定是不是保留这一行记录。
IN适合子查询记录较小,主查询记录较多且有索引;EXITS适合主查询结果较少,子查询查询结果大但又索引的情况。
二、索引
1、你知道文件索引、数据库索引一般用什么数据结构来存储吗?
答:少部分用B树,一般文件索引,大部分用B+树。可以以时间复杂度Log(n)的效率查找到数据。
2、文件索引为什么用B+树不用二叉树、哈希表?
答:从查找次数来说B树和二叉树的查找时间差不多,但是树的节点在磁盘中的存储是不连续的,磁盘中的数据是以页为单位加载到内存中的,不同节点很可能分配到不同的磁盘页中,而用B+树,一次磁盘查询就可以完全载入一个节点。
如果要进行范围查询的话,hash表也只能遍历所有数据,如果哈希碰撞太多的话,查找效率也会降低很多。对于二叉树,范围查找也要多次遍历,效率低。
3、mysql索引的分类?
答:全文索引、Hash索引、B+树索引。
4、聚集索引和非聚集索引的区别?
答:聚集索引中索引在表中的逻辑顺序与磁盘中的物理存储顺序相同,一个表中只拥有一个聚集索引。
非聚集索引中索引在表中的逻辑顺序与磁盘中的物理存储顺序不同,一个表中可以有多个非聚集索引。
5、说说聚簇索引和辅助索引?
答:聚簇索引是一种数据存储方式,主索引的叶子节点的数据域中存储了那一行完整的数据。
辅助索引的叶子节点的数据域存储的是主键的值,在使用辅助索引进行查找时,需要先找到主键值,再到主索引中去进行查找,这个过程叫回表。
6、什么是哈希索引?
答:用哈希表的存储结构来存储数据,能够以O(1)时间复杂度进行查找,但是失去了有序性,无法用于排序;只能用于精确查找,无法用于范围查找。
7.你知道最左匹配原则吗?
答:索引可以是一个列(a),也可以多个列(a,b,c,d),即联合索引,在查找的时候,先根据左边的索引列来查找的,只有当最左边那列的值相等,接着用后面那个索引来进行比较,最左匹配原则就是优先用最左边的索引去比较。当向右匹配到范围查找就会停止。
8、什么是覆盖索引?
答:在我们用辅助索引去查找数据的时候是先查找的表的主键,当我们本身要查询的内容就是主键或者这个索引字段的话就是索引覆盖,避免了回表。
9、联合索引的创建原则?
答:让选择性最强的索引列放前边,选择性最强就是不重复的索引值数量与表中数据行的比值,比如唯一索引就是的选择性就是最强的,值为1。
10、怎么知道你这条语句使用到了索引?
答:使用explain关键字加在查询语句前面,看possible_keys字段,如果为null,表示没有使用到索引。
11、索引设计的原则?
答:1)经常查询的字段要创建索引。
2)对于数据不重复的字段选择唯一索引,唯一索引可以很快的定位到对应数据。
3)经常需要排序的字段需要创建索引,因为索引已经排好序了。
4)数据量小的表最好不要用索引,还有选择性较差的字段不要用索引,比如男女;对于频繁更新的字段不要使用索引。
12、索引优化器?
答:where如果没有按定义索引顺序的话,优化器会按照最左匹配原则进行匹配。
(a,b,c)联合索引,a,b,c是完全满足最左匹配原则的,a,b部分匹配原则,b,c不使用索引。
13、什么是前缀索引?**
答:当在很长的字符列上面建立索引的时候,会造成这种索引很大并且查询很慢,用前缀索引就是用字符串的前几个字符来作为索引。
三、实战语句
1、找到所有分数大于平均分的学生的名字?student(id,name,score)
答:select name from student where score>(select avg(score) form student)
2、找到分数最高的学生名字,最高分不止一个? student(id,name,score)
答:select name from student s1,(select id from student where score in (select max(score) from student) s2 where s1.id = s2.id
思路:先找到表中的最大分数,用 in 语句找到score相等数据获取id,用=也可以。然后把查询到的id作为一个表,用来与另一个表相连接。当然这是考虑了在姓名在另外一个表的情况,这个题就一个表,所以用里面的语句就好了
select id from student where score = (select max(score) from student)