博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据库常见面试题解析
阅读量:2390 次
发布时间:2019-05-10

本文共 7153 字,大约阅读时间需要 23 分钟。

文章目录

数据库的分类及常用的数据库

数据库分为:关系型数据库和非关系型数据库

  • 关系型:mysql oracle sqlserver等
  • 非关系型:redis,memcache,mogodb,hadoop等

关系型数据库

Mysql选用B+树这种数据结构作为索引,可以提高查询索引时的磁盘IO效率,并且可以提高范围查询的效率,并且B+树里的元素也是有序的。

简单介绍一下关系数据库三范式?

范式就是规范,就是关系型数据库在设计表时,要遵循的三个规范。

要想满足第二范式必须先满足第一范式,要满足第三范式必须先满足第二范式。

  • 第一范式(1NF)列数据的不可分割(原子性)
  • 二范式(2NF)主键
  • 第三范式: 要求一个数据库表中不包含已在其它表中的非主关键字信息。(外键)
  • 反三范式,有的时候为了效率,可以设置重复或者可以推导出的字段.
    订单(总价)和订单项(单价)

事务四个基本特征或 ACID 特性。

事务是并发控制的单位,是用户定义的一个操作序列。这些操作要么都做,要么都不做,是一个不可分割的工作单位。

原子性Atomic 事务内操作不可分割要么…要么…

一致性Consistency 数据的完整性必须保持一致(转账)后面失败了要对前面的操作进行回滚
隔离性 Isolation 一个事务开始,其他事务无法干扰
持久性 Durability 事务开始 不能终止

InnoDB对事务的实现方式

利用回滚日志(undo log) 和 重做日志(redo log) 两种表实现事务,并实现 MVCC (多版本并发控制);

查询需要对资源加共享锁(S),数据修改需要对资源加排他锁(X)

利用undo log使读写不阻塞,实现了可重复读。当一个事务正在对一条数据进行修改时,该资源会被加上排它锁。在事务未提交时对加锁资源进行读操作时,读操作无法读到被锁资源,通过一些特殊的标志符去读undo log 中的数据(过程很复杂),这样读到的都是事务执行之前的数据。

mysql数据库的默认的最大连接数?

my.ini

在这里插入图片描述

说一下msyql的分页?Oracle的分页?

为什么需要分页?在很多数据是,不可能完全显示数据。进行分段显示.

Mysql是使用关键字limit来进行分页的 limit offset,size 表示从多少索引去多少位.

String sql = 	"select * from students order by id limit " + pageSize[每页显示]*(pageNumber-1)[多少页] + "," + pageSize;

Oracle的分页,要使用三层嵌套查询(百度)。

String sql = 	 "select * from " +  	 (select *,rownum rid from (select * from students order by postime desc) where rid<=" + pagesize*pagenumber + ") as t" + 	 "where t>" + pageSize*(pageNumber-1);

简单讲一下数据库的触发器的使用场景?

简单讲一下数据库的存储过程的使用场景?

用jdbc怎么调用存储过程?

加载驱动

获取连接
设置参数
执行
释放连接

常用SQL

简单说一下你对jdbc的理解?

Java database connection

Java只定义接口,让数据库厂商自己实现接口,对于我们者而言。只需要导入对应厂商开发的实现即可。然后以接口方式进行调用.(mysql + mysql驱动(实现)+jdbc)

写一个简单的jdbc的程序。写一个访问oracle数据的jdbc程序?

加载驱动(com.mysql.jdbc.Driver,oracle.jdbc.driver.OracleDriver)获取连接(DriverManager.getConnection(url,usernam,passord))设置参数  Statement PreparedStatement            cstmt.setXXX(index, value);执行   executeQuery executeUpdate释放连接(是否连接要从小到大,必须放到finnaly)

JDBC中的PreparedStatement相比Statement的好处

1:PreparedStatement是预编译的,比Statement速度快

2:代码的可读性和可维护性
虽然用PreparedStatement来代替Statement会使代码多出几行,但这样的代码无论从可读性还是可维护性上来说.都比直接用Statement的代码高很多档次:
3:安全性
PreparedStatement可以防止SQL注入攻击,而Statement却不能。

