概述
这里写目录标题
- Oralce数据库
- 数据库基础题
- 1. 数据库的常见分类有哪些?
- 2. 数据库将表存入存储系统的方式有哪两种
- 3. 数据库的约束由哪些?
- 4. 什么是第一,二,三,BC范式?
- 5. 事务的概念和四种特性是什么?
- 6. 事务的四种隔离级别分别是什么?
- 7. 简述存储过程,它有什么优点?能否写下存储过程的语法。
- 8. 存储过程和函数的区别是什么?各自作用?
- 9. 触发器的作用?分类?优缺点有哪些?
- 11. 什么是游标?如何知道游标已经执行到最后?
- 12. 什么是视图?视图的作用是什么?
- 13. 什么情况下可以对视图执行DM操作?
- 14. SQL语句有哪些常见的分类?
- 15.笛卡尔积是什么?产生笛卡尔积的条件?
- 16.什么是OLTP和OLAP?
- 数据库零散知识点
- 1. Delete,Drop和Truncate的三者之间的区别
- 2. Null有哪些注意事项?
- 3. 如何判断一个存储过程是否正在运行?
- 4. 如何将文本文件或Excel中的数据导入数据库?
- 开发类常考题
- SQL操作题
- 1. 怎么将相邻记录合并到一条?
- 2. 如果查询的列中含有特殊字符,如通配符“%”和“_”,那么该如何查询这些特殊字符?
- 3. 如何随机抽取表SCOTT.EMP的前5条记录?
- 函数相关
- 1. Oracle常用日期处理函数有哪些?他们的作用是什么?
- 2. 函数SUBSTR和INSTR有什么区别?
- 3. NVL,NVL2,NULLIF,COALESCE的区别是什么?
- 4. 条件表达式CASE和DECODE的区别是什么?
- 5. Oracle常用的替换函数有哪两个?
- 6. 如何判断一个字符串是否含有中文汉字?
- 7. 在Oracle中有哪些常用的分析函数?
- 8. Oracle中的正则表达式用到哪四个函数?
- 9. Oracle中有哪些常用的字符函数?
- 高级操作
- 1. Oracle行列互换有哪些方法?
- 2. 如何分批插入,分批更新,分批删除,分批提交?
- 3. 如何删除表中重复的记录?
- 4. 怎样创建一个一个索引,索引使用的原则,有什么优点和缺点
- 5. Oracle如何解锁?
- 6.热备份和冷备份的区别是什么?
- 分区表
- 1. 分区表有什么优点?分区表有哪几类?如何选择用哪种类型的分区表?
- 2. 分区表常用数据字典视图有哪些?
- 3. 普通表转换为分区表有哪些方法?
- 索引
- 1. 索引的定义?索引的优缺点有哪些?
- 2. 哪些情况下可以考虑用索引?
- 3. 索引的分类?
- SQL优化相关
- 1.SQL优化在写法上有哪些常用方法?
- 2. count(*) count(1)与count(col)的区别
- 3.数据库中索引会失效的几种情况?
- 修改记录
- 本文初衷是为了学习归纳,若有错误,欢迎指出。
Oralce数据库
数据库基础题
1. 数据库的常见分类有哪些?
数据库可以按照存储模型,或者关系型/非关系型来进行分类。
-
如果是按照存储模型分类,则可以把数据库分为网状数据库,关系型数据库和层次数据库。其中使用最广泛的是关系型数据库,比如Oracle,MySQL,DB2,SQLServer。
网状数据库是以记录类型为节点的网状数据模型的数据库,处理方法是将网状结构分解成若干棵二级或二级以上的树结构,它的代表有DBTG(数据库任务组系统)。
层次数据库,也称为树状数据库,它将数据组织成有向有序的树结构,并用一对多的关系联结不同层次的数据库,典型代表是IBM的IMS数据库。
关系型数据库RDBMS,它通过数据,关系,和对数据的约束三者组成的数据模型来存放和管理系统,现实中的各种实体以及实体之间的各种联系均可以用关系模型来表示,并用SQL结构化查询语言来检索和操作数据库。其特点有:(1)数据以表格形式存在(2)每一行存储着一条单独的记录(3)每个列作为一条记录的一个属性存在(4)许多的行和列组成一张表(5)若干表组成数据库。
-
如果是按照是否关系模型来分类,可以把数据库分为关系型数据库和非关系型数据库,其中关系型数据库又可以根据是否在内存分为内存数据库和非内存数据库,内存数据库顾名思义就是将数据存放在内存中操作,相对于磁盘的读写速度要快很多,典型代表是SQLite和TimesTen,非内存数据库就常见的那几种RDBMS。另外关系型数据库还有跟大小划分,小型的如Access,Foxbase,SQLite,中型的如MySQL,SQLServer,PostgreSQL,大型的如Oracle,DB2。对于非关系型数据库,也即是NoSQL,分为键值数据库,列存储数据库,文档型数据库,和图形数据库。键值数据库主要会用到一个哈希表,这个表中有一个特定的键和一个指向特定数据的指针,优势是简单,容易部署,典型的代表是Redis。列存储数据库通常是用来应对分布式存储的海量数据,键依然存在,但是他们的特点是键指向了多个列,典型代表有HBase,HyperTable。而文档型数据库和键值数据库类似,他的数据类型是版本化的文档,半结构化的文档以特定的格式存储,比如JSON,可以看作是键值数据库的升级版,查询效率也更高,典型代表是MongoDB。对于图形数据库,采用图形模型,能够扩展到多台服务器,代表是Giraph,Titan等。
2. 数据库将表存入存储系统的方式有哪两种
参考连接:https://www.jianshu.com/p/3d3950c9fb06
行存储和列存储。
绝大部分数据库是用行存储的,行存储法是将各行放入连续的物理位置,把行当作一个整体来存储,然后由数据库引擎根据每个查询提取需要的列,行存储适用于OLTP系统,插入更新等频繁的系统。从查询来说,行存储笔记适合随机查询,并且在整行数据读取上要由于列存储。
列存储是将数据按照列存储到数据库中,它的行数据中包含一个列或者多个列,使用与OLAP,数据仓库,数据挖掘等查询密集型应用,不适合在OLTP这种DML频繁的系统。优点是它的每个字段的数据聚集存储,在查询只需要少数几个字段时能大大减少读取的数据量,尤其在数据量大时查询速度很快。另一个优点是因为字段聚集存储,所以更容易压缩解压,因为同一列的数据中数据类型是相同的,天生适合压缩…。
简述下关系型数据库完整性规则?
关系型数据库的完整性规则分为三类:实体完整性,参照完整性和用户自定义完整性。
实体完整性是指惯性的主属性也就是主键,不能为空,如果为空即存在不可区分的实体,这和现实的环境相矛盾,说明这个实体一定不是完整的实体。
参照完整性指的是如果关系R1的外键和关系R2的主键相符,那么外键的每个值必须在关系R2的主键值中都可以找到或者是空值。
用户自定义完整性是根据实际应用环境需要,对某一具体应用所涉及的数据提出约束条件。比如使用CHECK约束,UNIQUE约束,Default约束,Identity约束,Not null等。
3. 数据库的约束由哪些?
数据库的约束可以分为五类:主键约束,唯一约束,非空约束,检查约束,外键约束。
- 主键约束:主键唯一标识一个实体,必须非空且唯一
- 唯一约束:除了主键外,其他列如果不希望出现重复值,也可以使用唯一约束。
- 非空约束:列值不能为空
- 检查约束:检查列值是否合法。
- 外键约束:外键值必须是参照表的主键或者空值。
对于外键和主键约束,主要是为了维护关系型数据库的完整性,主键是能唯一标识一条记录,外键是用于和另一张表关联,并具有级联更新或删除的特点,外键更新的值也必须是主键表中主键有的值。
4. 什么是第一,二,三,BC范式?
范式主要目的是为了消除重复数据减少数据冗余。
第一范式:数据库表中的每一列都不可再分。
第二范式:在第一范式的基础上,消除非主属性对主键的部分依赖,也就是1NF基础上,每一个非主属性必须完全依赖于主键。
第三范式:在第二范式基础上消除传递依赖,或者说在1NF基础上,每个非主属性都不部分依赖于主键也不存在传递依赖。
符合第三范式的数据表,可以消除数据容易,更新异常,插入异常和删除异常。
BC范式:在第三范式基础上消除对主键子集的依赖,相比于第三范式,多限制了主键中的主属性也不能有部分依赖或者传递依赖。BC范式算是第三范式的修正版,能使数据库冗余度更小。
一般来说,数据库只要满足第三范式就可以了。
5. 事务的概念和四种特性是什么?
事务是一个操作序列,这些操作要么都做,要么都不做,具有不可分割的关系。通常以Begin Transaction开始,以Commit或Rollback结束。
四个特性如下:
- 原子性:指事务在逻辑上是不可分割的操作单元,其所有语句要么都执行,要么都补执行。比如A给B转账100元,A账号减去100元并且B账号增加100元,这两个动作不可分割只完成一个。
- 一致性:事务完成一项工作,将数据库中的数据从一种一致性状态转换到另一种一致性状态,以体现现实世界中的状态变化。还是比如转账,A和B的总资产加起来是5000元,那么不管A给B转账还是B给A转账多少次,他们之间总和必须还是5000元。
- 隔离性:隔离是针对并发事务而言,所谓并发就是数据库服务器同时处理多个事务,隔离性就是隔离多个并发事务之间相互影响。
- 持久性:是指事务一旦提交成功,对数据的修改是永久性的,即使数据库重启,事务做的更改操作不会丢失。
6. 事务的四种隔离级别分别是什么?
首先要知道如果没有隔离性,事务会发生什么问题:
第一个是脏读,一个事务读取了另一个事务修改但没有提交的数据,比如A对B转账100元,A的数据显示已经转账给B但事务没有提交,B去查看时发现确实多了100元,但由于事务没有提交,后续可能被回滚,回滚的话实际上A没有转账给B100元,就属于脏读。
第二个是不可重复度,在同一个事务操作中,同一条查询语句,在T1时间读取和在T2时间读取的数据显示不同,这期间可能数据被DML了。比如事务在T读取某个数据,而事务T2立刻修改了这个数据并提交,那么T1事务重复读取时就得到一个不同的数据结果。
第三个是幻读,幻读和不可重复读有点类似,都是在同一事务中查询,但期间有其他事务对数据做了DML操作,不同的是不可重复读针对的是同一个数据项,而幻读针对的是一个数据整体,比如数据条数。
在SQL中定义了4种隔离级别,每一种级别都规定了事务所作的修改。较低级别的事务通常可以执行更高的并发,系统的开销也更低,但存在问题较危险。
- 第一种是Read Uncommitted 未提交读。事务中的改变,即便没有提交对其他事务而言也是可见,实际很少用到。
- 第二种是Read Committed 提交读。大多数数据库默认的级别,一个事务只能看见已经提交事务所作的改变,对应解决了脏读问题。
- 第三种是Repeatable Read 可重复读。确保多次重复读取同样的数据,能得到同样的结果,对应解决不可重复读问题。
- 第四种是Serializable 可串行化,序列化。它通过强制事务排序,强制事务串行执行,使得他们不可能相互冲突,从而解决幻读问题,是最高的隔离级别。实际应用较少,因为花费代价大,需要在每个读的数据行上加上共享锁,会导致大量的超时现象和锁竞争,除非非常需要确保数据一致性且接受没有并发情况下使用。
7. 简述存储过程,它有什么优点?能否写下存储过程的语法。
存储过程是用户定义的一系列SQL语句的集合,涉及特定表或其他对象的任务,用户可以调用存储过程。存储过程用于执行特定的操作,可以接受输入参数,输出参数,返回单个或者多个结果集。存储过程允许用户声明变量并且可包含程序流,逻辑以及对数据库的查询。
存储过程的优点如下:
- 存储过程增强了SQL语言的功能和灵活性,这点比如可以用结构化的控制语言编写,能完成复杂的判断和运算
- 存储过程可以保证数据的安全性,可以使没有权限的用户在权限控制下间接地存储数据库中的数据。
- 通过存储过程可以使相关的sql操作连在一起发生,从而维护数据库完整性
- 存储过程编译一次后,由于已经做了语法分析,并优化执行,那么下一次运行时就能极大地改善SQL语句的性能,能以更快的速度执行。
- 可以降低网络的通信量,存储过程的SQL是一次性发送到数据库服务器的。
- 企业易于维护,业务规则发生变化时,只需修改存储过程中的逻辑。
存储过程的语法如下:
CREATE [OR REPLACE] PROCEDURE Procedure_name [(
argment [ {IN |OUT | IN OUT}] TYPE,
argment [ {IN |OUT | IN OUT}] TYPE)]
{IS | AS}
<类型.变量的说明,后面加分号>
BEGIN
<执行部分>
ECXCEPTION
<可选的异常错误处理程序>
END 存储过程名;
8. 存储过程和函数的区别是什么?各自作用?
存储过程和函数都是存储在数据库中的程序,都可以接受输入和输出参数,可以由用户直接或间接的调用,都是一系列SQL的集合。
但不同的是(1)标识符不同,函数是FUNCTION,过程是PROCEDURE;(2)函数必须有返回值,并且只有一个返回值;(3)存储过程没有返回值类型,不能直接赋值给变量,函数有返回值类型,在调用函数时,除了在select语句中,其他情况下必须将返回值赋值给一个变量。(4)刚提到的,函数可以在SELECT语句中直接使用,而过程不行。
9. 触发器的作用?分类?优缺点有哪些?
触发器和存储过程的区别在于,触发器不能显式调用,而是由某个事件来触发运行,即触发器是在某个事件发生隐式地运行的,而存储过程时可以被用户或由应用程序显式调用执行的。
11. 什么是游标?如何知道游标已经执行到最后?
游标是一种机制,可以对select语句返回的结果集,每次处理一行或者一部分行。
12. 什么是视图?视图的作用是什么?
视图是从数据库的基本表中选取出来的数据组成的逻辑窗口,是一个虚拟表,存放的只是视图的定义而不存放实际的数据,而视图中的数据也会在引用视图时动态生成,用户只需集中关注想要的数据,而非全部数据,大大提高运行效率和用户满意度。视图看上去和基表类似,通过视图修改数据时,实际上是在修改基本表,相反基本表的数据更新也会反映在视图上。
视图的作用由以下几点:(1)隐藏了数据的复杂性(2)有利于控制用户对表的某些数据的访问权限,提高了安全性。(3)能够简化查询结构,执行复杂查询操作。(4)能让用户可以多角度,更灵活的共享同一数据。
13. 什么情况下可以对视图执行DM操作?
视图对DML操作应遵循以下内容:
- 简单视图可以DML操作
- 当视图包含group by,distinct时不能执行删除操作
- 当视图有以下情况时,不能通过视图来修改基本表或插入数据到基本表:
- 有group by,distinct
- 视图中包含了表达式的定义
- 视图中有ROWNUM伪列(针对Oracle)
- 基表中未在视图中选择的其他列定义为非空且无默认值的时候。
DROP VIEW view_name可以删除视图,删除后,基于被删除视图的其他视图或者程序会无效。
14. SQL语句有哪些常见的分类?
- DML:UPDATE ,INSERT ,DELETE ,MERGE ,SELECT…FOR UPDATE;
- DDL:CREATE TABLE/INDEX,ALTER TABLE/INDEX,DROP TABLE/INDEX,TRUNCATE TABLE;
- DCL:数据控制语言,GRANT,REVOKE;
- DQL:SELECT
- TCL:事务控制语言(Oracle),COMMIT,ROLLBACK,SAVEPOINT,SET TRANSATION,SET CONSTRAINT,ROLLBACK TO SAVEPOINT;
- SCS:会话控制语言(Oracle),ALTER SESSION,ALTER SYSTEM,SET ROLE;
- ESS:嵌入式sql(Oracle),OPEN ,CLOSE, CONNECT ,DESCRIBE ,WHENEVER, PREPARE ,EXECUTE ,FETCH
15.笛卡尔积是什么?产生笛卡尔积的条件?
笛卡尔积是把所有记录做乘积操作,生成大量结果,而通过结果中可用的值有限。
笛卡尔积的原因:(1)连接条件缺失,没有写where条件(2)连接条件无效,比如where条件写的是A.ID = A.ID (3)统计信息不准确,假如表A有100W条记录,但统计信息中记录的是0行,那么这种情况下的连接就容易形成笛卡尔积。
16.什么是OLTP和OLAP?
数据处理可以大致分为两大类:OLTP(联机事务处理)和OLAP(联机分析处理)。
OLTP是传统关系型数据库的主要应用,记录实时的DML操作,主要是执行基本的,日常的事务处理,比如银行交易。一般情况下,OLTP系统数据量少,DML操作频繁,并行事务处理多,OLTP系统强调数据库处理效率,要求实时。主要面对数据库。
OLAP是数据仓库系统最主要的应用,支持复杂的分析操作,侧重决策支持,并且提供直观易懂的查询结果。OLAP实时性要求不高,DML不频繁,但数据量很大,主要面对数据仓库。
在大数据中,对于OLAP,列式存储或者NoSQL的模式比传统意义上的行存储更有优势。
17.数据类型有哪些?
18.如何定义序列?
数据库零散知识点
1. Delete,Drop和Truncate的三者之间的区别
相同点是Truncate和不带where条件的delete及drop都会删除表内所有的数据,而drop和Truncate都是DD语句,执行后会自动提交;这三者执行后,索引的大小都会自动进行维护。
不同的是
(1)drop table还会删除表结构和表上的约束,并且依赖于该表的存储过程和函数等都将变成无效状态;而Truncate和delete只是删除表的数据,不会影响表的定义,存储过程,触发器,约束等。
(2)刚刚提到的drop和Truncate语句都是DDL语句,隐式提交,不能回滚;delete是DML语句,事务提交后数据才生效,可以回滚。
(3)drop table后会将表所占用的空间全部释放,Truncate table后表的大小会变为初始化的大小,而delete table后表的大小不会发生改变,所以正常情况下,truncate后的表比delete之后的表查询速度要快。
(4)drop和delete都可以作用域视图,truncate不能作用于视图
(5)执行速度一般是drop > truncate > delete,drop和truncate因为底层修改了数字字典,所以无论大表还是小表都执行非常快,而delete是需要读取数据到undo,所以对大表进行delete全表操作将会非常慢。
(6)安全性方面,drop和truncate在无备份情况下需要谨慎。
想删除部分数据行的话,用delete带上where条件,想删除表数据及结构就用drop,想保留表结构而将所有数据都删除就用truncate。
2. Null有哪些注意事项?
- 判断是否为null只能用 is null 或者 is not null
- 空值是无效的,未指定的,未知的或者不可预知的值,而不是0,也不能说是空格。
- 包含空值的数学运算结果都为空值null
- null在order by排序中默认为最大值,desc在最前,asc在最后,可以加上null last来限制null值的显示
- 大部分函数都不计算空值。count(*)和count(1)是统计表中的数据量,这时不管有没有null值,而假如count(某个具体列),那它也是忽略null值的。
3. 如何判断一个存储过程是否正在运行?
select *
from v$db_object_cache
where type = 'PROCEDURE'
and locks > 0
and pins > 0;
select * from all_objects where object_type = 'PROCEDURE' and object_name = 'AW_TRUNC_PROC';
4. 如何将文本文件或Excel中的数据导入数据库?
- pl/sql中的文本导入器(tools - text import)
- SQL*Loader
- shell脚本
- excel工具批量生成插入语句
- MySQL的Navicat有功能直接导入。
- Oracle的exp和imp功能
开发类常考题
SQL操作题
1. 怎么将相邻记录合并到一条?
可以利用分析函数lag()函数和lead()函数,他们可以提取前N条记录和后N条记录
select owner,
name,
lag(name, 1, null) over(partition by owner order by name) LAG_NAME
from v$db_object_cache
where type = 'PROCEDURE';
OWNER NAME LAST_NAME
1 APEX_040200 WWV_FLOW_INIT_HTP_BUFFER
2 SYS AW_DROP_PROC
3 SYS AW_TRUNC_PROC AW_DROP_PROC
4 SYS LOGMNR_DDL_TRIGGER_PROC AW_TRUNC_PROC
2. 如果查询的列中含有特殊字符,如通配符“%”和“_”,那么该如何查询这些特殊字符?
SELECT * FROM SCOTT.EMP WHERE NAME LIKE 'A%' ESCAPE ''; -- ESCAPE代表将后面的字符用于转义的意思。
3. 如何随机抽取表SCOTT.EMP的前5条记录?
使用ROWID来查询:
SELECT * FROM (SELECT * FROM SCOTT.EMP ORDER BY SYS_GUID()) WHERE ROWID <= 5;
函数相关
1. Oracle常用日期处理函数有哪些?他们的作用是什么?
-
首先要知道Oracle常用的日期数据类型是DATE和TIMESTAMP。DATE可以保存日期和时间,日期范围从公元前4712年1月1日至公元9999年12月31日,数据显示格式是“年 月 日 小时 分 秒”,并且在数据库中的存储固定为7个字节。而TIMESTAMP与DATE的区别是它不仅可以显示日期和时间,还可以保存小数秒,小数位数范围从0-9,默认为6位;数据显示格式是“年 月 日 时 分 秒 小数秒”;在数据库用7个或者11个字节存储,如果精度是0 那么用7个字节存储,如果精度不为0那么用11个字节存储。
注意:如果TIMESTAMP日期类型和数值进行加减运算,那么结果会自动转换为DATE类型,小数秒会被去掉。
-
运算注意:日期加减一个数字结果仍为日期;两个日期相减返回之间相差的天数;
默认的日期格式是“DD-MON-RR”????
-
会用到的修改系统日期格式操作(在遇到日期查询错误时可能要修改日期格式):
-
查询当前数据库日期格式
SELECT SYS_CONTEXT('USERENV','NLS_DATE_FORMAT') FROM DUAL;
-
修改当前会话的日期格式
-
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
--修改日期语音
ALTER SESSION SET NLS_LANGUAGE = 'AMERICAN'; --修改为英文
ALTER SESSION SET NLS_LANGUAGE = 'SIMPLIFIED CHINESE'; --修改为中文
-
常用日期函数:
(1)TO_CHAR(DATE,FORMATSTR) 格式化日期成字符
(2)TO_DATE(CHAR,FORMATSTR) 将字符转换成日期
HH表示12小时进制,HH24表示采用24小时进制,MM表示月份,MI表示分钟。
(3)sysdate :返回当前系统日期和时间,精确到秒;
systimestamp :返回当前系统日期和时间,精确到毫秒;
(4)TRUNC(DATE) 返回DATE的日期部分,时间隐式为0时0分0秒
(5)EXTRACT(DATA FROM DATEVALUE) 返回日期的某一部分内容
SELECT EXTRACT(YEAR FROM SYSDATE) FROM DUAL;
如果DATEVALUE是DATE类型,返回值可以是year,mon,day;
如果DATEVALUE是TIMESTAMP类型,则返回值可以是year,mon,day,hour,min,second;
(6)ADD_MONTHS(DATE,NUMS) 在DATE增减NUMS个月得到新日期。可以用来得到上个月,下个月,去年和下年等。
SELECT ADD_MONTHS(SYSDATE,1) FROM DUAL;
(7)LAST_DAY(DATE) 返回指定日期所在月份的最后一天。
SELECT TO_CHAR(lAST_DAY(SYSDATE),'YYYY-MM-DD') FROM DUAL; --2020-03-31
(8)MONTHS_BETWEEN(DATE1,DATE2) 返回两个日期的月份之差,date1减去date2。
SELECT MONTHS_BETWEEN(ADD_MONTHS(SYSDATE,1),SYSDATE) FROM DUAL;
(9)NEXT_DAY(DATE,CHAR) 从给定日期开始,返回下个CHAR指定星期的日期。
SELECT NEXT_DAY(SYSDATE,'星期二') FROM DUAL;
(10)TO_DSINTERVAL(CHAR) 返回[天 时:分:秒]格式构成的时间间隔,一般用于日期加减运算
select date'2010-2-12'+TO_YMINTERVAL('01-02') newdate from dual; --2011-4-12
(11)NUMTOYMINTERVAL(N,CHAR) 返回CHAR中指定单位的时间间隔数值,一般用于日期加减运算
char可以为YEAR,MONTH
1 SQL> select date '2010-2-12' + NUMTOYMINTERVAL(1, 'year') newdate1, --2011-2-12
2 date '2010-2-12' + NUMTOYMINTERVAL(1, 'month') newdate2 --2010-3-12
3 from dual;
(12)NUMTODSINTERVAL(N,CHAR) 返回CHAR中指定单位的时间间隔数值,一般用于日期加减运算
char可以为DAY,HOUR,MINUTE,SECOND
1 SQL> select date '2010-2-12' + NUMTODSINTERVAL(1, 'DAY') newdate1, --2010-2-13
2 date '2010-2-12' + NUMTODSINTERVAL(1, 'HOUR') newdate2 --2010-2-12 上午 01:00:00
3 from dual;
2. 函数SUBSTR和INSTR有什么区别?
这两个都是字符函数。
但SUBSTR是截取子串,下标从1开始,有三个参数,第一个参数是目标字符串,第二个参数是将要输出的子串的起点,第三个参数是将要输出的子串的长度。如果没有第三个参数,那么将输出余下的全部字符,如果第二个参数为负数,则从目标字符串尾部开始。
而INSTR作用是获取字符的位置,类似于求下标值,它接受4个参数。格式:(目标字符串 匹配的内容 指定搜索的起点 第几次满足条件才会输出),其中第3,4参数默认为1。
在SUBSTR和INSTR结合使用时,需要考虑到INSTR没有获取到匹配内容的情况,可以加DECODE函数或其他函数来转化:
SELECT NAME,
SUBSTR(NAME,1,INSTR(NAME,'A') - 1),
DECODE(INSTR(NAME,'A'),0,NAME,SUBSTR(NAME,1,INSTR(NAME,'A') - 1))
FROM XB_LHR; --处理结果就不会显示为空值
INSTR的特殊用法(以下结果相同):
SELECT * FROM DBA_OBJECTS D WHERE INSTR('5,6,7',D.OBJECT_ID) >0;
SELECT * FROM DBA_OBJECTS D WHERE D.OBJECT_ID = 5 OR D.OBJECT_ID = 6 OR D.OBJECT_ID = 7;
3. NVL,NVL2,NULLIF,COALESCE的区别是什么?
以上几个都是处理字段值为空的转换函数。
NVL(COLUMN,VALUE) 当修饰的icolumn字段值为Null时,运算结果为value,可以使用的数据类型有:日期,字符,数字,函数的参数只能有两个。
NVL2(表达式1,表达式2,表达式3) 如果表达式1的值不为Null,那么显示表达式2的值,否则显示表达式3的值。
NULLIF(表达式1,表达式2) 如果表达式1和表达式2内容相同,那么返回Null,否侧返回表达式1的值
COALESCE(列名,表达式1,表达式2,表达式3…) 用来匹配多个字段的值,如果表达式1的值为空,那么列名显示表达式2的值,以此类推。
(1)和NVL相比,COALESCE的有点在于可以同时处理交替的多个值
(2)返回参数列表中第一个非空的表达式
(3)最后一个表达式通常是一个常量
(4)参数可以有多个,最少一个,可以全是NULL
(5)所有的表达式应该有相同的数据类型。
4. 条件表达式CASE和DECODE的区别是什么?
这两种都使用到了SQL语句的IF-THEN-ELSE结构。
对于CASE表达式,SQL中CASE有两种格式:简单CASE函数和搜索CASE函数。
- 简单CASE
- 搜索CASE
以上两种都可以实现相同的功能,简单case的写法相对简洁,但是功能相对于搜索case会有些限制,比如编写判别式无法用简单case完成。另外要注意的是case函数只返回第一个符合条件的值,剩余的case部分会被忽略,所以在编写case时需要注意编写条件的顺序。ELSE部分可以不加,END AS后面跟别名,AS也可以不加。
DECODE函数的格式如下:
DECODE(VALUE,IF1,THEN1,IF2,THEN2…ELSE),表示如果值符合条件1则输出THEN1的值,一次类推,如果都不符合任何一个IF条件,那么返回空。
使用DECODE时需要注意一下三点:
- Oracle在调用DECODE函数之前,需要预先确定列的数据类型;
- 确定DECODE函数的返回值类型,是根据第一个IF条件的返回值类型,之后的所有的返回类型按按照第一个类型进行强制转换。
- 当Oracle在第一个条件返回类型为Null时,默认会将它当做字符串处理。
5. Oracle常用的替换函数有哪两个?
REPLACE函数和TRANSLATE函数,两个都是替代函数,只不过replace函数针对的是字符串,而translate函数针对的是单个字符。
REPLACE(搜索的字符串,需要匹配的内容,替换后的内容),如果第三个参数省略,那么默认为空,也就是具有删除效果;如果第二个参数为空,那么就不替换任何操作,而只有查询搜索功能。示例如下:
SELECT REPLACE('zhangdongwen','dong','DONG') FROM dual; --zhangDONGwen
TRANSLATE(CHAR,FROM,TO),简单来说,就是将CHAR中FROM的字符转换为TO中与之位置相对应的字符,如果TO中找不到与之对应字符,则返回值中该字符就会被删除。示例如下:
SELECT TRANSLATE('translate','ans','wo') FROM dual; --trwolate
6. 如何判断一个字符串是否含有中文汉字?
7. 在Oracle中有哪些常用的分析函数?
分析函数是Oracle从8.1.6开始引入的一个新概念,为分析数据提供了一种简单高效的处理方法,在没有分析函数之前,实现相同功能需要用到自联查询,子查询,内联查询甚至可能存储过程。Oracle的分析函数主要用于报表开发和数据仓库,强大的分析功能,可以用于SQL的优化,能达到事半功倍的效果。
分析函数的一般格式是:函数名(参数列表)OVER([PARTITION BY 字段或者表达式][ORDER BY 字段或者表达式 ]),其中Over()部分称为开窗函数,开窗函数指定了分析函数工作的数据窗口大小,这个数据窗口会随着行的变化而变化,
整体释义:函数以某个字段patition by 分组,同时在over()开窗函数中制定每个分组的order by排序方式后,从起点至终点进行扫描计算,返回该函数的统计值
下面介绍几个常用的分析函数:
-
LAG和LEAD分析函数
这两个行数可以在一次查询中取出同一字段的前N行和后N行的值,Lag可以访问当前行的前N行,Lead可以访问当前行的后N行。示例如下:
select ename,job,sal ,lag(sal,1) over(partition by job order by sal) last_sal from T_ZDW_EMP190810; --结果显示: 1 FORD ANALYST 3000 -- 2 SCOTT ANALYST 3000 3000 3 SMITH CLERK 800 -- 4 JAMES CLERK 950 800 5 ADAMS CLERK 1100 950 6 MILLER CLERK 1300 1100 7 CLARK MANAGER 2450 -- 8 BLAKE MANAGER 2850 2450 9 JONES MANAGER 2975 2850 10 KING PRESIDENT 5000 -- 11 MARTIN SALESMAN 1250 -- 12 WARD SALESMAN 1250 1250 13 TURNER SALESMAN 1500 1250 14 ALLEN SALESMAN 1600 1500
-
RANK()分析函数
该函数作用是跳跃排序,并给出序号。跳跃排序是指它非连续排名,假如有4个人,其中有3个人并列第一名,那么最后一名的排序序号应该为4,排序结果为1 1 1 4。RANK()分析函数多用于TOP—N查询中。示例如下:
--查询emp表中每个部门中工资前3名的员工信息,如果遇到工资一样的,则排名一样(如部门20所示), --下一级工资排名为跳序,如:1,2,2,2,5... SELECT * FROM (SELECT e.*, rank() over(partition BY deptno order by sal desc) rk FROM T_ZDW_EMP190810 e) t1 WHERE t1.rk <= 3 ; --结果显示: 1 7839 KING PRESIDENT 1981/11/17 5000 -- 10 1 2 7782 CLARK MANAGER 7839 1981/6/9 2450 -- 10 2 3 7934 MILLER CLERK 7782 1982/1/23 1300 -- 10 3 4 7788 SCOTT ANALYST 7566 1987/4/13 3000 -- 20 1 5 7902 FORD ANALYST 7566 1981/12/3 3000 -- 20 1 6 7566 JONES MANAGER 7839 1981/4/2 2975 -- 20 3 7 7698 BLAKE MANAGER 7839 1981/5/1 2850 -- 30 1 8 7499 ALLEN SALESMAN 7698 1981/2/20 1600 300 30 2 9 7844 TURNER SALESMAN 7698 1981/9/8 1500 -- 30 3
-
DENSE_RANK()分析函数
和Rank()函数类似,但dense_rank()函数可以给出连续排名。即假如有4个人,其中有3个人并列第一名,那么最后一名的排序序号应该为2,排序结果为1 1 1 2。示例如下:
--查询emp表中每个部门中工资前3名的员工信息,如果遇到工资一样的,则排名一样, --下一级工资排名为顺序,如:1,2,2,2,3... SELECT * FROM (SELECT e.*, dense_rank() over(partition BY deptno order by sal desc) rk FROM T_ZDW_EMP190810 e) t1 WHERE t1.rk <= 3; --结果显示: 1 7839 KING PRESIDENT -- 1981/11/17 5000 -- 10 1 2 7782 CLARK MANAGER 7839 1981/6/9 2450 -- 10 2 3 7934 MILLER CLERK 7782 1982/1/23 1300 -- 10 3 4 7788 SCOTT ANALYST 7566 1987/4/13 3000 -- 20 1 5 7902 FORD ANALYST 7566 1981/12/3 3000 -- 20 1 6 7566 JONES MANAGER 7839 1981/4/2 2975 -- 20 2 7 7876 ADAMS CLERK 7788 1987/5/13 1100 -- 20 3 8 7698 BLAKE MANAGER 7839 1981/5/1 2850 -- 30 1 9 7499 ALLEN SALESMAN 7698 1981/2/20 1600 300 30 2 10 7844 TURNER SALESMAN 7698 1981/9/8 1500 -- 30 3
-
First_value()分析函数和Last_value()分析函数
first_value()取首记录值,last_value()取尾记录值。
除此之外,还有 Max()、Min()、Sum()、Avg()、Count()与Over()分析函数的一般语法配合使用。
8. Oracle中的正则表达式用到哪四个函数?
- REGEXP_LIKE
- REGEXP_INSTR
- REGEXP_SUBSTR
- REGEXP_REPLACE
9. Oracle中有哪些常用的字符函数?
常用的有如下几个函数:
- lower(char)将字符串全部转为小写的格式;
- upper(char)将字符串全部转化为大写的格式;
- initCap(char)每个单词首字母大写其余小写
- concat(char1,char2…)字符拼接函数
- length(char)返回字符串的长度
- substr(char,m,n) 字符串的子串,从m开始去n位
- replace(char,search_string,replace_string)替换函数
- instr(char,search_string,start,num)获取字符的位置,配置到的内容,从start开始,获取第Num次的位置。
- trim(char)去掉左右两边空格,制表符等。
- ltrim(char)左边去掉空格,制表符等
- rtrim(char)右边去掉空格,制表符等
- lpad(salary,10,’#’)左补齐,比如#####24000
- rpad(salary,10,’#’)右补齐,比如24000#####
- chr(ascii)将ascii转换成字符
- ascii(char)将字符转换成ascII码
高级操作
1. Oracle行列互换有哪些方法?
准备数据:
create table kecheng
(
id NUMBER,
name VARCHAR2(20),
course VARCHAR2(20),
score NUMBER
);
insert into kecheng
(id, name, course, score)
values
(1, ‘张三’, ‘语文’, 67);
insert into kecheng
(id, name, course, score)
values
(1, ‘张三’, ‘数学’, 76);
insert into kecheng
(id, name, course, score)
values
(1, ‘张三’, ‘英语’, 43);
insert into kecheng
(id, name, course, score)
values
(1, ‘张三’, ‘历史’, 56);
insert into kecheng
(id, name, course, score)
values
(1, ‘张三’, ‘化学’, 11);
insert into kecheng
(id, name, course, score)
values
(2, ‘李四’, ‘语文’, 54);
insert into kecheng
(id, name, course, score)
values
(2, ‘李四’, ‘数学’, 81);
insert into kecheng
(id, name, course, score)
values
(2, ‘李四’, ‘英语’, 64);
insert into kecheng
(id, name, course, score)
values
(2, ‘李四’, ‘历史’, 93);
insert into kecheng
(id, name, course, score)
values
(2, ‘李四’, ‘化学’, 27);
insert into kecheng
(id, name, course, score)
values
(3, ‘王五’, ‘语文’, 24);
insert into kecheng
(id, name, course, score)
values
(3, ‘王五’, ‘数学’, 25);
insert into kecheng
(id, name, course, score)
values
(3, ‘王五’, ‘英语’, 8);
insert into kecheng
(id, name, course, score)
values
(3, ‘王五’, ‘历史’, 45);
insert into kecheng
(id, name, course, score)
values
(3, ‘王五’, ‘化学’, 1);
$$
-
列转行
就是将原表中的列作为转换后的表的内容,主要采用Union All来操作。
-
行转列
将行数据内容作为列明。主要采用MAX(或者SUM)和DECODE函数完成。
或者可以用pivot(聚合函数 for 列名 in(类型)),其中 in(’’) 中可以指定别名,in中还可以指定子查询,比如 select distinct code from customers。
SELECT NAME,
MAX(DECODE(COURSE, '语文', SCORE, NULL)) 语文,
MAX(DECODE(COURSE, '化学', SCORE, NULL)) 化学,
MAX(DECODE(COURSE, '历史', SCORE, NULL)) 历史,
MAX(DECODE(COURSE, '数学', SCORE, NULL)) 数学,
MAX(DECODE(COURSE, '英语', SCORE, NULL)) 英语
FROM KECHENG
GROUP BY NAME;
1 王五 24 1 45 25 8
2 李四 54 27 93 81 64
3 张三 67 11 56 76 43
select *
from (select name, nums from demo)
pivot(sum(nums)
for name in( '苹果', '橘子', '葡萄', '芒果'));
苹果 橘子 葡萄 芒果
1 7000 8000 3500 9700
- 多列转换成字符串,可以采用||或者CONCAT函数完成。
SELECT CONCAT('A','B') FROM DUAL;
- 多行转换成字符串,可以采用SYS_CONNECT_BY_PATH或者聚合函数(MAX+DECODE)和分析函数(ROWNUM())来完成。如果是在mysql,那么直接有一个group_concat()函数可以完成。
SELECT id,
MAX(decode(rn, 1, col, NULL)) ||
MAX(decode(rn, 2, ',' || col, NULL)) ||
MAX(decode(rn, 3, ',' || col, NULL)) str
FROM (SELECT id,
col,
row_number() over(PARTITION BY id ORDER BY col) AS rn
FROM t_row_str) t
GROUP BY id
ORDER BY 1;
1 1 a,b,c
2 2 a,d,e
3 3 c
--Oracle中SYS_CONNECT_BY_PATH的完成方式,暂时未知该函数使用方法
SELECT t.id id,
MAX(substr(sys_connect_by_path(t.col, ','), 2)) str
FROM (SELECT id,
col,
row_number() over(PARTITION BY id ORDER BY col) rn
FROM t_row_str) t
START WITH rn = 1
CONNECT BY rn = PRIOR rn + 1
AND id = PRIOR id
GROUP BY t.id;
-
字符串转换成多列
实际上是用substr和instr来进行字符串拆分的问题
-
字符串转换成多行
主要采用UNION ALL,SUBSTR和INSTR来完成。
2. 如何分批插入,分批更新,分批删除,分批提交?
主要采用游标加BULK COLLECT的方式来实现,用LIMIT来限制每次需要操作的行数,其中分批更新也可以采用游标For循环加ORDER BY排序的方式,效率也很高。
3. 如何删除表中重复的记录?
删除表中重复记录有两种情况:
-
第一种是重复的记录要求全部删除
-
第二种是重复的记录要求只保留最新的一条记录。
在Oracle中每条记录都有一个ROWID,并且这个ROWID是唯一的,重复的记录可能列内容一样,但是ROWID不会相同,可以利用ROWID去删除重复记录。
针对第一种,利用group by 重复的字段找出总数大于1就可以找到重复的字段值。
DELETE FROM 表名 WHERE 字段 IN (SELECT 字段 FROM 表名 GROUP BY 字段 HAVING COUNT(1) >1);
对于第二中,就利用ROWID和聚合函数MAX来保留最新一条记录。
DELETE FROM 表名 WHERE ROWID NOT IN (SELECT MAX(ROWID) FROM 表名 GROUP BY 字段 ;
SYS_CONTEXT和USERENV的用法是什么?他们可以返回哪些常用的值?
SYS_CONTEXT函数是Oracle提供的一个获取环境上下文信息的预定义函数,该函数用来返回一个指定NAMESPACE下的PARAMETER值,该函数可以在sql和pl/sql使用,常用返回值如下:
SELECT SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA') CURRENT_SCHEMR,
SYS_CONTEXT('USERENV', 'CURRENT_SQL') CURRENT_SQL,
SYS_CONTEXT('USERENV', 'STATEMENTID') STATEMENTID,
SYS_CONTEXT('USERENV', 'TERMINAL') TERMINAL
FROM DUAL;
1 SYS SC-201911020948
USERENV函数用来返回当前的会话信心,常用如下:
SELECT USERENV('CLIENT_INFO') CLIENT_INFO,
USERENV('LANGUAGE') 数据库字符集,
USERENV('ISDBA') 是否DBA角色,
USERENV('TERMINAL') 当前计算机名
FROM DUAL;
1 SIMPLIFIED CHINESE_CHINA.ZHS16GBK TRUE SC-201911020948
4. 怎样创建一个一个索引,索引使用的原则,有什么优点和缺点
创建标准索引:
CREATE INDEX 索引名 ON 表名 (列名) TABLESPACE 表空间名;
创建唯一索引:
CREATE unique INDEX 索引名 ON 表名 (列名) TABLESPACE 表空间名;
创建组合索引:
CREATE INDEX 索引名 ON 表名 (列名1,列名2) TABLESPACE 表空间名;
创建反向键索引:
CREATE INDEX 索引名 ON 表名 (列名) reverse TABLESPACE 表空间名;
索引使用原则:
- 索引字段建议建立NOT NULL约束
- 经常与其他表进行连接的表,在连接字段上应该建立索引;
- 经常出现在Where子句中的字段且过滤性很强的,特别是大表的字段,应该建立索引;
- 可选择性高的关键字 ,应该建立索引;
- 可选择性低的关键字,但数据的值分布差异很大时,选择性数据比较少时仍然可以利用索引提高效率
- 复合索引的建立需要进行仔细分析;尽量考虑用单字段索引代替:
- 正确选择复合索引中的第一个字段,一般是选择性较好的且在where子句中常用的字段上;
- 复合索引的几个字段经常同时以AND方式出现在Where子句中可以建立复合索引;否则单字段索引;
- 如果复合索引中包含的字段经常单独出现在Where子句中,则分解为多个单字段索引;
- 如果复合索引所包含的字段超过3个,那么仔细考虑其必要性,考虑减少复合的字段;
E、如果既有单字段索引,又有这几个字段上的复合索引,一般可以删除复合索引; - 频繁DML的表,不要建立太多的索引;
- 不要将那些频繁修改的列作为索引列;
索引的优缺点:
优点:
-
- 创建唯一性索引,保证数据库表中每一行数据的唯一性
-
- 大大加快数据的检索速度,这也是创建索引的最主要的原因
-
- 加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
-
- 在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。
缺点:
-
- 索引创建在表上,不能创建在视图上
-
- 创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加
-
- 索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大
-
- 当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度
5. Oracle如何解锁?
6.热备份和冷备份的区别是什么?
热备份是数据库在运行的情况下,采用归档方式备份数据的方法,针对归档模式的数据库,在数据库仍处于工作状态时进行备份。
而冷备份是指数据库在正常关闭情况下,将关键性文件复制到另外位置的备份方式,适用于所有模式的数据库。
热备份的优点在于当备份时,数据库仍旧可以被使用并且可以将数据库恢复到任意一个时间点。冷备份的优点在于它的备份和恢复操作相当简单,并且由于冷备份的数据库可以工作在非归档模式下,数据库性能会比归档模式稍好。
分区表
1. 分区表有什么优点?分区表有哪几类?如何选择用哪种类型的分区表?
当表中数据量不断增大到很大时,查询速度就会变慢很多,应用程序性能会下降,这时候可以考虑使用分区表,对表进行分区,在逻辑上它仍然是一张表,但物理上是将表中的数据存放到多个表空间或物理文件上,查询时不会每次都扫描整张表,而只针对特定的分区扫描查询,这样就能提供更好的数据处理和访问的性能。
分区表主要有以下几种优点:
-
维护轻松,可用性强:假如系统故障破坏了表的某些分区,那只需要维护这部分分区,其他分区还可以正常访问
-
均衡的I/O性能:可以把表的不同分区分配到不同的磁盘来平衡I/O
-
改善性能,对用户透明:对大表的DML等操作可以分解到表的不同分区来并行执行,速度更快,而最终用户感觉不到分区的存在。
对于何时考虑分区,一般是针对大表进行分区,有益于大表操作的性能和数据维护,通常当表的大小超过2GB或者对于OLTP系统当表的数据量超过1000万条时都可以考虑。
但具体如何考虑设置分区,还关联到分区的以下几种类型:
-
范围分区(RANGE PARTITION) 在以下几种情况会用到:
-
频繁地被一个时间范围谓词扫描
-
维护一个时间滚动的数据窗口
-
保存历史数据
比如某个大表需要按照不同年,月,日的时间来保存历史数据,就可以设置为年分区,月分区,日分区,在增量模式中就可以根据这些分区值批量更新插入到历史数据表中。
-
-
哈希分区(HASH PARTITION) 哈希分区有以下的优点可以考虑:
-
提高大表的高可用性和可管理性
-
可以避免数据倾斜,将数据均匀地分布在多个物理设备上,最大化I/O吞吐量。
-
分区修剪和分区只能连接
-
要求分区键是高基数列
-
分区修剪不支持基于分区字段的范围查询,只支持等值查询或IN-LIST查询。
哈希分区可以参考阿里云的ADS库,其分区方式就是用到了哈希分区,并通过设置二级分区,聚集列等方式来避免数据倾斜。
-
-
列表分区(LIST PARTITION) 列表分区提供了一种按照字段的值来进行分区的方法,适用于有高重复率字段值的表,它有如下特点:
-
列表值是离散的
-
列表值是无序的
-
分区键只能包含一个列
-
列表值是低基数的
参考广东省每个地市的不同行政区划代码,这些记录行政区划代码的字段就可以作为列表分区
-
-
复合分区(组合分区) 在分区内再建子分区的方式,比如设置一级分区,二级分区,常用的是范围分区+哈希分区或者范围分区+列表分区。
-
INTERVAL(间隔分区)
-
系统分区
另外,INTERVAL(间隔分区),系统分区是Oracle 11g的新特性,暂不讨论,其他四种在大数据平台数据处理中都有所使用到。
对于海量的数据库设计中,选择哪种类型的分区表设计很重要,考虑范围分区,哈希分区,列表分区哪一种作为分区表可以总结为以下三点:
(1)如果需要数据的过期化处理,那么考虑范围分区(比如有些大表要求只保留7天的数据或者增量改造时通过时间分区更新到历史数据)
(2)如果需要数据均匀分布,以便有更好的性能,那么可以考虑哈希分区(参考ADS库)
(3)如果数据的值可以很好的对应某个分区,那么考虑用列表分区(比如行政区划代码或者税务机关代码)。
最后,如果选择的分区键不能确保各分区内数据量的平均,容易造成数据倾斜,那么这种分区方式很可能是不正确的,需重新考虑分区键。
2. 分区表常用数据字典视图有哪些?
Oracle分区表相关的数据字典视图如下:
- 显示数据库所有分区表的信息:DBA_PART_TABLES
- 显示分区信息,显示数据库所有分区表的详细分区信息:DBA_TAB_PARTITIONS
- 显示子分区信息,显示数据库所有复合分区表的子分区信息:DBA_TAB_SUBPARTITIONS
- 显示分区列,显示数据库所有分区表的分区列信息:DBA_PART_KEY_COLUMNS
- 显示子分区列,显示数据库所有分区表的子分区列信息:DBA_SUBPART_KEY_COLUMNS
SELECT * FROM DBA_PART_TABLES;
SELECT * FROM DBA_TAB_PARTITIONS;
SELECT * FROM DBA_TAB_SUBPARTITIONS;
SELECT * FROM DBA_PART_KEY_COLUMNS;
SELECT * FROM DBA_SUBPART_KEY_COLUMNS;
3. 普通表转换为分区表有哪些方法?
这里只讲通用的,可能还有其他方法后面需要补充(比如大数据中如何转分区表)
- 导出/导入方法
- 子查询插入法
- 分区交换数据法
- 在线重定义(Oracle的,了解就行)
(1)导入导出方法:
逻辑很简单,就是先导出数据和数据结构,再建立分区表,然后重新导入到分区表即可。
但这种方法实施过程中,目标表不能进行DML操作,适用于业务量较小的表
- 导出表:exp usr/psed tables=T_TEST_LHR file=exp_lhr.dmp
- 删除表:DROP TABLE T_TEST_LHR;
- 重建分区表的定义:
CREATE TABLE T_TEST_LHR(QTY NUMBER(3),NAME VARCHAR2(15))
PARTITION BY RANGE(QTY)(PARTITION P1 VALUES LESS THAN (501),
PARTITION P2 VALUES LESS THAN (MAXVALUE));
- 利用ignore=y来导入分区表:imp usr/pswd file=exp_lhr.dmp ignore=y
(2)子查询插入法
采用CTAS的方式创建分区表,方法简单易用,不会产生undo日志,而还有少量redo日志,效率相对较高,而且建表完成数据也传输完成。
缺点是数据的一致性需要考虑,在执行完后要对数据进行检查,代价比较高,另外过程中T表不能DML,
适用于修改不频繁的表,在闲时进行,表的数据量不宜太大。
CREATE TABLE T_NEW(ID,TIME) PARTITION BY RANGE(TIME)
(PARTITION T1 VALUES LESS THAN (TO_DATE('201311',YYYYMM)),
PARTITION T2 VALUES LESS THAN (TO_DATE('201606',YYYYMM)),
PARTITION T3 VALUES LESS THAN (MAXVALUE))
AS SELECT ID,TIME FROM T;
--然后改名
RENAME T_NEW TO T;
(3)分区数据交换法
指定分区交换命令。只对数据字典中分区和表的定义作修改,如果没有数据的修改或复制,效率最高,如果原来的表有数据,直接将这些数据插入到新表中。
缺点是存在数据一致性问题,如果要求多个分区,需要进行分区的SPLIT操作,增加复杂度,适用于大数据量并且尽量在系统空闲时操作。
CREATE TABLE T_NEW(ID NUMBER PRIMARY KEY,TIME DATE)PARTITION BY RANGE(TIME)
(PARTITION T1 VALUES LESS THAN (TO_DATE('2013-11-1','YYYY-MM-DD')),
PARTITION T2 VALUES LESS THAN (MAXVALUE));
--交换数据
ALTER TABLE T_NEW EXCHANGE PARTITION T1 WITH TABLE T;
(4)在线重定义法
性能强大,但实现比较复杂,适用于7*24系统。
EXEC DBMS_REDEFINITION.START_REDEF_TABLE(USER,'T','T_NEW','ID ID,TIME TIME',DBMS_REDEFINITION.CONS_USE_PK);
EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE(USER,'T','T_NEW');
索引
1. 索引的定义?索引的优缺点有哪些?
索引的概念和目录很相似,索引是对某些特定的列中的数据排序,生成独立的索引表,如果索引列出现在查询条件中,那么数据库就会自动引用该索引,先从索引表中查询出符合条件的ROWID,由于ROWID记录物理地址,所以能快速的定位到具体的记录,从而提高查询效率。
创建索引能极大提高系统性能,优点如下:
- 加快数据的检索速度
- 加速表和表直接的连接
- 索引能有效减少磁盘I/O
- 当使用group by 和order by时,可以显著减少排序和分组的时间
- 创建唯一性索引,可以保证数据库中每一行数据的唯一性
- 通过使用索引,可以在查询过程中使用优化隐藏起,提高系统性能。
但也有明显的缺点,主要体现在后期维护索引较困难,创建索引和维护索引都要花时间,并且数据量越大越不好维护。并且索引建立需要占用物理空间,如果是聚族索引需要的空间更大,索引也不能建立在视图之上。
2. 哪些情况下可以考虑用索引?
(1)大表考虑建立索引比较有意义
(2)在where子句或是连接条件经常引用的列上建立索引。
(3)经常出现在关键字group by ,order by,distinct上的字段,最好建立索引。
(4)如果某属性常作为最大值或最小值等聚集函数的参数,那么可以考虑该属性建立索引。
(5)表的主键,外键必须有索引
(6)经常和其他表进行连接的表,在连接字段建立索引
(7)索引应该建立在小字段上,对于大的文本字段甚至超长字段,不适合建立索引
(8)对于那些查询中很少涉及的列,重复值比较多的列不适合建索引
(9)复合索引的前导列要考虑好,一般是选择性较好的字段
(10)索引的层次不要超过4层
(11)频繁进行DML的列,不要建索引
(12)删除无用的索引。
(13)如果既有单字段索引又有复合索引,那么可以考虑删除掉复合索引,还有复合索引一般的字段不超过3个。
’
3. 索引的分类?
- 普通索引:仅加速查询
- 唯一索引:加速查询 + 列值唯一(可以有null)
- 主键索引:加速查询 + 列值唯一(不可以有null)+ 表中只有一个
- 组合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并
还有其他索引,根据不同数据库支持不同类型的索引,暂时未更新。
SQL优化相关
1.SQL优化在写法上有哪些常用方法?
(1)SELECT子句中避免使用“ * ”,应该写出具体需要查询的字段,使用*来查询出所有的字段其实是非常低效的,在解析sql过程中,需要查询数字字典来将 * 转换成所有列名,这会消耗更多的时间,另外加入某张表中有LOB类型的字段,这种字段可以存储JSON格式的数据,在读取时是会非常耗时的。
(2)尽量使用表的别名。可以减少解析时间和减少那些由列歧义而引起的语法错误。
(3)避免隐式转换。如果要进行比较的两个值数据类型不同,那么会将其中一个值进行类型转换使其能够比较,每行都进行转换会导致性能问题。另外,通常比较两个数据类型不同的值时,会自动地从复杂向简单的数据类型转换,由于添加函数到索引列所以导致索引列不被使用,影响查询。比如将数值类型存储在字符列时,如果不加单引号就会隐式转换,影响速度。
例如,假设USER_NO时一个字符类型的索引列
SELECT USER_NO,USER_NAME FROM USER_TABLE WHERE USER_NO = 109204421;
--这条语句会被隐式转换为:
SELECT USER_NO,USER_NAME FROM USER_TABLE WHERE TO_NUMBER(USER_NO) = 109204421;
正确写法应加单引号:
SELECT USER_NO,USER_NAME FROM USER_TABLE WHERE USER_NO = '109204421';
(4)避免使用耗费资源的操作,包括DISTINCT, UNION, MINUS, INTERSECT, ORDER BY, GROUP BY 等,能用DISTINCT的就不要用GROUP BY,能用UNION ALL的就不要用UNION。
(5)避免写过于复杂的SQL,不一定要一个SQL来解决问题,可以将一个大的SQL改写成多个小的语句。
(6)应尽量避免在where条件中对字段进行函数,算术运算或其他表达式等操作,因为可能会使索引失效,查询时要考虑做优化,将这些操作移至等号右边。
例如:
SELECT * FROM T1 WHERE SUBSTR(ID,1,4) = '5678';--这种不会利用索引,而走全表扫描
--改写后如下:
SELECT * FROM T1 WHERE ID LIKE'5678%';
SELECT * FROM T1 WHERE TO_CHAR(CREATED,'YYYY') = '2020';
--改写后如下:
SELECT * FROM T1 WHERE CREATED >= TO_DATE('20200101','YYYYMMDD') AND CREATED < TO_DATE('20210101','YYYYMMDD');
(7)合理使用分析函数
(8)应尽量避免在where条件中使用不等操作符!=或<>,因为这样引擎会放弃索引而使用全表扫描。
(9)尽可能减少关联表的数量,关联表尽量不要超过3张
(10)慎用IN,因为IN会让索引失效。可以改为BETWEEN …AND …;
(11)对于分区表,要减少需要扫描的分区,查询中在分区表加partition,避免全分区扫描。
(12)使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表,比如下面的两条语句可以改写成一条语句,从而只对SCOTT.EMP表访问一次:
SELECT COUNT(*),SUM(SAL) FROM SCOTT.EMP WHERE DEPTNO = 20 AND ENAME LIKE 'SMITH';
SELECT COUNT(*),SUM(SAL) FROM SCOTT.EMP WHERE DEPTNO = 30 AND ENAME LIKE 'SMITH';
SELECT
COUNT(DECODE(DEPTNO,20,1,NULL)) D20_COUNT,
COUNT(DECODE(DEPTNO,30,1,NULL)) D30_COUNT,
SUM(DECODE(DEPTNO,20,SAL,NULL)) D20_SAL,
SUM(DECODE(DEPTNO,30,SAL,NULL)) D30_SAL
FROM SCOTT.EMP WHERE ENAME LIKE'SMITH';
(13)用where字句替换Having子句,因为Having子句只会在检索出所有的记录后才会对结果集进行过滤。
(14)必要时使用Hint强制优化查询。比如:
2. count(*) count(1)与count(col)的区别
-
从执行结果看,count(*)和count(1)都是统计行数,count(col)是统计列中非空的行数。
-
从执行效率看,如果在开发中需要用到count函数,那么优先考虑count( * ),因为在mysql中对count( * )做了优化处理,当然还是要视在那种数据库引擎上查询。
如果有主键或复合主键的情况下,count * 比count(1)快些;
如果没有主键情况下,count(1)比较快
如果表中只有一个字段,那么count * 是最快的。
count * ,count(1),count 字段如果有主键或者索引,都会优先走索引。
3.数据库中索引会失效的几种情况?
(1)没有where字句。有索引的字段必须要在where条件后使用才会有效。
(2)使用is null或者is not null会让索引失效。
(3)where子句中对字段使用函数,算术运算或者表达式会使索引失效,但是可以优化成将这些操作放在等号右边,就能用上索引。
(4)使用like进行模糊查询中,如果索引列的值的第一个字符被模糊查询到,那么将不会使用索引。比如以下:
SELECT * FROM STUDENT WHERE NAME LIKE 'AAA%'; --走索引
SELECT * FROM STUDENT WHERE NAME LIKE '%AAA'; --或者‘_AAA’都不会走索引,只要第一个字符被模糊搜索了就不会走索引。
(5)索引列同时用等于号和范围索引,通常只会使用第一个索引,第二个索引不生效。
(6)where条件使用了不等于号操作!=或<>
(7)索引列用来比较不匹配的数据类型,这种情况下会发生隐式转换,给索引列套上函数进行转换,导致索引失效。
- 知识点结构图
修改记录
时间 | 内容 |
---|---|
2020年4月09日 | 第一次发布,未排版 |
2020年9月21日 | 新增知识点结构图 |
- 参考文献:
《Oracle程序员面试笔试宝典》
最后
以上就是幸福薯片为你收集整理的Oracle面试笔试题集的全部内容,希望文章能够帮你解决Oracle面试笔试题集所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复