java面试④数据库部分
2.3.1 数据库的分类及常用的数据库
数据库分为:关系型数据库和非关系型数据库
关系数据库:mysql,oracle,sqlServer
非关系型:redis,mongoDB
2.3.2 简单介绍一下关系数据库三范式
范式就是规范,就是关系型数据库在设置表时,要遵循的三个规范。
要满足第二范式必须先满足第一范式,要满足第三范式必须先满足第二范式。
所谓第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体列中的某个属性不能有多个值或者不能有重复的属性,列数据的不可分割。
二范式(2NF)要求数据库表中的每个行必须可以被唯一的区分,为实现区分通常需要为表加上一列,以存储各个实例的唯一标识。(主键)
满足第三范式(3NF)必须先满足第二范式,简而言之,第三范式要求一个数据库表中不包含已在其他表中已包含的非关键字信息。(外键)
反三范式,有的时候为了效率,可以设置重复或者可以推导的字段,订单(总价)和订单项(单价)
2.3.3 事务的四个基本特征
事物是并发控制的单位,是用户定义的一个操作序列,这些操作要么都做,要么都不做,是一个不可分割的工作单位。
一个转账必须A帐号扣钱成功,B帐号加钱成功,才算真正的转账成功。
事务必须满足四大特征:
原子性:表示事务内操作不可分割,要么成功,要么都失败
一致性:要么成功,要么失败,后面的失败了要对前面的操作进行回滚
隔离性:一个事务开始后,不能与其他事务干扰
持久性(持续性):表示事务开始了,就不能终止。
2.3.4 mysql数据库的默认的最大连接数?
为什么需要最大连接数?特定服务器上面的数据库只能支持一定数目同时连接,这时候需要我们设置最大连接数(最多同时服务多少连接),在数据库安装时都会有一个默认的最大连接数。最大连接数为100.
max_connections=100;
2.3.5 说一下mysql的分页?Oracle的分页?
为什么需要分页?在很多数据库时,不可能完全显示数据,进行分段显示。
mysql是使用关键字limit 来进行分页的,limit offset,size 表示从多少索引取多少位。
Oracle的分页。大部分情况下,我们是记不住了,说思路,要使用三层嵌套查询
oracle的分页优点记不住了,只记得一些大概,是使用类三层嵌套查询,如果在工作中使用了,可以到原来的项目中拷贝或上网查询。
sqlserver的是top
- --top not in方式
- select top 条数 * from tablename
- where Id not in (select top 条数*页数 Id from tablename)
2.3.6 简单讲一下数据库的触发器的使用场景
触发器,需要触发条件,当条件满足以后做什么操作。
触发器用处还是很多的,比如校内网、Facebook,你发一个日志,自动通知好友,其实就是在增加日志做一个后触发,再向通知表中写入条目,因为触发效率高,而UCH没有用触发器,效率和数据处理能力很低。
每插入一个帖子,都希望将版面表中的最后发帖时间,帖子数字段进行同步更新,用触发器做效率更高。
关键字:trigger
2.3.7 简单讲一下数据库的存储过程的使用场景?
数据库存储过程具有如下优点:
1)存储过程只在创建时进行编译,以后每次执行存储过程都不需要重新编译,而一般SQL语句每执行一次就编译一次,因此使用存储过程可以大大提高数据执行数度,
2)通常,复杂的业务逻辑需要多条SQL语句,这些语句要分别地从客户端发送到服务器,当客户端和服务器之间的操作很多时,将产生大量的网络传输,如果将这些操作放在一个存储过程中,那么客户机和服务器之间的网络传输就会大大减少,降低类网络负载,
3)存储过程创建一次便可以重复使用,从而可以减少数据库开发人员的工作量,
4)安全性高,存储过程可以屏蔽对底层数据库对象的直接访问,使用exectu权限调用存储过程,无需拥有访问底层数据库对象的显示权限。
定义存储过程:
create procedure studen(name varchar(50),age int,id in);
begin
insert into student values('lisi',22,1);
select name,age from student;
end;
调用存储过程
call student();
2.3.8 用jdbc怎么调用存储过程?
加载驱动
获取连接
设置参数
执行
释放连接
public static void main(String[]args) { Connection conn = null; CallableStatement st = null; try { //这里最好不要这么干,因为驱动名写死在程序中了 Class.forName("com.mysql.jdbc.Driver"); //实际项目中,这里应用DataSource数据,如果用框架 //这个数据源不需要我们编码创建,我们只需DataSourceds=context.lookup(); //conn = ds.getConnection(); conn = DriverManager.getConnection("jdbc:mysql:///test","root","root"); st = conn.prepareCall("{call insert_Student(?,?,?)}"); st.registerOutParameter(3, Types.INTEGER); st.setString(1, "laowang"); st.setInt(2, 25); st.execute(); //get第几个,不同的数据库不一样,建议不写 System.out.println(st.getString(3)); } catch(Exception e){ e.printStackTrace(); } } |
2.3.9 常用的SQL
略
2.3.10 简单说一下你对jdbc的理解
Java database connection java数据库连接,数据库关系系统(mysql,oracle)是很多,每个数据库管理系统支持的命令是不一样的,
java只定义接口,让数据库厂商自己实现接口,对于我们而言只需要导入对应厂商开发的实现接口,然后以接口方式进行调用(mysql+mysql驱动+jdbc)
2.3.11 写一个简单的jdbc的程序,写一个访问oracle数据库的jdbc程序?
加载驱动(oracle.jdbc.driver.OracleDriver)
获取连接(DriverManager.getConnection(url, user, password))
设置参数
Statement st = conn.createStatement();
st.setXXX(index,value)
执行(execute)
释放连接(是否连接要从小到大,必须放到finally)
2.3.12 JDBC中的PreparedStatement相比Statement的好处
大多数时候都使用PreparedStatement代替
1)PreparedStatement是预编译的,比Statement速度快
2)代码的可读性和可维护性
虽然PreparedStatement来代替Statement会使代码多出几行,但这样的代码无论从可读性还是可维护性上来说,都比直接用Statement的代码高很多档次。
stmt.executeUpdate("insert into tb_name (col1,col2,col2,col4) values ('"+var1+"','"+var2+"',"+var3+",'"+var4+"')");
perstmt = con.prepareStatement("insert into tb_name (col1,col2,col2,col4) values (?,?,?,?)");
perstmt.setString(1,var1);
perstmt.setString(2,var2);
perstmt.setString(3,var3);
perstmt.setString(4,var4);
perstmt.executeUpdate();
不用我多说,对于第一种方法.别说其他人去读你的代码,就是你自己过一段时间再去读,都会觉得伤心.
3)安全性
PreparedStatement可以防止SQL注入攻击,而Statement却不能,比如:
String sql = "select * from tb_name where name= '"+varname+"' and passwd='"+varpasswd+"'";
如果我们把[' or '1' = '1]作为varpasswd传入进来.用户名随意,看看会成为什么?
select * from tb_name = '随意' and passwd = '' or '1' = '1';
因为'1'='1'肯定成立,所以可以任何通过验证.更有甚者:
把[';drop table tb_name;]作为varpasswd传入进来,则:
select * from tb_name = '随意' and passwd = '';drop table tb_name;有些数据库是不会让你成功的,但也有很多数据库就可以使这些语句得到执行.
而 如果你使用预编译语句.你传入的任何内容就不会和原来的语句发生任何匹配的关系.(前提是数据库本身支持预编译,但上前可能没有什么服务端数据库不支持编 译了,只有少数的桌面数据库,就是直接文件访问的那些)只要全使用预编译语句,你就用不着对传入的数据做任何过虑.而如果使用普通的statement, 有可能要对drop,;等做费尽心机的判断和过虑.
2.3.13 数据库连接池的作用
1)限定数据库的个数,不会导致由于数据库过多导致系统运行缓慢或者崩溃。
2)数据库连接池不需要每次创建或者销毁,节约资源。
3)数据库连接池不需要每次创建,响应时间快。