数据库连接池作用

1、限定数据库的个数,不会导致由于数据库连接过多导致系统运行缓慢或崩溃

2、数据库连接不需要每次都去创建或销毁,节约了资源
3、数据库连接不需要每次都去创建,响应时间更快。

InnoDB、Mysaim的特点?

innoDB是默认的数据库存储引擎(支持高并发[写])行锁

外键
事务
行表锁
缓存
Mysaim读快
两种类型都有⾃⼰优缺点,选择那个完全要看⾃⼰的实际类弄。

⾏锁,表锁;乐观锁,悲观锁,共享锁,排它锁?

a. ⾏锁:数据库表中某⼀⾏被锁住。

b. 表锁:整个数据库表被锁住。
c. 乐观锁:顾名思义,就是很乐观,每次去拿数据的时候都认为别⼈不会修改,具体实现是给表增加⼀个版本号的字
段,在执⾏update操作时⽐较该版本号是否与当前数据库中版本号⼀致,如⼀致,更新数据,反之拒绝。
d. 悲观锁:顾名思义,就是很悲观,每次去拿数据的时候都认为别⼈会修改。读数据的时候会上锁,直到update完成才
释放锁,使⽤悲观锁要注意不要锁住整个表。
读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会互相影响。
写锁(排它锁):当前写操作没有完成前,它会阻断其他写锁和读锁。

数据库隔离级别

常看当前数据库的事务隔离级别:show variables like 'tx_isolation';

在这里插入图片描述
这就是事务还没提交,而别的事务可以看到他其中修改的数据的后果,也就是脏读。
可重复读虽然读取同一条数据可以保证一致性,但是却不能保证没有插入新的数据

MySQL主从复制的基本原理。

1、master将改变记录到⼆进制⽇志(binary log)中(这些记录叫做⼆进制⽇志事件,binary log events,可以通过show

binlog events进⾏查看);
2、slave将master的binary log events拷⻉到它的中继⽇志(relay log);
3、slave重做中继⽇志中的事件,将改变反映它⾃⼰的数据。
在这里插入图片描述

select * from table t where size > 10 group by size order by size的sql语句执⾏顺序?

sql语句执⾏顺序如下:

where -> group by -> having -> select -> orderby

数据库事务的⼏种粒度;

a. 表锁定:对整个表的锁定。

b. ⾏锁定:只锁定进⾏更改的⾏,例如:insert,update,delete,都隐式采⽤⾏锁定。
c. 数据库锁机制可分为多种粒度的: 数据库,表,⻚⾯,⾏
d. 粒度越⼤,DBMS管理越容易,但是实现并发处理的能⼒就越差,表,⻚⾯,⾏

mysql调优:

定位:查找、定位慢查询

a) 创建索引:创建合适的索引,我们就可以现在索引中查询,查询到以后直接找对应的记录。
b) 分表 :当一张表的数据比较多或者一张表的某些字段的值比较多并且很少使用时,采用水平分表和垂直分表来优化
c) 读写分离:当一台服务器不能满足需求时,采用读写分离的方式进行集群。
d) 缓存:使用redis来进行缓存
e) 一些常用优化技巧(遵循范式,选择合适的存储引擎)

a. explain select语句;

b. 当只要⼀条数据时使⽤limit 1;
c. 为搜索字段建索引;
d. 避免select *;
e. 字段尽量使⽤not null;
f. 垂直分割;
g. 拆分⼤的delete和insert语句:delete和insert会锁表;
h. 分表分库分区。

mysql索引结构

BTree索引

