一,必背的知识点:
1、数据库三范式是什么?
第一范式(1NF):字段具有原子性,不可再分。所有关系型数据库系统都满足第一范式)
数据库表中的字段都是单一属性的,不可再分。例如,姓名字段,其中的姓和名必须作为一个整体,无法区分哪部分是姓,哪部分是名,如果要区分出姓和名,必须设计成两个独立的字段。
第二范式(2NF):
第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。
要求数据库表中的每个实例或行必须可以被惟一地区分。通常需要为表加上一个列,以存储各个实例的惟一标识。这个惟一属性列被称为主关键字或主键。
第二范式(2NF)要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。简而言之,第二范式就是非主属性非部分依赖于主关键字。
第三范式的要求如下:
满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。
所以第三范式具有如下特征:
1,每一列只有一个值
2,每一行都能区分。
3,每一个表都不包含其他表已经包含的非主关键字信息。
例如,帖子表中只能出现发帖人的id,而不能出现发帖人的id,还同时出现发帖人姓名,否则,只要出现同一发帖人id的所有记录,它们中的姓名部分都必须严格保持一致,这就是数据冗余。
2. truncate与delete的区别?(delete from table和truncatetable tablea的区别!)
truncate是DDL语言.delete是DML語言 DDL语言是自動提交的.命令完成就不可回滾.truncate的速度也比delete要快得多.
详细说明:
相同点:truncate和不带where子句的delete, 以及drop都会删除表内的数据
不同点:
1). truncate和 delete只删除数据不删除表的结构(定义)
drop语句将删除表的结构被依赖的约束(constrain),触发器(trigger),索引(index); 依赖于该表的存储过程/函数将保留,但是变为invalid状态.
2).delete语句是dml,这个操作会放到rollback segement中,事务提交之后才生效;如果有相应的trigger,执行的时候将被触发.
truncate,drop是ddl, 操作立即生效,原数据不放到rollbacksegment中,不能回滚. 操作不触发trigger.
3).delete语句不影响表所占用的extent, 高水线(highwatermark)保持原位置不动
显然drop语句将表所占用的空间全部释放
truncate 语句缺省情况下见空间释放到 minextents个 extent,除非使用reuse storage; truncate会将高水线复位(回到最开始).
4).速度,一般来说: drop> truncate >delete
5).安全性:小心使用drop 和truncate,尤其没有备份的时候.否则哭都来不及
使用上,想删除部分数据行用delete,注意带上where子句. 回滚段要足够大.
想删除表,当然用drop
想保留表而将所有数据删除. 如果和事务无关,用truncate即可. 如果和事务有关,或者想触发trigger,还是用delete.
3 . 对数据库的访问是怎么实现的
将对持久层数据库的基本添加,修改,查找等操作提取到BaseDAO中,采用JavaBean对数据进行封装,以便对持久层的数据能够很好的处理,实现BaseDAO设计对数据库访问的便捷。业务组件通过DAO 的委托接口调用DAO对象,使得上层组件不 直接依赖于DAO的实现类.
二、说出一些数据库优化方面的经验
1.用PreparedStatement一般来说比Statement性能高:一个sql 发给服务器去执行,涉及步骤:语法检查、语义分析, 编译,缓存
2.有外键约束会影响插入和删除性能,如果程序能够保证数据的完整性,那在设计数据库时就去掉外键。(比喻:就好比免检产品,就是为了提高效率,充分相信产品的制造商)
3.看mysql帮助文档子查询章节的最后部分,例如,根据扫描的原理,下面的子查询语句要比第二条关联查询的效率高:
1). select e.name,e.salary where e.managerid=(select id from employee wherename='zxx');
2.) select e.name,e.salary,m.name,m.salary from employees e,employees mwhere
e.managerid = m.id and m.name='zxx';
一句话:
建立主键,为数据库创建索引,建立存储过程,触发器,可提高查询速度。
三,一些复杂的sql查询语句
多找题目练习
1、注册Jdbc驱动程序的三种方式
1).Class.forName("com.mysql.jdbc.Driver");
2).DriverManager.registerDriver(new com.mysql.jdbc.Driver());
3).System.setProperty("jdbc.drivers","com.mysql.jdbc.Driver");
2、JDBC中的PreparedStatement相比Statement的好处
关系:PreparedStatement继承自Statement,都是接口区别:PreparedStatement可以使用占位符,是预编译的,批处理比Statement效率高
详解:
1)、PreparedStatement:表示预编译的 SQL 语句的对象。
接口:public interface PreparedStatement extends Statement之间的继承关系
SQL 语句被预编译并存储在 PreparedStatement 对象中。然后可以使用此对象多次高效地执行该语句。
注:用于设置 IN 参数值的设置方法(setShort、setString 等等)必须指定与输入参数的已定义 SQL 类型兼容的类型。例如,如果 IN 参数具有 SQL 类型 INTEGER,那么应该使用 setInt 方法,问号的位置也是应该注意的,因为第一个问好的位置为1,第二个问号的位置为2.以此类推。
2)、Statement:用于执行静态 SQL 语句并返回它所生成结果的对象。
接口:public interface Statement extends Wrapper
在默认情况下,同一时间每个 Statement 对象只能打开一个 ResultSet 对象。因此,如果读取一个 ResultSet 对象与另一个交叉,则这两个对象必须是由不同的 Statement 对象生成的。如果存在某个语句的打开的当前 ResultSet 对象,则 Statement 接口中的所有执行方法都会隐式关闭它。
3. 写一个用jdbc连接并访问oracle数据的程序代码
4、Class.forName的作用?为什么要用?
答:按参数中指定的字符串形式的类名去搜索并加载相应的类,如果该类字节码已经被加载过,则返回代表该字节码的Class实例对象,否则,按类加载器的委托机制去搜索和加载该类,如果所有的类加载器都无法加载到该类,则抛出ClassNotFoundException。加载完这个Class字节码后,接着就可以使用Class字节码的newInstance方法去创建该类的实例对象了。
有时候,我们程序中所有使用的具体类名在设计时(即开发时)无法确定,只有程序运行时才能确定,这时候就需要使用Class.forName去动态加载该类,这个类名通常是在配置文件中配置的,例如,spring的ioc中每次依赖注入的具体类就是这样配置的,jdbc的驱动类名通常也是通过配置文件来配置的,以便在产品交付使用后不用修改源程序就可以更换驱动类名。
5、用 JDBC 查询数据题型, 把主要代码写出来(考试概率极大).
Connection cn = null;
PreparedStatement pstmt =null;
Resultset rs = null;
try
{
Class.forname(driveClassName);
cn= DriverManager.getConnection(url,username,password);
pstmt= cn.prepareStatement(“select score.*from score ,student “ +
“wherescore.stuId = student.id and student.name = ?”);
pstmt.setString(1,studentName);
Resultsetrs = pstmt.executeQuery();
while(rs.next())
{
system.out.println(rs.getInt(“subject”) + “ ” + rs.getFloat(“score”) );
}
}catch(Exception e){e.printStackTrace();}
finally
{
if(rs!= null) try{ rs.close() }catch(exception e){}
if(pstmt!= null) try{pstmt.close()}catch(exception e){}
if(cn!= null) try{ cn.close() }catch(exception e){}
}
6、这段代码有什么不足之处?
try {
Connection conn = ...;
Statement stmt = ...;
ResultSet rs = stmt.executeQuery("select * from table1");
while(rs.next()) {
}
} catch(Exception ex) {
}
答:没有finally语句来关闭各个对象,另外,使用finally之后,要把变量的定义放在try语句块的外面,以便在try语句块之外的finally块中仍可以访问这些变量。
7、说出数据连接池的工作机制是什么?
J2EE服务器启动时会建立一定数量的池连接,并一直维持不少于此数目的池连接。客户端程序需要连接时,池驱动程序会返回一个未使用的池连接并将其表记为忙。如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建连接的数量有配置参数决定。当使用的池连接调用完成后,池驱动程序将此连接表记为空闲,其他调用就可以使用这个连接。
8、为什么要用 ORM? 和 JDBC 有何不一样?
orm是一种思想,就是把object转变成数据库中的记录,或者把数据库中的记录转变成object,我们可以用jdbc来实现这种思想,其实,如果我们的项目是严格按照oop方式编写的话,我们的jdbc程序不管是有意还是无意,就已经在实现orm的工作了。
现在有许多orm工具,它们底层调用jdbc来实现了orm工作,我们直接使用这些工具,就省去了直接使用jdbc的繁琐细节,提高了开发效率,现在用的较多的orm工具是hibernate。也听说一些其他orm工具,如toplink,ojb等。