【转载】Oracle数据库总结

在网上看到一篇很好的Oracle,转载过来以便保存,同时分享给需要的朋友们吧
本文【转载】自http://blog.sina.com.cn/s/blog_a44e6f3801012ur1.html

数据库,顾名思义,就是一个存放数据的仓库,但是数据不是随意的存放在数据库里面,而是通过“方案”(schema)来组织和管理数据的。方案里可以存储表,视图,索引,触发器,存储过程,存储函数等。在数据库中,所创建的每一个用户都有自己的一个方案名,每一个用户的数据对象都是存储在自己的方案中,如果当前用户要访问自己方案中的数据对象,是不需要添加方案名的,如果当前用户要访问其他用户中的表,则需要在所要访问的数据对象前面添加该数据对象的所属的方案名。例如,system用户要访问scott用户下的emp表。语句如下:

select * from scott.emp;

  oracle的数据库的标准语言是SQL语言,SQL语言可以在数据库做,数据查询(DQL)、数据定义(DDL)、数据更新(DML)、数据控制(DCL)。语言简洁,易学易用。说的再通俗一点就是每个查询,就像一句英语话一样。举个例子:

select ename,job,sal from emp where ename=’SCOTT’;

该sql语句所要表示的是:我要查询emp表中员工名为SCOTT的工作和薪水。

sql语言可以对表、视图、索引等进行定义、更新和删除。对于数据的插入、更新与删除都是数据的更新。下面来说一下对表的定义、更新、删除以及要注意的事项。

一、表结构定义

1.创建表

create table table_name(field_name data type(length) field_constraint…)

constraint constraint_name constraint_type (field…);

create为定义表的关键字,table为表关键字。

定义表的注意事项:

⑴表名要尽量短,而且说明该表的主要特征。表名要避免使用关键字。表名不区分字母大小写。

⑵约束级可分为字段级约束和表级约束。如果某个约束只作用于一个字段,则在此字段定义后写出字段级约束。如果某个约束作用于两个或者两个以上的字段,则需要在所有字段定义完之后再使用constraint子句来定义表级约束。

2.修改表

我们定义出来的表不一定就是非常完美的,也许有问题的,例如我们的表名或字段名定义的时候输入错了,数据类型、长度或约束条件定义不妥,那我们就需要使用修改命令修改表中的相关内容。需要修改表的相关操作包括修改表名、表字段、表结构。

修改表名

如果我们觉得表名的定义不合适,可以使用修改表名命令来完成。

格式:rename 旧表名 to 新表名; 其中 rename是表名重命名的关键字。

修改表字段

修改字段名命令格式如下:

alter table 表名 rename column 旧字段名 to 新字段名;

修改表结构

我们在定义表的时候,发现字段数据或约束条件定义不妥,则需要修改表结构。

alter table table_name add field_name datatype(length) constraint…;
alter table table_name drop column field…;
alter table table_name modify field_name field_datatype(length)…;

其中,alter是修改操作的关键字,add子句向表中添加字段,drop子句从表中删除字段,modify子句修改表中已有字段。

3.删除表

当我们数据中有一些废弃的表,不再需要了,那我们就可以删除此表,以释放该表所占用的存储空间。但是在实际应用中,不建议使用该操作,因为在实际应用中,删除表是一件可怕的事情,如果不小心删除了一张以后还要使用的表。那可就犯错误咯。

删除表的格式如下:

drop table table_name;

二、索引

当我们拥有的表中的数据量达到了一定值的时候,数据查询的速度则会大大降低,直接影响了系统的性能

为了能加快查询速度,我们就需要针对锁查询的字段来创建索引。一个表中可以有多个索引,索引需要先

义,然后由数据库管理系统在执行数据查询的时候自动调用。索引的命令如下:

create (unique) index index_name on table_name(field_name order …);

其中index是定义索引的关键字,unique是指定该索引类型是唯一的,及该索引列的值是不能重复的,像这种类型的索引,都是建立在主键上面的。例如,员工表中的员工编号是不会出现重复的,那么就可以创建唯一索引了。次序是指定索引值的排列顺序,asc表示升序,desc 表示降序,默认为升序。当我们的查询条件发生变化时,查询的时候不再涉及到某个字段,该字段上所定义的索引也就不需要了,我们就可以删除该索引,以释放该索引所占用的表空间。关于索引的使用我们要注意到几点:1.使用索引的目的 2.何时使用索引