在这里插入图片描述
B+Tree索引
在这里插入图片描述
B+Tree(指针)与B-Tree 的区别

 1)B-树的关键字和记录是放在一起的,叶子节点可以看作外部节点,不包含任何信息;B+树的非叶子节点中只有关键字和指向下一个节点的索引,记录只放在叶子节点中。  2)在B-树中,越靠近根节点的记录查找时间越快,只要找到关键字即可确定记录的存在;而B+树中每个记录的查找时间基本是一样的,都需要从根节点走到叶子节点,而且在叶子节点中还要再比较关键字。从这个角度看B-树的性能好像要比B+树好,而在实际应用中却是B+树的性能要好些。因为B+树的非叶子节点不存放实际的数据,这样每个节点可容纳的元素个数比B-树多,树高比B-树小,这样带来的好处是减少磁盘访问次数。尽管B+树找到一个记录所需的比较次数要比B-树多,但是一次磁盘访问的时间相当于成百上千次内存比较的时间,因此实际中B+树的性能可能还会好些,而且B+树的叶子节点使用指针连接在一起,方便顺序遍历(例如查看一个目录下的所有文件,一个表中的所有记录等),这也是很多数据库和文件系统使用B+树的缘故。  思考:为什么说B+树比B-树更适合实际应用中操作系统的文件索引和数据库索引? 1) B+树的磁盘读写代价更低   B+树的内部结点并没有指向关键字具体信息的指针。因此其内部结点相对B 树更小。如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多。相对来说IO读写次数也就降低了。 2) B+树的查询效率更加稳定   由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。

聚簇索引与非聚簇索引

聚簇索引并不是一种单独的索引类型,而是一种数据存储方式。
术语‘聚簇’表示数据行和相邻的键值聚簇的存储在一起。
如下图,左侧的索引就是聚簇索引,因为数据行在磁盘的排列和索引排序保持一致。
在这里插入图片描述

聚簇索引的好处:按照聚簇索引排列顺序,查询显示一定范围数据的时候,由于数据都是紧密相连,数据库不不用从多个数据块中提取数据,所以节省了大量的io操作。聚簇索引的限制:对于mysql数据库目前只有innodb数据引擎支持聚簇索引,而Myisam并不支持聚簇索引。由于数据物理存储排序方式只能有一种,所以每个Mysql的表只能有一个聚簇索引。一般情况下就是该表的主键。

为了充分利用聚簇索引的聚簇的特性,所以innodb表的主键列尽量选用有序的顺序id,而不建议用无序的id,比如uuid这

如何优化数据库性能(索引、分库分表、批置操作、分⻚算法、升级硬盘SSD、业务优化、主从部署)

1、选择合适的数据库引擎,合理使⽤索引

2、分⻚获取数据,只获取需要的字段
3、优化业务逻辑,减少数据库IO
4、分库分表
5、部署主从数据库
6、升级硬件

SQL什么情况下不会使⽤索引(读)(不包含,不等于,函数)

a. select * 可能导致不⾛索引;

b. 空值会导致不⾛索引,因为hashset不能存空值;
c. 索引列有函数运算,不⾛索引,可以在索引列建⽴⼀个函数的索引。
d. 隐式转换可能导致不⾛索引;
e. 表的数据库⼩或者需要选择⼤部分数据,不⾛索引;
f. !=或者<>可能导致不⾛索引;
g. 字符型的索引列会导致优化器认为需要扫描索引⼤部分数据且聚簇因⼦很⼤,最终导致弃⽤索引扫描⽽改⽤全表扫描
⽅式
h. like ‘%liu’ 百分号在前不⾛索引;
i. not in, not exist不⾛索引;

—般在什么字段上建索引(过滤数据最多的字段)

1、表的主键、外键必须有索引;

2、数据量超过300的表应该有索引;
3、经常与其他表进⾏连接的表,在连接字段上应该建⽴索引;
4、经常出现在Where⼦句中的字段,特别是⼤表的字段,应该建⽴索引;
5、索引应该建在选择性⾼的字段上;
6、索引应该建在⼩字段上,对于⼤的⽂本字段甚⾄超⻓字段,不要建索引;

mysql存储引擎中索引的实现机制;

查找慢查询并定位慢查询?

在项目自验项目转测试之前,在启动mysql数据库时开启慢查询,并且把执行慢的语句写到日志中,在运行一定时间后。通过查看日志找到慢查询语句。

1、关闭数据库服务器(关闭服务)
2、把慢查询记录到日志中
在这里插入图片描述
3、设置慢查询时间
在这里插入图片描述
4.找出日志中的慢查询SQL
使用explain 慢查询语句,来详细分析语句的问题
在这里插入图片描述

索引使用小技巧?

