java面试 数据库

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

关系型数据库:mysql oracle sqlserver
非关系型数据库:redis mogodb hadoop

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

第一范式(原子性)   是指数据库表的每一属性都是不可分割的
					(例如“联系方式”可细分为“QQ”“E-mail”)
第二范式(完全依赖) 要求数据库表中的每个行必须可以被唯一地区分,
					存储各个实例的唯一标识[主键]

第三范式(非传递依赖) 不存在这样X->Y,Y->Z的成立,则符合第三范式

事务四个基本特征(ACID)

事务四大特征:原子性,一致性,隔离性,持久性

原子性:表示事务内操作不可分割,要么都成功,要么都失败/要么执行,要么不执行
一致性:要么成功要么失败,失败了要对前面的操作进行回滚/事务前后,数据总额一致
隔离性:一个事务开始后,不能被其他事务干扰/所有操作全部执行完以前,其他会话不能看到过程
持久性:表示事务开始了,就不能终止/事务一旦提交,对数据的该表就是永久

数据库的事务隔离级别

读未提交		-脏读问题
读已提交		-不可重复读问题
重复读		-幻读问题
串行化		-无

索引有B索引和hash索引

hash索引,等值查询效率高,不能排序,不能进行范围查询
B索引,数据有序,可进行范围查询

left join,right join,inner join 有什么区别

left join 以左表为主,显示左表全部数据
right join 以右表为主,
inner join 显示2张表的全部数据

Redis持久化存储方式有哪几种

RDB:以快照的形式保存,定期保存快照,适合大规模数据恢复,数据完整性和一致性差
AOF:将写操作日志追加到AOF文件中,数据完整性高,恢复速率慢

Redis集群模式有哪几种

主从集群:主要为了高可用或读写分离,单向链表结构
分布式集群:数据分片储存,扩展单击内存上限,网状结构

Redis分布式锁怎么实现

使用setnx命令同时加上过期时间,以当前请求ID为value
(释放锁的时候可以校验是否是当前持有者,防止其他线程无意中释放了锁)
伪代码:
Long result = jedis.setnx(lockKey,requestId,expireTime);
return result ==1;

redis支持的数据类型

String:
Hash
Set 
List
Sorted Set

mysql数据库主从同步延迟原理

mysql主库的DDL和DML会产生binlog日志,从库读取主库的binlog然后在从库实施,
从库的同步线程是单线程,如果其中一个执行卡住了,后面的操作都会等待,造成延迟
另外还有就是同步操作和slave的大型query语句产生了锁等待

mysql如何解决主从同步延时问题

1、从库设置 sync_binlog=0 让系统觉得什么时候同步到磁盘
2、innodb_flush_log_at_trx_commit 设置成0或2
(0 延迟写,实时刷新到硬盘,1 实时写 实时刷新到硬盘,2 实时写,延迟刷新到硬盘)
3、提高从库的硬件性能
4、提高数据库版本到mysql5.6.3以上,支持多线程同步

数据索引新建原则

1、具有唯一性的属性必须增加唯一约束,与唯一索引
2、经常出现在where子句中的查询条件需要增加索引
3、如果属性为大文本不要增加索引
4、字符串类型的索引需要指定长度,尽量使用前缀来增加索引
5、经常被join联合的外键需要增加索引
6、一张表不要有太多索引
7、索引尽量在区分度比较高的属性上
8、不经常使用的索引需要删除

redis的哨兵模式

主要功能有:
1、redis集群的监控
2、如果发现某个redis节点运行出现状况,能够通知另外一个进程
3、如果master挂掉能够自动切换,选举出一个slave来代替master

分布式事务怎么实现?

二阶段提交
事务参与者向协调者发送确认请求,当协调者收到所有参与者都同意提交之后,
则给所有参与者发送提交信息,否则发送回滚信息

三阶段提交
第一阶段:协调者先发送请求给参与者询问是否可以执行事务,参与者给出预估回答
第二阶段:协调者根据第一阶段返回值判断是否会向所有参与者发送事务执行请求,
		如果第一阶段全部返回确定消息,则发送提交请求
第三阶段:如果第二阶段都返回正确信息,则向参与者发送commit,提交等待结果

数据库的分表策略有哪些

横线划分:某一张表的属性太多,可以拆分出来2张表,一张表保存热数据(需要经常修改)
		一张保存冷数据(查询较多)
水平拆分:表单数据量过大,达到单表上限

redis具体用来存储哪些数据

1、热点数据
2、分布式session的解决方案
3、整表数据缓存
4、简单的发布订阅,延时队列

redis怎么获取一个有过期时间的剩余时间

ttl 当key不存在返回-2,key存在但是没有设置剩余时间时,返回-1,否则按秒为但会返回剩余时间
pttl 按毫秒为单位返回key的剩余时间

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

100	
	
为什么需要最大连接数?
特定服务器上面数据库只能支持一定数量的连接,这时候一般设置最大连接数