我们使用索引是为了提高查询速度,减少I/O操作。所以我们要合理的使用索引。现在说一下,怎么合理索引。

1.经常检索排序的大表中40%或非排序表7%的行,建议建索引;

2.为了改善多表关联,索引列用于联结;

3.列中的值相对比较唯一;

4.取值范围(大:B*树索引,小:位图索引);

5.date型列一般使用基于函数的索引;

6.列中有许多空值,不适合建立索引;

7.经常一起使用的多个字段检索记录,组合索引比单列索引更有效;

8.限制每个表中索引的数量,对于频繁插入和更新的表来说的话,索引越多,系统CPU.I/O负担越重。索引根据所不同的表,建立不同的索引;

9.删除不再需要的索引,如果在以后的查询中不再使用到索引,那就可以删除该索引,重新建立索引前需要先删除索引,如果使用alter index index_name on table_name(field_name,order) rebuild 重建索引,则不需要删除索引。

三、表数据的增删改查

3.1、数据插入

当我们的表创建好了之后,那就要开始插入数据,插入数据的方法有有三种方法,我们就要根据自己不同的需求来选择不同的插入方式来完成数据插入。

1、单行数据插入 顾名思义,就是对数据表插入一行数据。
insert into 表名(字段名1,…) values(字段值1,…);

2、多行数据插入 
①单条语句插入多行数据insert into 表名(字段名1,…) values(字段值1,…),(字段值11,…),…;
②从其他表中复制而来 insert into 表名(字段名1,…) select 字段名1,… from 源表 …;

3、复制表
create table 表名 as select * from 旧表名;
4.更新表
我们插入过数据之后,可以会出现数据插入有误,那我们就要使用update命令进行修改。
SQL两种修改数据的方法。
1.直接赋值修改使用update命令直接将表中的数据修改为确定值。这种方法是我们日常中应用中最为常用的。
2.嵌套修改将数据表中的数据修改为从其他数据对象中所取得的数据值,为了更好的理解,
举一个例子,将员工SCOTT的工作和薪水修改成和员工SMITH一样的工作和薪水,命令如下:

update emp set (job,sal) = (select job,sal from emp where ename=’SMITH’) where ename=’SCOTT’;

3.2、数据删除

当某些表中的数据我们不再需要的时候,我们就可以删除此数据.sql给我们提供了两种删除方法。

1、删除所选行的数据 delete命令可以从表中删除所选行的数据。这在日常应用中最为常用。

2、整表数据删除 truncate命令可以删除整个表的数据,整表的数据已经被删除了,表定义还存在。该命令所做的删除不能回滚,对于已经删除的数据不能恢复,为永久删除。truncate命令在日常应用,应尽量避免使用,以免造成严重的后果。

3.3、数据查询

当我们把数据表定义过并插入数据之后,就要考虑查询数据表中的数据了。SQL给出了: 
1.单表查询,顾名思义,就是对于一个数据表的查询,而在实际应用中很少出现对一个表的查询。
2.多表查询,对于两个或多个数据表的查询,在实际应用中应用的非常多,在进行多表查询的时候,我们要注意多表查询的条件:多表查询中的条件个数不能少于数据表的个数-1,这样才可以排除笛卡尔积。
3.嵌套查询,在实际查询中,我们利用某个查询的执行结果来作为其他查询的条件,那样我们就可以使用嵌套查询来查询。
4.分组查询,以数据表中某个字段作为分组条件,来进行分组查询.例如对一个部门表的查询,我们可以以部门表中的部门号作为分组条件,可以查询每个部门的信息状态。

在实际应用中,我们在查询数据表的时候,表的结构以及表中的某些信息不想向无关人员透漏,为了保证数据表中数据的安全性,我们可以采用视图来完成对数据表中数据的安全性,提高数据的隐蔽性。视图是从表中用select语句所导出来的一张虚表。视图分为只读视图和可修改视图,只读视图,表示该视图只能读,不能进行添加、修改和删除。可修改视图,可以对视图进行添加、修改和删除,但更新的数据必须满足视图中所包含的字段。对于视图的修改使用 or replace加以实现修改。

四、PL/SQL

