面试关于数据库的问题

这篇写的不错

1 请写出分页查询语句

select * from (select * from (select b.*,rownum rn from BIZ_MAIN_TRANS b) where rn<=10 ) where rn >0; (oracle)

select * from table_name limit 0,5 (mysql)

2 什么是数据库事务?

数据库事务是指对数据库的一组操作,要么全部执行,要么全部不执行。例如可以将银行的实时转账看做一个事务,转出卡扣款后转入卡必须余额增加。

3 你实际项目中所用的事务是在哪一层控制,采用的是什么隔离级别?什么是事务的传播行为,什么是ACID?

一般是放在SERVICE层,(业务逻辑)
数据库数据操作容易出现的问题(脏读,不可重复读,幻读)
脏读:T1在修改数据,T2读取的数据不是最终的数据是无效的
幻读:T1修改数据,T2对同一个表中的部分数据修改,导致T1修改部分没有成功。
不可重复读:T1修改数据,并查询结果,但同时T2也对数据进行了修改,导致查询的结果不符合预期。

事务的隔离级别点这里
Serializable (脏读、幻读、不可重复读)
Repeatable read (脏读、不可重复读)
Read committed (脏读)
Read uncommitted (没用)

什么是事务的传播行为 点这里
事务的传播行为是指一个事务被另外一个事务调用时,这个事务方法应该如何进行。
methodA事务方法调用methodB事务方法时,methodB是继续在调用者methodA的事务中运行呢,还是为自己开启一个新事务运行,这就是由methodB的事务传播行为决定的。

事务的7种传播行为: 点这里
1 propagation_required
如果当前没有事务就创建新事务,如果当前存在事务,就加入该事务。
2 propagation_supports
支持事务,如果当前存在事务就支持该事务,如果当前不存在事务就以非事务执行。
3 propagation_mandatory
如果当前存在事务就加入该事务,如果当前不存在事务就抛出异常
4 propagation_requires_new
无论当前有没有事务都创建新事务
5 propagation_not_supported
以非事务执行,如果当前存在事务,就挂起该事务
6 propagation_never
以非事务执行,如果当前存在事务就抛出异常
7 propagation_nested
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

ACID:
事务的原子性、事务的一致性、事务的持久性、事务的隔离性

4 数据库的三范式

点这里
1 第一范式(1NF):确保每一列的原子性
2 非键字段必须依赖于键字段(要求每个表只描述一件事)
3 除了主键以外的其它列都不传递依赖于主键列

5 如何进行sql优化

1 尽量减少对*的使用,写明具体的列明 select id from tablename,使用表的别名代替表全名
2 使用varchar/narvarchar代替char/nchar (CHAR的长度是固定的,而VARCHAR2的长度是可以变化的,可节省空间)
3 使用索引
4 尽量避免对null进行判断(将导致索引失效)
select id from t where num is null可以在num上设置默认值0,确保表中num列没有null值。
5 应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
6 应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,
如:select id from t where num=10 or num=20
可以这样查询:select id from t where num=10union allselect id from t where num=20
7 .in 和 not in 也要慎用,否则会导致全表扫描,
如:select id from t where num in(1,2,3)对于连续的数值

6 索引失效的场景有哪些

上面的问题基本就是索引失效的场景但是并没有全,我们再来梳理下:点这里

1 隐式转换导致索引失效.
由于表的字段tu_mdn定义为varchar2(20),但在查询时把该字段作为number类型以where条件传给Oracle,这样会导致索引失效.
错误的例子:select * from test where tu_mdn=13333333333;
正确的例子:select * from test where tu_mdn=’13333333333’;

2 对索引列进行运算导致索引失效(+,-,*,/,! 等)
错误的例子:select * from test where id-1=9;
正确的例子:select * from test where id=10;

3 使用Oracle内部函数导致索引失效
错误的例子:select * from test where round(id)=10; 说明,此时id的索引已经不起作用了
正确的例子:首先建立函数索引,create index test_id_fbi_idx on test(round(id));然后 select * from test where round(id)=10; 这时函数索引起作用了

