以下为javaweb开发人员必须掌握的基础数据库知识总结。
1、分别列举mysql和oracle数据库分页查询例子
答:以用户信息表为例
mysql分页:select s.* from sys_user s limit 0,5
Oracle分页:select * from (select rownum rn,s.* from sys_user s where rownum<=5) where rn >=0
2、数据库事务的特性
答: 原子性:事务的原子性是指事务中包含的所有操作要么全做,要么全不做(all or none)。
一致性:在事务开始以前,数据库处于一致性的状态,事务结束后,数据库也必须处于一致性状态。
隔离性:事务隔离性要求系统必须保证事务不受其他并发执行的事务的影响
持久性:一个事务一旦成功完成,它对数据库的改变必须是永久的,即便是在系统遇到故障的情况下也不会丢失。
3、数据库事物隔离级别有几种
答: Read uncommitted (未提交读):允许脏读取,但不允许更新丢失。如果一个事务已经开始写数据,则另外一个事务则不允许同时进行写操作,但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。
Read committed (提交读):允许不可重复读取,但不允许脏读取。这可以通过“瞬间共享读锁”和“排他写锁”实现。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。
Repeatable read (可重复读):禁止不可重复读取和脏读取,但是有时可能出现幻读数据。这可以通过“共享读锁”和“排他写锁”实现。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。
Serializable (序列化):提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,不能并发执行。仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。
脏读:一个事务读取到了另一个事务未提交的数据操作结果。这是相当危险的,因为很可能所有的操作都被回滚。
不可重复读(Non-repeatable Reads):一个事务对同一行数据重复读取两次,但是却得到了不同的结果。
包括以下情况:
(1) 虚读:事务T1读取某一数据后,事务T2对其做了修改,当事务T1再次读该数据时得到与前一次不同的值。
(2) 幻读(Phantom Reads):事务在操作过程中进行两次查询,第二次查询的结果包含了第一次查询中未出现的数据或者缺少了第一次查询中出现的数据(这里并不要求两次查询的SQL语句相同)。这是因为在两次查询过程中有另外一个事务插入数据造成的。
4、什么是连接查询,联合查询,子查询,嵌套查询,自连接查询
答: 连接查询:连接查询分为内连接和外连接,交叉连接
内连接是指用比较运算符比较要联接列的值的联接,join或inner jion 例:
select * from table1 t1 join table2 t2 on t1.id = t2.id 只返回符合条件的table1和table2的列,
等价于A:select a.*,b.* from table1 a,table2 b where a.id=b.id
B:select * from table1 cross join table2 where table1.id=table2.id (注:cross join后加条件只能用where, 不能用on)
外连接分为左外连接(左连接left join),右外连接(右连接right join),全连接full join,
左连接的结果集包括 LEFT OUTER 子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左 表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值(null)。 例:
select * from table1 t1 left join table2 t2 on t1.id=t2.id 包含table1的所有子句,根据指定条 件返回table2相应的字段,不符合的以null显示
右连接是左向外联接的反向联接。将返回右表的所有行。如果右表的某行在左表中没有匹配行,则将 为左表返回空值。 例:
select * from table1 t1 right join table2 t2 on t1.id=t2.id 包含table2的所有子句,根据指定 条件返回table1相应的字段,不符合的以null显示
全连接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包 含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。 例:
select * from table1 t1 full join table2 t2 on t1.id=t2.id返回左右连接的和(见上左、右连接)
交叉连接:不带WHERE条件子句,它将会返回被连接的两个表的笛卡尔积,返回结果的行数等于两个表行 数的乘积,有where子句,往往会先生成两个表行数乘积的数据表,然后才根据where条件从中选择。
select * from T_student s cross join T_class c where s.classId = c.classId
(注:cross join后加条件只能用where,不能用on)
联合查询:将两个查询字段相同的结果集合并为一个结果集,用unio或unio all,例:
select t1.neme,t1.sex from table1 t1 unio select t2.neme,t2.sex from table2 t2
子查询:将其中一个查询出来的结果集当做另一个查询的条件,例:
select t1.* from table1 t1 where t1.id in (select t2.fkid from table2 t2 )
嵌套查询:指在一个外层查询中包含有另一个内层查询。其中外层查询称为主查询,内层查询称为子查询。SQL允 许多层嵌套,由内而外地进行分析,子查询的结果作为主查询的查询条件,子查询中一般不使用order by子句,只能对最终查询结果进行排序,例:
select * from (select rownum rn,s.* from sys_user s where rownum<=5) where rn >=0
自连接查询:自连接查询是建立在以上几种链接查询的基础上,与自身链接,通常用于自反关系,做递归查询
5、数据库索引是什么
答:索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。
6、索引的优缺点
答:优点: 第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。
第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
第四,在使用分组和排序 子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。
第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。
缺点: 第一,创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。
第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立 聚簇索引,那么需要的空间就会更大。
第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。
7、什么时候使用索引
答:索引是建立在数据库表中的某些列的上面。因此,在创建索引的时候,应该仔细考虑在哪些列上可以创建索引,在哪 些列上不能创建索引。一般来说,应该在这些列上创建索引,例如:
在经常需要搜索的列上,可以加快搜索的速度;
在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构;
在经常用在连接的列上,这 些列主要是一些外键,可以加快连接的速度;
在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的;
在经常需要排序的列上创 建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;
在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。
8、列举几种mysql常用的函数
答:max(),count(),sum(),avg(),group by,limit,order by等
9、按性别分组统计班级学生的人数
答:select s.sex,count(s.id) from student s group by s.sex
10、查询成绩表中成绩最高的学生的姓名
答:select t.name from t_score t where t.score = (select max(t2.score) from t_score t2)
11、Having关键字的用法
答:having子句可以让我们筛选成组后的各种数据,having子句在查询过程中慢于聚合语句(sum,min,max,avg,count).而 where子句在查询过程中则快于聚合语句(sum,min,max,avg,count)。
12、Sql关键字的解释执行顺序
一、查询的逻辑执行顺序
(1) FROM left_table
(3) join_type JOIN right_table (2) ON join_condition
(4) WHERE where_condition
(5) GROUP BY group_by_list
(6) WITH {cube | rollup}
(7) HAVING having_condition
(8) SELECT (9) DISTINCT (11) top_specification select_list
(9) ORDER BY order_by_list
标准的 SQL 的解析顺序为:
(1) FROM 子句 组装来自不同数据源的数据
(2) WHERE 子句 基于指定的条件对记录进行筛选
(3) GROUP BY 子句 将数据划分为多个分组
(4) 使用聚合函数进行计算
(5) 使用HAVING子句筛选分组
(6) 计算所有的表达式
(7) 使用ORDER BY对结果集进行排序
二、执行顺序
1. FROM:对FROM子句中前两个表执行笛卡尔积生成虚拟表vt1
2. ON: 对vt1表应用ON筛选器只有满足 join_condition 为真的行才被插入vt2
3. OUTER(join):如果指定了 OUTER JOIN保留表(preserved table)中未找到的行将行作为外部行添加到vt2, 生成t3,如果from包含两个以上表,则对上一个联结生成的结果表和下一个表重复执行步骤和步骤直 接结束。
4. WHERE:对vt3应用 WHERE 筛选器只有使 where_condition 为true的行才被插入vt4
5. GROUP BY:按GROUP BY子句中的列列表对vt4中的行分组生成vt5
6. CUBE|ROLLUP:把超组(supergroups)插入vt6,生成vt6
7. HAVING:对vt6应用HAVING筛选器只有使 having_condition 为true的组才插入vt7
8. SELECT:处理select列表产生vt8
9. DISTINCT:将重复的行从vt8中去除产生vt9
10. ORDER BY:将vt9的行按order by子句中的列列表排序生成一个游标vc10
三、书写顺序
SELECT 字段列表
FROM 表名
WHERE 记录筛选条件
GROUP BY 分组字段列表
HAVING 分组筛选条件
ORDER BY 排序字段列表
13、数据库存储过程的作用
答: 第一:存储过程因为SQL语句已经预编绎过了,因此运行的速度比较快。
第二:存储过程可以接受参数、输出参数、返回单个或多个结果集以及返回值。可以向程序返回错误原因。
第三:存储过程运行比较稳定,不会有太多的错误。只要一次成功,以后都会按这个程序运行。
第四:存储过程主要是在服务器上运行,减少对客户机的压力。
第五:存储过程可以包含程序流、逻辑以及对数据库的查询。同时可以实体封装和隐藏了数据逻辑。
第六:存储过程可以在单个存储过程中执行一系列 SQL 语句。
第七:存储过程可以从自己的存储过程内引用其它存储过程,这可以简化一系列复杂语句。
存储过程还可以控制权限,比如一个表不直接允许用户直接访问,但要求允许用户访问和修改其中一个或多个字段, 那就可以通过一个存储过程来实现并允许该用户使用该存储过程。
如果多条SQL语句执行过程中,过程环节返回了数据作为后面环节的输入数据,如果直接通过SQL语句执行,势必 导致大量的数据通过网络返回到客户机,并在客户机运算;如果封装在存储过程中,则将运算放在服务器进行,不 但减少了客户机的压力,同时也减少了网络流量,提高了执行的效率。
14、存储过程的缺点
答:不便于处理业务逻辑,调试麻烦,移植性差等
15、Mysql数据库存储过程中如何定义变量
答:例:DECLARE v_end_time VARCHAR(20);
16、存储过程中游标的作用及用法
答: 游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。游标充当指针的作用。尽管游标能 遍历结果中的所有行,但他一次只指向一行。
概括来讲,SQL的游标是一种临时的数据库对象,即可以用来存放在数据库表中的数据行副本,也可以指向存储在 数据库中的数据行的指针。游标提供了在逐行的基础上操作表中数据的方法。
游标的一个常见用途就是保存查询结果,以便以后使用。游标的结果集是由SELECT语句产生,如果处理过程需要 重复使用一个记录集,那么创建一次游标而重复使用若干次,比重复查询数据库要快的多。
单从用法上来说游标与java中的迭代器用法一样
17、Mysql存储过程中循环怎么写
答:在MySQL存储过程的语句中有三个标准的循环方式:WHILE循环,LOOP循环以及REPEAT循环。还有一种非标准的 循环方式:GOTO,这种循环方式最好别用,很容易引起程序的混乱。一下介绍三种标准循环方式的写法:
WHILE循环:
mysql> create procedure pro01()
-> begin
-> declare i int;
-> set i=0;
-> while i<5 do
-> insert into t1(filed) values(i);
-> set i=i+1;
-> end while;
-> end;//
INSERT和SET语句在WHILE和END WHILE之间,当变量i大于等于5的时候就退出循环。使用set i=0;语句是为了 防止一个常见的错误,如果没有初始化,i默认变量值为NULL,而NULL和任何值操作的结果都是NULL。
LOOP循环:
mysql> create procedure pro02()
-> begin
-> declare i int default 0;
-> loop_label: loop
-> insert into t1(filed) values(i);
-> set i=i+1;
-> if i>=5 then
-> leave loop_label;
-> end if;
-> end loop;
-> end;//
使用LOOP编写同样的循环控制语句要比使用while和repeat编写的要复杂一些:在循环内部加入了IF……END IF 语句,在IF语句中又加入了LEAVE语句,LEAVE语句的意思是离开循环,LEAVE的格式是:LEAVE 循环标号。
REPEAT循环:
mysql> create procedure pro03()
-> begin
-> declare i int default 0;
-> repeat
-> insert into t1(filed) values(i);
-> set i=i+1;
-> until i>=5
-> end repeat;
-> end;//
REPEAT循环的功能和前面WHILE循环一样,区别在于它的执行后检查是否满足循环条件(until i>=5),而WHILE 则是执行前检查(while i<5 do)。