在前面所介绍的sql语言可以在数据库中进行各种操作,但是SQL语言却是作为独立语言SQL Plus应用环境中使用的,语句之间是相互独立的。在实际应用中,许多事务处理都是过程性的,前后语句之间有一定的关联。oracle公司推出了PL/SQL过程化SQL语言,可以把变量、控制语句、存储过程和存储函数应用到sql语言中,提高程序执行的效率,下面来进一步说一下PL/SQL。

PL/SQL所编写出来的程序称为PL/SQL程序块,完整的PL/SQL程序块包含3个基本部分:声明部分、执行部分和异常处理部分。

声明部分以declare为开头,主要是定义执行部分所要用到的变量、常量、游标等。执行部分以begin为开头,以end为结束。其中包含对数据库的数据操纵语句,执行部分可以把一条或者多条sql语句组织起来,提高程序块的执行效率。异常处理部分是包含在执行部分中的,以exception为开头,异常处理部分对程序在执行过程中所出现的异常情况进行处理。上面所说的三个部分,执行部分是必须的,定义部分和异常处理部分是可以省略的。现在介绍过了PL/SQL程序块的基本机构,现在进一步说一下PL/SQL程序块。

4.1、数据类型

PL/SQL的数据类型分为标量类型、复合类型、引用类型。标量类型是系统定义的,标量类型和数据库的字段的类型是一样的,只是标量还有一些扩展。复合类型是用户定义的,复合类型中可以包含一个或者多个变量。复合类型有记录、表和数组。引用类型,是用户定义的只想某个数据缓冲区的指针,游标就是PL/SQL中的引用类型。下面进一步介绍复合类型和引用类型。

%type是PL/SQL提供的一种变量声明方式,使用%type可以用来定义和数据表中某个字段数据类型相同的数据类型,使用%type可以避免出现定义类型错误,使得程序的具有很好的稳定性,所以说使用%type是一种很好的编程风格。
还有一种变量声明方式%rowtype,使用该变量声明方式会使得记录变得更简单,但是缺乏灵活性.例如,如果定义了%rowtype类型的变量,该变量的结构与定义表的结构完全相同,查询时必须使用*或者列举全部的字段信息。记录变量的赋值分为整体赋值和单个赋值。现在来说一下两者的差别。1.整理赋值,如果两个记录类型不同的变量进行赋值将会出现编译错误。必须是两个记录类型相同的变量才可以进行整体赋值。2.单个赋值,只要两个记录类型中的数据类型相同,即使记录类型不同,进行单个赋值是合法的。

4.2、程序控制结构

PL/SQL程序控制结构:PL/SQL程序的控制结构分为顺序结构、选择结构和循环结构这3种类型。
1.顺序结构
顺序结构是指程序在执行时,按照语句在程序中出现的先后顺序执行。在我们sqlplus环境下输入命令 set serveroutput on 表示允许服务器将结果显示出来。
2.选择结构
PL/SQL的选择结构是指在执行时,根据选择条件,执行满足特定条件的语句序列。选择结构可分为if语句和case语句。
①if语句
if语句的语法格式如下:

if logical expression 1 then

statement sequence 1

elsif logical expression 2 then

statement sequence 2

else statement sequence N

end if;

该语句的执行过程:逻辑表达式1的值为”真”的时候,执行语句序列1,逻辑表达式2的值为”真”的时候,执行语句序列2,否则执行语句序列N。
②.case结构
case语句的格式如下:

case expression

when expression 1 then statement sequence 1;

when expression 2 then statement sequence 2;

else statement sequence N;

case语句的执行过程:计算表达式的值,当运算结果满足表示1时,执行语句序列1,当运算结果满足表达式2时,执行语句序列2,否则执行语句序列N。

2.循环结构
PL/SQL循环结构程序在执行的时候,重复执行某些语句序列,被重复执行的被称为循环体。
PL/SQL循环结构分为loop循环、 while loop循环和for循环。下面一一来说明每种循环结构的语法和执行过程。

①loop循环
loop循环也称为简单循环。这种循环是先执行循环体,然后在判断退出条件。loop循环也分为loop-if-exit-end loop和loop-exit-when-end loop 两种循环方式。

loop-if-exit-end loop语法如下:

loop

statement sequence

if exit conditions then

exit;

end if;

end loop;

该循环结构在执行过程中,先执行的语句序列。然后通过if选择结构和关键字exit来控制判断是否退出循环。

