数据库面试题整理.docx
- 文档编号:5632236
- 上传时间:2022-12-29
- 格式:DOCX
- 页数:16
- 大小:24.35KB
数据库面试题整理.docx
《数据库面试题整理.docx》由会员分享,可在线阅读,更多相关《数据库面试题整理.docx(16页珍藏版)》请在冰豆网上搜索。
数据库面试题整理
数据库部分
1、数据库三范式是什么?
第一范式(1NF):
字段具有原子性,不可再分。
所有关系型数据库系统都满足第一范式)数据库表中的字段都是单一属性的,不可再分。
例如,姓名字段,其中的姓和名必须作为一个整体,无法区分哪部分是姓,哪部分是名,如果要区分出姓和名,必须设计成两个独立的字段。
第二范式(2NF):
第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。
要求数据库表中的每个实例或行必须可以被惟一地区分。
通常需要为表加上一个列,以存储各个实例的惟一标识。
这个惟一属性列被称为主关键字或主键。
第二范式(2NF)要求实体的属性完全依赖于主关键字。
所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。
为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。
简而言之,第二范式就是非主属性非部分依赖于主关键字。
第三范式(3NF):
满足第三范式(3NF)必须先满足第二范式(2NF)。
简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。
所以第三范式具有如下特征:
1,每一列只有一个值
2,每一行都能区分。
3,每一个表都不包含其他表已经包含的非主关键字信息。
例如,帖子表中只能出现发帖人的id,而不能出现发帖人的id,还同时出现发帖人姓名,否则,只要出现同一发帖人id的所有记录,它们中的姓名部分都必须严格保持一致,这就是数据冗余。
2、说出一些数据库优化方面的经验?
1、关键字段建立索引。
2、使用存储过程,它使SQL变得更加灵活和高效。
3、备份数据库和清除垃圾数据。
4、SQL语句语法的优化。
5、清理删除日志。
3、union和unionall有什么不同?
UNION在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排
序运算,删除重复的记录再返回结果。
实际大部分应用中是不会产生重复的记录,最常见的是过程表与历史表UNION。
这个SQL在运行时先取出两个表的结果,再用排序空间进行排序删除重复的记录,最后返回结果集,如果表数据量大的话可能会导致用磁盘进行排序。
而UNIONALL只是简单的将两个结果合并后就返回。
这样,如果返回的两个结果集中有重复的数据,那么返回的结果集就会包含重复的数据了。
从效率上说,UNIONALL要比UNION快很多,所以,如果可以确认合并的两个结果集中不包含重复的数据的话,那么就使用UNIONALL,
4.分页语句
取出sql表中第31到40的记录(以自动增长ID为主键)
sqlserver方案1:
selecttop10*fromtwhereidnotin(selecttop30idfromtorderbyid)ordebyidsqlserver方案2:
selecttop10*fromtwhereidin(selecttop40idfromtorderbyid)orderbyiddesc
mysql方案:
select*fromtorderbyidlimit30,10
oracle方案:
select*from(selectrownumr,*fromtwherer<=40)wherer>30
分页技术(直接利用sql语句进行分页,效率最高和最推荐的)
mysql:
sql="select*fromarticleslimit"+(pageNo-1)*pageSize+","+pageSize;
oracle:
sql="select*from"+"(selectrownumr,*from"+"(select*fromarticlesorderbypostimedesc)"+"whererownum<="+pageNo*pageSize+")tmp"+"wherer>"+(pageNo-1)*pageSize;
sqlserver:
sql="selecttop10*fromidnotid(selecttop"+(pageNo-1)*pageSize+"idfromarticles)"
5.用一条SQL语句查询出每门课都大于80分的学生姓名
name
kecheng
fenshu
张三
语文
81
张三
数学
75
李四
语文
76
李四
数学
90
王五
语文
81
王五
数学
100
王五
英语
90
准备数据的sql代码:
createtablescore(idintprimarykeyauto_increment,namevarchar(20),subjectvarchar(20),scoreint);
insertintoscorevalues(null,'张三','语文',81),(null,'张三','数学',75),(null,'李四','语文',76),(null,'李四','数学',90),(null,'王五','语文',81),
(null,'王五','数学',100),
(null,'王五','英语',90);
A:
selectdistinctnamefromscorewherenamenotin(selectdistinctnamefromscorewherescore<=80)
B:
selectdistincenamet1fromscorewhere80 6.所有部门之间的比赛组合 一个叫department的表,里面只有一个字段name,一共有4条纪录,分别是a,b,c,d,对应四个球对,现在四个球对进行比赛,用一条sql语句显示所有可能的比赛组合. selecta.name,b.namefromteama,teambwherea.name 7、注册Jdbc驱动程序的三种方式 第一种方式 DriverManager.registerDriver(new com.microsoft.sqlserver.jdbc.SQLServerDriver());jdbc是使用桥的模式进行连接的。 DriverManager就是管理数据库驱动的一个类,java.sql.Driver就是一个提供注册数据库驱动的接口,而com.microsoft.sqlserver.jdbc.SQLServerDriver()是java.sql.Driver接口的一个具体实现。 第二种方式 System.setProperty("jdbc.drivers", "com.microsoft.sqlserver.jdbc.SQLServerDriver");多个驱动使用冒号分隔开,在连接时JDBC会按顺序搜索,直到找到第一个能成功连接指定URL的驱动程序。 第三种方式(推荐)Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");好处在于能够在编译时不依赖于特定的JDBC Driver库,也就是减少了项目代码的依赖性,而且也很容易改造成从配置文件读取JDBC配置,从而可以在运行时动态更换数据库连接驱动。 8、用JDBC如何调用存储过程 代码如下: packagecom.huawei.interview.lym; importjava.sql.CallableStatement;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.SQLException;importjava.sql.Types; publicclassJdbcTest{ publicstaticvoidmain(String[]args){ Connectioncn=null; CallableStatementcstmt=null; try{ //这里最好不要这么干,因为驱动名写死在程序中了 Class.forName("com.mysql.jdbc.Driver"); //实际项目中,这里应用DataSource数据,如果用框架, //这个数据源不需要我们编码创建,我们只需 Datasourceds=context.lookup() cn=DriverManager.getConnection("jdbc: mysql: ///test","root","root"); cstmt=cn.prepareCall("{callinsert_Student(? ? ? )}");cstmt.registerOutParameter(3,Types.INTEGER);cstmt.setString(1,"wangwu"); cstmt.setInt(2,25);cstmt.execute(); //get第几个,不同的数据库不一样,建议不写 System.out.println(cstmt.getString(3)); }catch(Exceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } finally { try{ if(cstmt! =null) cstmt.close(); if(cn! =null) cn.close(); }catch(SQLExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } } } 9、JDBC中的PreparedStatement相比Statement的好处 一个sql命令发给服务器去执行的步骤为: 语法检查,语义分析,编译成内部指令,缓存指令,执行指令等过程。 select*fromstudentwhereid=3----缓存--àxxxxx二进制命令 select*fromstudentwhereid=3----直接取-àxxxxx二进制命令 select*fromstudentwhereid=4----à会怎么干? 如果当初是select*fromstudentwhereid=? ----à又会怎么干? 上面说的是性能提高可以防止sql注入。 10、写一个用jdbc连接并访问oracle数据的程序代码 importjava.sql.Connection; importjava.sql.DriverManager; importjava.sql.ResultSet; importjava.sql.SQLException; importjava.sql.Statement; publicclassJDBCDemo{ publicstaticvoidmain(String[]args){ Connectionconn=null; ResultSetrs=null; try{ //加载驱动 Class.forName("oracle.jdbc.OracleDriver"); //获得连接 conn=DriverManager.getConnection("jdbc: oracle: thin: @localhost: 1521: orcl","scott","tiger"); Statementstat=conn.createStatement(); Stringsql="SELECT*FROMemp"; //执行语句获得结果集 rs=stat.executeQuery(sql); //遍历结果集 while(rs.next()){ Stringname=rs.getString("name"); System.out.println(name); } }catch(Exceptione){ e.printStackTrace(); }finally{ //关闭连接 try{ conn.close(); }catch(SQLExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } } } } 11、Class.forName的作用? 为什么要用? 按参数中指定的字符串形式的类名去搜索并加载相应的类,如果该类字节码已经被加载过,则返回代表该字节码的Class实例对象,否则,按类加载器的委托机制去搜索和加载该类,如果所有的类加载器都无法加载到该类,则抛出ClassNotFoundException。 加载完这个Class字节码后,接着就可以使用Class字节码的newInstance方法去创建该类的实例对象了。 有时候,我们程序中所有使用的具体类名在设计时(即开发时)无法确定,只有程序运行时才能确定,这时候就需要使用Class.forName去动态加载该类,这个类名通常是在配置文件中配置的,例如,spring的ioc中每次依赖注入的具体类就是这样配置的,jdbc的驱动类名通常也是通过配置文件来配置的,以便在产品交付使用后不用修改源程序就可以更换驱动类名。 12、大数据量下的分页解决方法。 答: 最好的办法是利用sql语句进行分页,这样每次查询出的结果集中就只包含某页的数据内容。 再sql语句无法实现分页的情况下,可以考虑对大的结果集通过游标定位方式来获取某页的数据。 sql语句分页,不同的数据库下的分页方案各不一样,下面是主流的三种数据库的分页sqlserver: Stringsql="selecttop"+pageSize+"*fromstudentswhereidnotin"+ "(selecttop"+pageSize*(pageNumber-1)+"idfromstudentsorderbyid)"+"orderbyid"; mysql: Stringsql="select*fromstudentsorderbyidlimit"+pageSize*(pageNumber-1)+","+pageSize; oracle: Stringsql="select*from"+(select*,rownumridfrom(select*fromstudentsorderbypostimedesc)whererid<="+pagesize*pagenumber+")ast"+"wheret>"+pageSize*(pageNumber-1); 13、用JDBC查询学生成绩单,把主要代码写出来(考试概率极大). Connectioncn=null; PreparedStatementpstmt=null; Resultsetrs=null; try { Class.forname(driveClassName); cn=DriverManager.getConnection(url,username,password); pstmt=cn.prepareStatement(“selectscore.*fromscore,student“+ “wherescore.stuId=student.idandstudent.name=? ”); pstmt.setString(1,studentName);Resultsetrs=pstmt.executeQuery();while(rs.next()) { system.out.println(rs.getInt(“subject”)+“”+ rs.getFloat(“score”)); } }catch(Exceptione){e.printStackTrace();} finally { if(rs! =null)try{rs.close()}catch(exceptione){} if(pstmt! =null)try{pstmt.close()}catch(exceptione){} if(cn! =null)try{cn.close()}catch(exceptione){} } 14、这段代码有什么不足之处? try{ Connectionconn=...;Statementstmt=...; ResultSetrs=stmt.executeQuery("select*fromtable1"); while(rs.next()){ } }catch(Exceptionex){ } 没有finally语句来关闭各个对象,另外,使用finally之后,要把变量的定义放在try语句块的外面,以便在try语句块之外的finally块中仍可以访问这些变量。 15、说出数据连接池的工作机制是什么? J2EE服务器启动时会建立一定数量的池连接,并一直维持不少于此数目的池连接。 客户端 程序需要连接时,池驱动程序会返回一个未使用的池连接并将其表记为忙。 如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建连接的数量有配置参数决定。 当使用的池连接调用完成后,池驱动程序将此连接表记为空闲,其他调用就可以使用这个连接。 实现方式,返回的Connection是原始Connection的代理,代理Connection的close方法不是真正关连接,而是把它代理的Connection对象还回到连接池中。 16、为什么要用ORM? 和JDBC有何不一样? orm是一种思想,就是把object转变成数据库中的记录,或者把数据库中的记录转变成objecdt,我们可以用jdbc来实现这种思想,其实,如果我们的项目是严格按照oop方式编写的话,我们的jdbc程序不管是有意还是无意,就已经在实现orm的工作了。 现在有许多orm工具,它们底层调用jdbc来实现了orm工作,我们直接使用这些工具,就省去了直接使用jdbc的繁琐细节,提高了开发效率,现在用的较多的orm工具是hibernate。 也听说一些其他orm工具,如toplink,ojb等。 17.主键自动增长不同数据库之间的差异 MySQL: 使用AUTO_INCREMENT关键字来执行auto-increment任务。 默认地,AUTO_INCREMENT的开始值是1,每条新纪录递增1。 要让AUTO_INCREMENT序列以其他的值起始,请使用下列SQL语法: ALTERTABLEPersonsAUTO_INCREMENT=100(创建时会自动添加一个唯一的值) SQLServer: 使用IDENTITY关键字来执行auto-increment任务,默认地,IDENTITY的开始值是1,每条新纪录递增1。 要规定"P_Id"列以20起始且递增10,请把identity改为IDENTITY(20,10)(创建时会自动添加一个唯一的值) Oracle: 必须通过sequence对创建auto-increment字段(该对象生成数字序列)。 18、sqlserver与oracle的区别: sqlserver与 oracle的区别: --1.数据类型不同。 --sqlserver的数据类型: int,smallint,char,varchar,nchar,nvarchar,ntext,datetime,smalldatetime, money,decima,float,bit…… --oracle的数据类型: number(p,s),char,varchar2,Date,LOB --2.获得当前系统时间的函数不同。 --sqlserver: getdate() --oracle: sysdate --例如: 设定日期格式的函数: to_char(sysdate,'yyy-mm-dd'); --3.在oracle中没有默认约束的说法 --sqlserver中添加默认约束: altertabletalbe_nameaddDF_table_namedefault('男')forsex; --oracle中添加默认值: altertabletable_namemodify(sexdefault('男')); --4.连接变量和字符串的方式不一样 --sqlserver中连接: 使用“+”连接,例如: print'aaaa'+@name; --oracle中连接: 使用“||”连接,例如: dbms_output.put_line('aaa'||name);---name为变量 --5.oracle没有identity自动增长列,而是使用序列实现增长 --sqlserver自动增长: 在表的主键列中可直接使用identity(1,1)实现增长 --oracle使用序列自动增长: createsequencese_id startwith1 incrementby1 --使用序列实现自动增长: se_id.nextval --6.条件语句if……else……的语法不同 --sqlserver中: if条件 begin ………… end else begin …………
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据库 试题 整理
![提示](https://static.bdocx.com/images/bang_tan.gif)