mysql分页?Oracle分页?

mysql:
	String sql = "select * from students order by id limit"+
				pageSize*(pageNumber-1)+","+pageSize*pagenumber;
oracle:
	String sql = 	select *
					from (select rownum r,e1.*
							from (select * from emp order by sal) e1
							where r<=pageSize*pagenumber
							)		
					where r>pageSize*(pageNumber-1)	

数据库的触发器的使用场景

比如:校内网,你发一个日志,自动通知好友,其实就是增加日志时做一个后触发,
再向通知表中写入条目

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

数据库存储过程有如下优点

1、存储过程只在创建时进行编译,以后每次执行存储过程都不需再重新编译
	而一般SQL语句每执行一次就编译一次,因此使用存储过程可大大提高数据库执行速度
2、复杂的业务逻辑需要多条SQL语句。这些语句要分别地从客户机发送到服务器,
	当客户机和服务器之间的操作很多时,将产生大量的网络传输。
	如果将这些操作放在存储过程,那么客户机和服务器之间的网络传输大大减少,降低网络负载
3、存储过程创经济一次便可以重复使用,从而减少数据库开发人员的工作量
4、安全性高,存储过程可以屏蔽对底层数据库对象的直接访问,
	使用EXECUTE权限调用存储过程,无需拥有访问底层数据库对象的显式权限

用jdbc怎么调用存储过程

加载驱动 获取连接 设置参数 执行 释放连接

简单说一下你对jdbc的理解

java database connection java数据库连接。
数据库管理系统(mysql Oracle)是很多,每个数据库管理系统支持的命令是不一样的

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

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

加载驱动(com.mysql.jdbc.Driver,oracle.jdbc.driver.OracleDeiver)
获取连接(DriverManager.getConnection(url,username,password))
设置参数 Statement PreparedStatement 
		cstmt.setXXX(index,value);
执行 	executeQuery executeUpdate
释放连接	释放连接从小到大,放在finally之后

JDBC中的PreparedStatement相比Statemrnt的好处

1、PreparedStatement是预编译的,比Statement速度快
2、代码的可读性和可维护性
3、安全性 PreparedStatement可以防止SQL注入攻击,而Statement却不能

数据库库连接池的作用

1、限制数据库的个数,不会导致由于数据库连接过多导致系统运行缓慢
2、数据库连接不需要每次创建销毁
3、数据库连接不需要每次去创建,响应时间更快

加载驱动的三种方法

加载驱动方法

1、调用方法Class.forName
	Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
2、通过registerDriver方法注册
	DriverManager.registerDriver(new com.mysql.jdbc.Driver());
3、通过添加系统的jdbc.drivers属性
	System.setProperty("jdbc.drivers", "com.mysql.jdbc.Driver");

什么样的属性适合创建索引?

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

什么是RMI?

java远程方法调用(java RMI)是java API对远程过程调用提供的面向对象的等价形式,

RMI体系结构的基本原则是什么

RMI体系结构是基于一个非常重要的行为定义和行为实现相分离的原则。
RMI允许定义行为的代码和实现行为的代码相分离,并且运行在不同的JVM上

数据库优化

1、索引	(唯一、不为空、经常被查询)
2、分库分表分区	(分库 频繁查询和频繁修改的库分开 
				分表 分为历史表和实时表 mycat分表
				分区 将自定义的相应规则数据放在一起)
3、数据库引擎 (常用的 innodb myisam)
4、预处理	
5、mysql like查询
6、读写分离

索引是什么

索引是帮助高效获取数据的数据结构,索引也可能是个文件

数据库为什么用B+树,不用hash 二叉树 红黑树

hash不能进行范围查询
二叉树深度太大,查询速度慢
红黑树可以控制深度,但数据太大,深度也会变深
B+树可以保持深度在3~5的范围内,是用叶子节点存数据

B树和B+树的区别

B树每个节点都存数据,B+树只有叶子节点存数据
B+树的数据以链表的形式存储

myisam

myd是用来存储是数据,myi是存储索引,frm文件存储表,非聚集索引

innodb

idb的以主键为索引来组织数据,
如果没有主键,它会自动帮你找个符合规范(6位长整型)的主键,如果找不到,则会新建一个字段当主键
聚集索引

聚集索引和非聚集索引

聚合索引例子:innodb,索引都在idb文件内,找不是主键的索引,会创副索引,根据副索引找主键索引
非聚集索引:myisam,文件数据和索引不是同一文件中,索引中存放的是地址

为什么要用自增id做主键

从插入层面来看,id自增做主键可以做到物理连续性最大
从查询层面看,如果用uuid查询会慢,字符串的比较比id的比较慢

什么是ORM

对象关系映射,解决面向对象和面向关系数据库存在的互不匹配的现象技术

hibernate有哪5类的核心接口

configuration接口
SessionFactory
Session
Transaction
Query和Criteria

什么是重量级,轻量级