第2种方法是在第1种简单循环的基础之上,对于退出循环条件的写法稍加改动,其语法如下:

loop

statement sequence

the exit when exit conditions;

end loop;

该循环结构在执行过程中,先执行的语句序列,然后再通过exit when来控制判断是否退出循环。

②while循环
while循环和前面的loop循环体不同的是,while循环先判断执行条件是否满足,然后再开始执行语句与序列。其语法如下

while excution conditions loop

statement sequence

end loop;

该循环结构在进入循环之前要对执行条件进行判断,是否满足执行条件,如果满足执行条件,则开始执行语句序列,否则退出循环。

③for循环
loop循环和while循环的循环次数事先是不知道的,它的循环次数取决于执行条件是否满足,而for循环的循环次数是已知的,其语法如下:

for loop_variable in (reverse)lower_bound .. upper_bound loop

statement sequence

end loop;

循环变量在上界值和下界值之间变化,其循环次数为:上界值-下界值+1.for循环的步长固定值1.

该循环结构的执行过程是,将下界值赋值给循环变量,如果选择关键字reverse,则将上界值赋值循环变量。就是对于前一种循环的反循环。

当循环变量超过了上界值或者下界值就终止循环。

4.3、游标

前面说到过,复合变量还有嵌套表和数据,嵌套表、数组和记录不同,不能对变量进行单个赋值,而是需要通过构造方法来进行整体赋值。如果嵌套表和数组进行单个赋值的话,会出现编译错误。下面来说一下游标在PL/SQL的应用。

在一般的情况下,我们利用select语句查询可所得到的结果都是多行记录数据,而在PL/SQL程序块中,select语句每次只能处理单行记录数据的情况,如果我们想操纵多行记录数据的话,那我们就需要使用游标来帮助我们完成。游标是由我们用户自定义的,它能够根据查询条件从数据库中查询出一组记录,将其作为一个临时表放置于缓冲区中,以游标为指针,逐行的对数据进行操作。

游标的类型分为显示游标和游标变量。我将一一说明两种游标的使用方法以及两者的差别。

显示游标的操作包括声明游标、打开游标、提取游标和关闭游标。

声明游标的语法如下: cursor cur_name is select sentence;

其中cursor 是声明游标的关键字,游标名由用户定义,select语句是我们建立游标的SQL查询命令,目的是从我们的数据库表中选取出一组符合查询条件的记录。

举个例子:cursor cursor_emp is select * from emp where deptno=dno;

这个例子声明了一个游标,游标名为cursor_emp,该游标是从emp表中查询出部门编号为dno变量指定值的那些记录。

声明游标实际上只是对游标加以说明,在我们使用游标之前,需要先打开游标,其语法格式如下:

open cursor_name;

打开游标命令,需要完成以下的工作。

打开游标的时候需要检查一下dno是否有值,如果没有被赋值的话,就没有办法知道dno是什么咯,那样的话就会发生编译错误,游标打开失败。当检查过dno有值之后,将会把select语句所查询出来符合查询条件的那些记录送入到数据缓冲区中,然后把游标指向第一条记录。

当我们的游标成功打开了之后我们就可以提取游标了。语法如下:

fetch cursor_name into variable1,variable2,…;

fetch cursor_name into record variable;

提取游标是指将游标中的数据赋给执行的变量或记录变量,每执行一次fetch命令,其数据缓冲区的指针就会自动下移一行。

游标一旦使用完毕,就应将其关闭。关闭游标之后,就可以释放与游标相关联的资源。其语法如下:

close cursor_name;

一旦游标关闭之后,如果再对游标进行操作是非法的。

关于游标我们需要注意的一点是,我们用fetch命令提取有数据赋给变量时,变量的个数必须与游标提取的数据个数一致,即必须写出与游标相对于的所有列,不允许只提出其中的某几列,例如,我们游标提取了7列,提取时必须有7个相对应的数据,否则会出现编译错误。

在PL/SQL程序中我们可以使用游标的属性操作来获取游标的状态,游标的属性都是以%开头的。