1. 对于创建的多列索引(复合索引),不是使用的第一部分就不会使用索引。alter table dept add index my_ind (dname,loc); // dname 左边的列,loc就是右边的列explain select * from dept where dname='aaa'\G 会使用到索引explain select * from dept where loc='aaa'\G 就不会使用到索引2. 对于使用like的查询,查询如果是’%aaa’不会使用到索引而‘aaa%’会使用到索引。   explain select * from dept where dname like '%aaa'\G不能使用索引   explain select * from dept where dname like 'aaa%'\G使用索引.所以在like查询时,‘关键字’的最前面不能使用 % 或者 _这样的字符.,如果一定要前面有变化的值,则考虑使用 全文索引->sphinx.3. 如果条件中有or,有条件没有使用索引,即使其中有条件带索引也不会使用。换言之,就是要求使用的所有字段,都必须单独使用时能使用索引.   4. 如果列类型是字符串,那一定要在条件中将数据使用引号引用起来。否则不使用索引。expain select * from dept where dname=’111’;expain select * from dept where dname=111;(数值自动转字符串)expain select * from dept where dname=qqq;报错也就是,如果列是字符串类型,无论是不是字符串数字就一定要用 ‘’ 把它包括起来.5. 如果mysql估计使用全表扫描要比使用索引快,则不使用索引。   表里面只有一条记录

数据库优化之分表?

水平分表策略:	1.按时间分表 这种分表方式有一定的局限性,当数据有较强的实效性,如微博发送记录、微信消息记录等,这种数据很少有用户会查询几个月前的数据,如就可以按月分表。	2.按区间范围分表 一般在有严格的自增id需求上,如按照user_id水平分表:	table_1  user_id从1~100w 	table_2  user_id从101~200w 	table_3  user_id从201~300w 	3.hash分表***** 通过一个原始目标的ID或者名称通过一定的hash算法计算出数据存储表的表名,然后访问相应的表。

语句优化小技巧

DDL优化:

1 、通过禁用索引来提供导入数据性能 。 这个操作主要针对有数据库的表,追加数据
//去除键
alter table test3 DISABLE keys;
//批量插入数据
insert into test3 select * from test;
//恢复键
alter table test3 ENABLE keys;

2、 关闭唯一校验

set unique_checks=0 关闭
set unique_checks=1 开启

3、修改事务提交方式(导入)(变多次提交为一次)

set autocommit=0 关闭
//批量插入
set autocommit=1 开启

DML优化(变多次提交为一次)

insert into test values(1,2);
insert into test values(1,3);
insert into test values(1,4);
//合并多条为一条
insert into test values(1,2),(1,3),(1,4)

1)在表没有主键时,count(1)比count(*)快;

2)有主键时,主键作为计算条件,count(主键)效率最高;

3)若表格只有一个字段,则count(*)效率较高。

非关系型数据库

有没有使用过redis? Redis是什么

key-value的nosql数据库

做缓存数据库的数据和web集群时当做中央缓存存放seesion
单线程 + 多路IO复用.

Redis五大数据类型

Redis持久化

Redis主从复制

哨兵模式

心跳检测假死的master

转载地址:http://jtxab.baihongyu.com/

你可能感兴趣的文章
利用Vertex shader实现Point Sprites
查看>>
图形处理器历史简介
查看>>
System Memory,AGP Memory and Video Memory in D3D.
查看>>
使用辅助库建立openGL编程环境
查看>>
使用Win32API开始openGL编程
查看>>
使用MFC开始openGL编程
查看>>
关于Gbuffer中的normal存储
查看>>
近距离观察Tone mapping.
查看>>
Physically based shading
查看>>
Color correction
查看>>
Temporal AA
查看>>
miniz compared to other real-time and high-ratio compressors
查看>>
Random number for GPU
查看>>
SSR
查看>>
引擎核心架构
查看>>
[转]关于现代CPU,程序员应当更新的知识
查看>>
游戏设计架构的一种方法
查看>>
FMOD音频引擎简单使用
查看>>
作为一名SAP从业人员,需要专门学习数学么
查看>>
周伯通的空明拳,米诺斯的星尘傀儡线,SAP Kyma的Serverless
查看>>