4 以下使用会使索引失效,应避免使用;
a. 使用 <> 、not in 、not exist、!=
b. like “%_” 百分号在前(可采用在建立索引时用reverse(columnName)这种方法处理)
c. 单独引用复合索引里非第一位置的索引列.应总是使用索引的第一个列,如果索引是建立在多个列上, 只有在它的第一个 列被where子句引用时,优化器才会选择使用该索引。
d. 字符型字段为数字时在where条件里不添加引号.
e. 当变量采用的是times变量,而表的字段采用的是date变量时.或相反情况。

7 表格(学号 id 、课程 classname、成绩 sorce),查询成绩至少两门不少于80分的学号

select id,count (classname ) from (select id ,classname ,sorce from student where sorce>=80) group by id having count (classname )>=2

8 经典sql例子

表格点这里
可能一下子做不完,每天做一点

Student(Sid,Sname,Sage,Ssex)学生表
Sid:学号
Sname:学生姓名
Sage:学生年龄
Ssex:学生性别
Course(Cid,Cname,T#)课程表
Cid:课程编号
Cname:课程名称
Tid:教师编号
SC(Sid,Cid,score)成绩表
Sid:学号
Cid:课程编号
score:成绩
Teacher(Tid,Tname)教师表
Tid:教师编号:
Tname:教师名字

题目:
1、查询“001”课程比“002”课程成绩高的所有学生的学号

select  Sid   from 
(select  Sid ,Cid,score  from  SC where Cid='001' ) t1 ,
(select  Sid ,Cid,score  from  SC where Cid='002' ) t2 
where t1.Sid =t2.Sid  and t1.score  >t2.score  

2、查询平均成绩大于60分的同学的学号和平均成绩

select  Sid ,avg(score)  from  SC group by Sid having avg(score)>60

3、查询所有同学的学号、姓名、选课数、总成绩

select  t1.sums,t1.sumc  ,t2.Sid ,t2.Sname   from
(select Sid ,sum(score) sums, sum(Cid) sumc  from SC  group by Sid  ) t1,
(select Sid ,Sname  from Student )t2 where   t1.Sid=t2.Sid

4、查询姓‘李’的老师的个数

select count(*) from Teacher where Tname like '李%'

5、查询没有学过“叶平”老师可的同学的学号、姓名

先选出叶萍老师带的课,再选出不是叶平带的学生
select  t0.Sid, t0.Cid,a.Sname  from  Student a ,SC   t0,
(select Cid,Tid from  Course   ) t1,
(select  Tid ,Tname from Teacher where Tname ='叶平') t2  
where t1.Tid =t2.Tid  and  t0.Cid ! having not in  and t0.Sid = a.Sid

6、查询学过“叶平”老师所教的所有课的同学的学号、姓名

select  t0.Sid, t0.Cid,a.Sname  from  Student a ,SC   t0,
(select Cid,Tid from  Course   ) t1,
(select  Tid ,Tname from Teacher where Tname ='叶平') t2  
where t1.Tid =t2.Tid  and  t0.Cid = t1.Cid and t0.Sid = a.Sid

7、查询学过“011”并且也学过编号“002”课程的同学的学号、姓名
8、查询课程编号“002”的成绩比课程编号“001”课程低的所有同学的学号、姓名
9、查询所有课程成绩小于60的同学的学号、姓名:
10、查询没有学全所有课的同学的学号、姓名
11、查询至少有一门课与学号为“1001”同学所学相同的同学的学号和姓名
12、查询至少学过学号为“001”同学所有一门课的其他同学学号和姓名
13、把“SC”表中“叶平”老师教的课的成绩都更改为此课程的平均成绩
14、查询和“1002”号的同学学习的课程完全相同的其他同学学号和姓名
15、删除学习“叶平”老师课的SC表记录
16、向SC表中插入一些记录,这些记录要求符合以下条件:没有上过编号“003”课程的同学学号、002号课的平均成绩
17、按平均成绩从高到低显示所有学生的“数据库”、“企业管理”、“英语”三门的课程成绩,按如下形式显示:学生ID,数据库,企业管理,英语,有效课程数,有效平均分
18、查询各科成绩最高和最低的分:以如下的形式显示:课程ID,最高分,最低分
19、按各科平均成绩从低到高和及格率的百分数从高到低顺序
20、查询如下课程平均成绩和及格率的百分数(用”1行”显示): 企业管理(001),马克思(002),OO&UML (003),数据库(004)

猜你喜欢

转载自blog.csdn.net/qq_31941773/article/details/82987734