1、%found 这是一个布尔型属性,用来测试游标是否得到数据,如果前面的fetch语句得到了一行记录数据,那么%found就会返回true,否则返回false.
2.%notfound 是%found的反逻辑,常被用循环退出。
3.%isopen 用来测试游标是否打开。如果游标已打开,那%isopen返回true,否则返回false.
4.%rowcount 用来返回从游标中取出的数据的总行数。每当fetch语句成功的提取一行数据,%rowcount的值就会增加1.

前面讨论的游标属于显式游标,即游标与一条固定的select语句相关联。在实际使用中,往往希望一个游标在运行时与不同的select语句相关联。那我们就需要使用游标变量来完成该操作了。游标变量也是引用类型,当程序运行的时候,它可以指向不同的selec查询语句的数据缓冲区。游标变量也是需要先定义,后声明,再使用。

游标变量的定义语法如下:

type cursor_type_name is ref cursor return return_type;

其中type 是定义游标类型的关键字,游标类型名,由用户定义的,返回类型指的是最终由游标变量所返回的数据的类型。游标变量的返回类型必须是一个记录类型。这一点是和显式游标不同的。

当我们的游标定义好之后就可以声明游标变量了。声明游标变量的格式如下:

cursor_variable_name cursor_type_name;

当游标变量定义、声明之后,我们就可以打开游标使用了,打开游标变量时,必须与一条select语句相关联的。这一点也是和显式游标打开的方法是不一样的。其语法格式如下:

open cursor_variable for select statement;

游标变量可以与不同的select语句相关联。这样使得游标变量的灵活性非常好。

提取游标变量和提取显式游标的操作是一样。格式如下:

fetch cursor_name into variable1,variable2,…;

fetch cursor_name into record_variable;

当我们使用完游标变量之后,就可以对其进行关闭,这和显式游标操作也是相同的。

4.4、异常处理

当我们在设计PL/SQL程序的时候,经常会出现意想不到的错误,而异常处理就是针对这些错误进行处理的程序段。oracle系统中的处理分为系统预定义的异常处理和自定义的异常处理两种。系统预定义异常处理是针对PL/SQL程序在执行过程中发生的系统预定义的异常问题的程序。系统预定义异常处理是由系统自动触发的。当然我们也可以利用自定义异常处理来处理显示触发系统预定义的异常问题。自定义异常处理是根据用户本身的需求而编写的异常处理程序,自定义异常处理是由用户触发的。自定义异常处理也是先定义,后触发,再处理。其定义语法格式如下:

abnormal_handling_name exception;

abnormal_handling_name是用户定义的,exception是异常处理的关键字。

在PL/SQL程序块的执行部分,需要执行异常处理触发语句,异常处理的触发语句语法格式为

raise 异常处理名;

在一个PL/SQL程序块中可以包含多个异常处理,根据不同的异常处理而编写不同的异常处理程序。我们需要在程序块中exception中编写异常处理程序。方法如下:

exception

when abnormal_handling_name 1 then

abnormal_handling_name statement sequence 1;

when abnormal_handling_name N then

abnormal_handling_name statement sequence N;

4.5、存储过程

前面所说的PL/SQL程序块都是没有命名的程序块,而存储过程就是命名过的程序块,而且存储过程中还允许使用参数,使用参数的方法有传入参数、传出参数和传入传出参数三种,根据不同的需要选择不同的参数方法。有一点需要特别注意的是:在给参数定义数据类型的时候,只需要指明参数的类型就可以了,不需要指明参数的长度。这是数据库新手特别容易犯的错误。存储过程的创建语法格式为:

create (or replace) procedure procedure_name (Parameter name1,in|out|inout Parameter_type,…)

is

procedure body;

其中procedure是存储过程名关键字,or replace 在修改存储过程中使用,表示如果存在同名的存储过程,就将其替换。

关于过程调用方法有2种写法

exec procedure_name (Parameter name1,Parameter name2,…);

exec procedure_name (Parameter name1,Parameter name2,…);

对于存储过程的修改,没有指定的修改语句,只是在创建存储过程的语句create procedure 中间加上or replace 就可以实现修改存储过程了,命令的意思就是如果该过程名有的话,就替换掉。

4.6、存储函数

存储函数也是一个命名的程序块,和过程非常相似,唯一不同的是过程没有返回值,函数有返回值。函数的定义语法格式为:

create (or replace) function function_name (Parameter name1,in|out|inout Parameter_type,…)

return return_type

is

function body;

function是存储函数函数关键字,return 为返回语句。