轻量级指它的创建和销毁不需要消耗太多资源
重量级指不能随意创建和销毁它的实例,占用太多内存 

什么是视图?

视图是一种虚拟的表,具有和物理表相同的功能,可以对视图进行增删改查,对视图的修改不影响基本表

如下场景用到视图
1、不希望访问者获取整个表信息,只暴露部分字段给访问者
2、查询的数据来源于不同表,而查询者希望以统一的方式查询。

触发器的作用

触发器是一种特殊的存储过程,主要通过事件来触发而被执行。
它可以强化约束,来维护数据的完整性和一致性
可以跟踪数据库内的操作从而不允许未经许可的更新和变化
可以联级运算

维护数据库的完整性和一致性,用触发器还是自写业务逻辑?

尽可能用约束,如,check,主键,外键,非空字段等约束,这样效率最高,也方便。
其次是使用触发器,
最后考虑的是自写业务逻辑,但麻烦,编程复杂,效率低

索引的作用?优缺点

数据库索引是一个排序的数据结构,以快速查询和更新数据库表中的数据
索引的实现使用B树或B+树

为表设置索引的代价
1、增加了数据库的存储空间,
2、插入和修改数据时要花费较多的实际

索引提高性能的优点
1、通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性
2、可以大大加快数据的检索速度
3、加速表和表之间的连接
4、在使用分组和排序子句进行数据检索时,减少查询中分组和排序的时间
5、可以在查询过程中,使用优化隐藏器,提高系统的性能

缺点
1、创建和维护索引要耗费时间
2、索引需要占用物理空间
3、插入删除和修改速度慢

应该在这些列上创建索引
1、经常搜索的列上
2、作为主键的列上
3、经常用在连接的列,主要是外键
4、在经常需要根据范围进行搜索的列上
5、经常排序的列
6、经常在where子句后的列

不应该创建索引
1、查询中很少使用的列
2、对于很少数据值的列不应该创建索引
3、对于定义为text,image,bit数据的列
4、当修改性能远远大于检索性能

drop delete truncate的区别

drop直接删掉表
truncate删除表中数据,再插入时自增长id又从1开始
delete删除表中数据,可以加where字句

1、delete执行删除每次从表中删除一行,将删除操作作为事务记录在日志中。
truncate删除行不能恢复
2、表和索引所占空间
	truncate所占用空间会恢复初始值
	delete不会减少表和索引锁占空间
	drop表锁占空间全部释放
3、drop>truncate>delete
4、truncate只能对table,delete和drop可以是table和view 
5、truncate和delete只删除数据,而drop是删除整个表
6、

mysql优化经验

1、对查询进行优化,应尽量避免全表扫描,首先考虑在where及order by涉及的列上建立索引
2、避免在where子句中使用!=或<>操作符,否则引擎将放弃使用索引而进行全表扫描
3、尽量使用数字型字段,
若只含数值信息的字段尽量不要涉及为字符型,这会降低查询和连接的性能,并会增加存储开销。
因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数组型而言只需要比较一次
4、任何地方都不要使用select * from t,用具体的字段代替*,不要返回用不到的任何字段
5、避免频繁创建和删除临时表,以减少系统资源的消耗

mysql innnDB

innoDB引擎是一个存储引擎。优点是支持兼容ACID的事务

特点:
1、具有较好的事务支持,支持4个事务隔离级别
2、行级锁定:通过索引实现,全表扫描仍然会是表锁,注意间隙锁的影响
3、读写阻塞与事务隔离级别相关
4、具有非常高效的缓存特性:缓存引擎,也能缓存数据
5、整个表和主键以Cluster方式存储,组成一颗平衡树
6、所有Secondary Index都会保存主键信息

适用场景
1、需要事务支持
2、行级锁定堆高并发有很好的适应能力,但需要确保查询是通过索引完成
3、数据更新较为频繁的场景
4、数据一致性要求较高
5、硬件设备内存较大,可以利用InnoDB较好的缓存能力来提高内存利用率,减少磁盘IO

mysql主备同步的基本原理

mysql支持单向,异步复制,复制过程中一个服务器充分当主服务器,而其它服务器当从服务器

mysql复制是基于主服务器在二进制日志中跟踪所有对数据库的更改。
因此,要进行复制,必须在主服务器上启用二进制日志。
每个从服务器从主服务器接受主服务器已经记录到日志的数据。

当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。
从服务器接受从那时起发生的任何更新,并在本机上执行相同的更新。
然后封锁并等待主服务器通知新的更新。
从服务器执行备份不会干扰主服务器,在备份过程中主服务器可以继续处理更新

JDBC如何进行事务处理

jdbc中默认事务是自动提交的,
如果要手动控制事务,必须把jdbc自动提交事务关闭
conn.setAutoCommit(false)
接下来手动提交事务
conn.commit();
conn.setAutoCommit(true);
在异常处理中回滚整个事务
conn.rollback();
finally块关闭数据库连接
conn.close();

你可能感兴趣的:(java)