函数的调用方法为:

var income number

call function(parameter_name)into:income;

print income

4.7、触发器

pl/sql为了维护数据库的完整性的约束,提供了一个叫“触发器”的命名程序块,触发器和过程、函数是不同的,触发器是由触发条件满足时自动运行的,不需要编程调用。触发器分为行级触发器和语句级触发器。行级触发器,就是满足一个条件就执行一次,而语句级触发器,需要满足全部条件才会执行.其语法格式如下:

create or replace trigger trigger_name

before|after trigger event of field_list on table_name

for each row when trigger_condition

trigger body;

其中trigger是触发器关键字,before|after 表示之前或之后触发,for each row 表示逐行触发。

触发器的修改create or replace trigger 加以实现修改触发器。

这是跟着课程走学到的知识,现在学到的只是一些基本部分的知识,在以后的应用中,还是远远不够的,还需要加强学习,理论和实践相结合。

五、分区表

之后我又自己查阅资料,虽然前面我接触过oracle索引,那也只是最基本的索引。索引的种类分为非唯一索引,就是我们最常用的B*树索引,还有唯一索引。数据表中所创建的主键就是属于唯一索引,但是两者的概念不同的,建立主键是为了保证数据的完整性而创建的。而唯一索引是为了能加快查询速度而创建的。索引的种类.还有基于分区表的索引。局部有前缀分区索引,局部无前缀分区索引,全局有前缀分区索引,散列分区索引,基于函数的索引。创建分区索引的规则如下:

基础表必须是分区表;

分区数量与基础表相同;

每个索引分区的子分区数量与相应的基础表分区相同;

基础表的子分区中的行的索引项,被存储在该索引的相应的子分区中;

5.1 表分区

(1) 表空间及分区表的概念

表空间:

是一个或多个数据文件的集合,所有的数据对象都存放在指定的表空间中,但主要存放的是表, 所以称作表空间。

分区表:

当表中的数据量不断增大,查询数据的速度就会变慢,应用程序的性能就会下降,这时就应该考虑对表进行分区。表进行分区后,逻辑上表仍然是一张完整的表,只是将表中的数据在物理上存放到多个表空间(物理文件上),这样查询数据时,不至于每次都扫描整张表。

(2) 表分区的具体作用

Oracle的表分区功能通过改善可管理性、性能和可用性,从而为各式应用程序带来了极大的好处。通常,分区可以使某些查询以及维护操作的性能大大提高。此外,分区还可以极大简化常见的管理任务,分区是构建千兆字节数据系统或超高可用性系统的关键工具。

分区功能能够将表、索引或索引组织表进一步细分为段,这些数据库对象的段叫做分区。每个分区有自己的名称,还可以选择自己的存储特性。从数据库管理员的角度来看,一个分区后的对象具有多个段,这些段既可进行集体管理,也可单独管理,这就使数据库管理员在管理分区后的对象时有相当大的灵活性。但是,从应用程序的角度来看,分区后的表与非分区表完全相同,使用 SQL DML 命令访问分区后的表时,无需任何修改。

5.2 什么时候使用分区表:

1、 表的大小超过2GB。

2、 表中包含历史数据,新的数据被增加都新的分区中。

5.3 表分区有以下优点和缺点:

1、 改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索速度。

2、 增强可用性:如果表的某个分区出现故障,表在其他分区的数据仍然可用;

3、 维护方便:如果表的某个分区出现故障,需要修复数据,只修复该分区即可;

4、 均衡I/O:可以把不同的分区映射到磁盘以平衡I/O,改善整个系统性能。

缺点:

分区表相关:已经存在的表没有方法可以直接转化为分区表。

表分区的类型分为 范围分区、列表分区散列分区、组合范围散列分区和复合范围散列分区。

六、执行计划

如果要分析某条SQL的性能问题,通常我们要先看SQL的执行计划,看看SQL的每一步执行是否存在问题。如果一条SQL平时执行的好好的,却有一天突然性能很差,如果排除了系统资源和阻塞的原因,那么基本可以断定是执行计划出了问题。看懂执行计划也就成了SQL优化的先决条件。这里的SQL优化指的是SQL性能问题的定位,定位后就可以解决问题。

七、oracle 锁机制

数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。

加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁。加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作。

在数据库中有两种基本的锁类型:排它锁和共享锁。当数据对象被加上排它锁时,其他的事务不能对它读取和修改。加了共享锁的数据对象可以被其他事务读取,但不能修改。数据库利用这两种基本的锁类型来对数据库的事务进行并发控制。

7.1 Oracle数据库的锁类型

根据保护的对象不同,Oracle数据库锁可以分为以下几大类:DML锁,用于保护数据的完整性;DDL锁,用于保护数据库对象的结构,如表、索引等的结构定义;内部锁和闩,保护数据库的内部结构。

DML锁的目的是为了保证并发情况下的数据完整性.在oracle数据库中,DML锁主要包括TM锁和TX锁,其中TM锁称为表级锁,TX锁称为行级锁。

当oracle数据库发生TX锁等待时,如果不及时处理常常会引起oracle数据库挂起,或者导致死锁的发生,这些现象锁都会对实际应用时产生极大的危害,打个比方,长时间未响应,大量的事务处理失败等。所以,我们在实际应用中,要避免出现类似的情况。

我们来介绍一下悲观锁和乐观锁。

悲观锁在用户修改之前就发挥了作用,例如

select * from table_name for update

当用户发出该命令之后,oracle将会对返回的数据添加行级锁,以防止其他用户也对此表进行修改。

而乐观锁则认为数据在select到update并commit的这段时间数据不会被改变的。然而这里面有一个潜在的危险就是由于被选出来的结果集并没有被锁定,是存在着被其他用户更改的可能性,所以oracle仍然建议我们使用悲观锁,因为这样会更安全。

八、分析函数

分析函数为了我们分析数据提供了一个简单高效的处理方式。

我们只需要使用一个简单的sql语句就可以实现了,而且执行效率方面有很大的提高。函数分为很多种,我们就说几个常用函数的使用方法。

8.1、Oracle ROLLUP和CUBE 用法

Oracle的GROUP BY语句除了最基本的语法外,还支持ROLLUP和CUBE语句。如果是Group by ROLLUP(A, B, C)的话,首先会对(A、B、C)进行GROUP BY,然后对(A、B)进行GROUP BY,然后是(A)进行GROUP BY,最后对全表进行GROUP BY操作。

如果是GROUP BY CUBE(A, B, C),则首先会对(A、B、C)进行GROUP BY,然后依次是(A、B),(A、C),(A),(B、C),(B),(C),最后对全表进行GROUP BY操作。 grouping_id()可以美化效果。除了使用GROUPING函数,还可以使用GROUPING_ID来标识GROUP BY的结果。也可以 Group by Rollup(A,(B,C)) ,Group by A Rollup(B,C),…… 这样任意按自己想要的形式结合统计数据,非常方便。

8.2、Rank的用法

功能描述:根据ORDER BY子句中表达式的值,从查询返回的每一行,计算它们与其它行的相对位置。组内的数据按ORDER BY子句排序,然后给每一行赋一个号,从而形成一个序列,该序列从1开始,往后累加。每次ORDER BY表达式的值发生变化时,该序列也随之增加。有同样值的行得到同样的数字序号(认为null时相等的)。然而,如果两行的确得到同样的排序,则序数将随后跳跃。若两行序数为1,则没有序数2,序列将给组中的下一行分配值3,DENSE_RANK则没有任何跳跃。

rank()是跳跃排序,比如有两个第二名时接下来就是第四名(同样是在各个分组内)

dense_rank()l是连续排序,比如有两个第二名时仍然跟着第三名。

8.3、First的用法

功能描述:从DENSE_RANK返回的集合中取出排在最前面的一个值的行(可能多行,因为值可能相等),因此完整的语法需要在开始处加上一个集合函数以从中取出记录。

8.4、Last的用法

功能描述:从DENSE_RANK返回的集合中取出排在最后面的一个值的行(可能多行,因为值可能相等),因此完整的语法需要在开始处加上一个集合函数以从中取出记录。

8.5、Lag的用法

功能描述:可以访问结果集中的其它行而不用进行自连接。它允许去处理游标,就好像游标是一个数组一样。在给定组中可参考当前行之前的行,这样就可以从组中与当前行一起选择以前的行。Offset是一个正整数,其默认值为1,若索引超出窗口的范围,就返回默认值(默认返回的是组中第一行),其相反的函数是LEAD。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值