csdn emag(oracle)第三期

71

Upload: yiditushe

Post on 04-Dec-2014

1.340 views

Category:

Technology


0 download

DESCRIPTION

 

TRANSCRIPT

Page 1: Csdn Emag(Oracle)第三期
Page 2: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——Oracle 杂志》

目录

目录 ......................................................................................................................i

篇首寄语 ........................................................................................................ - 1 -

数据库实战 .................................................................................................... - 2 -

一次诊断和解决CPU利用率高的问题分析................................................ - 2 -

关于cursor_sharing = similar......................................................................... - 9 -

1.1. 实验现象 .........................................................................................................................- 9 -

1.2. 结论 ...............................................................................................................................- 12 -

数据库设计 .................................................................................................. - 14 -

时空数据库设计.......................................................................................... - 14 -

1.1. 需求前提: ...................................................................................................................- 14 -

1.2. 实践环境: ...................................................................................................................- 14 -

1.3. 术语表: .......................................................................................................................- 14 -

1.3.1. 时空对象 ...............................................................................................................- 14 -

1.3.2. 快照 .......................................................................................................................- 15 -

1.4. 设计方向: ...................................................................................................................- 15 -

1.5. 技术要点: ...................................................................................................................- 15 -

1.6. 图形解说: ...................................................................................................................- 15 -

1.7. 数据表: .......................................................................................................................- 16 -

1.8. 存储过程: ...................................................................................................................- 17 -

1.9. 视图: ...........................................................................................................................- 17 -

1.10. 触发器: .......................................................................................................................- 17 -

1.11. 扩展与变化: ...............................................................................................................- 17 -

1.11.1. 支持多种观察模式。 ...........................................................................................- 17 -

1.11.2. 增加对象关系表以描述时空对象之间的联系....................................................- 18 -

http://emag.csdn.net 2005 年 1 月 1 期 总第 3 期 i

Page 3: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——Oracle 杂志》

1.12. 使用方法: ...................................................................................................................- 18 -

数据库管理 .................................................................................................. - 19 -

Oracle中分区表的使用 ............................................................................... - 19 -

1.1. 分区表的创建 ...............................................................................................................- 20 -

1.1.1. 范围分区 ...............................................................................................................- 20 -

1.1.2. Hash分区(散列分区) .......................................................................................- 21 -

1.1.3. 复合分区 ...............................................................................................................- 22 -

1.2. 分区表操作 ...................................................................................................................- 22 -

1.2.1. 插入记录: ...........................................................................................................- 22 -

1.2.2. 查询分区表记录: ...............................................................................................- 23 -

1.2.3. 更新分区表的记录: ...........................................................................................- 24 -

1.2.4. 删除分区表记录: ...............................................................................................- 24 -

1.3. 分区表索引的使用: ...................................................................................................- 25 -

1.3.1. 局部索引分区的建立: .......................................................................................- 25 -

1.3.2. 全局索引分区的建立。 .......................................................................................- 26 -

1.4. 分区表的维护: ...........................................................................................................- 27 -

1.4.1. 增加一个分区: ......................................................................................................- 27 -

1.4.2. 合并一个分区: ...................................................................................................- 27 -

1.4.3. 删除分区: ...........................................................................................................- 28 -

1.5. 总结: ...........................................................................................................................- 28 -

数据库开发 .................................................................................................. - 29 -

VC+ADO开发Oracle应用程序 .................................................................. - 29 -

1.1. 准备工作 .......................................................................................................................- 29 -

1.2. 建立VC工程..................................................................................................................- 30 -

1.3. 设计应用程序界面 .......................................................................................................- 37 -

1.4. 填写代码 .......................................................................................................................- 41 -

1.5. 小结一下 .......................................................................................................................- 50 -

1.6. 两个封装类的说明 .......................................................................................................- 51 -

1.6.1. CADOConnection..................................................................................................- 51 -

http://emag.csdn.net 2005 年 1 月 1 期 总第 3 期 ii

Page 4: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——Oracle 杂志》

1.6.2. CADORecordset ....................................................................................................- 51 -

1.7. 后续工作 .......................................................................................................................- 52 -

1.8. 完整源代码下载 ...........................................................................................................- 53 -

数据库探秘 .................................................................................................. - 54 -

深入了解Oracle数据字典 ........................................................................... - 54 -

1.1. X$表 ..............................................................................................................................- 54 -

1.2. GV$和V$视图...............................................................................................................- 54 -

1.3. GV_$,V_$视图和V$,GV$同义词 ................................................................................- 55 -

1.4. 再进一步 .......................................................................................................................- 56 -

1.4.1. X$表 ......................................................................................................................- 56 -

1.4.2. GV$和V$视图.......................................................................................................- 57 -

Oracle 10g 新特性 ...................................................................................... - 60 -

浅谈ORACLE 10G 闪回恢复区................................................................ - 60 -

1.1. 何为闪回恢复区 ...........................................................................................................- 60 -

1.2. 为何要用闪回恢复区?..................................................................................................- 61 -

1.3. 设定闪回恢复区 ...........................................................................................................- 61 -

1.4. 管理并监控闪回恢复区 ...............................................................................................- 62 -

1.5. 闪回恢复区中文件的保持策略 ...................................................................................- 65 -

1.6. 注意事项 .......................................................................................................................- 66 -

1.7. 结束语 ...........................................................................................................................- 66 -

1.8. 参考信息 .......................................................................................................................- 66 -

http://emag.csdn.net 2005 年 1 月 1 期 总第 3 期 iii

Page 5: Csdn Emag(Oracle)第三期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

篇首寄语

值此新春佳节即将到来之际,我们的《Oracle 杂志》第三期与大家见面了。我们仅以此作为

献给大家的新年贺礼。感谢大家一直以来对我们杂志的支持。

呵呵,严格来说并不该我来写这篇寄语,因为这一期杂志的主编是 dinya。前期的一些重要工

作都是他负责完成的。但是后来由于工作的关系,才临时由我来接手,完成剩下的一些组织工作。

所以,我想先感谢 dinya 为杂志所作的贡献。然后,我想感谢其他的几位编辑,正是大家的积

极支持和无私奉献,才使得我们的杂志能够在年底这个异常繁忙的时候如期发布。

他们是:biti_rainy,eygle,chanet,雪狼,Fenng,kamus,coolyl,bzszp。呵呵,如果大家看

过我们的前两期杂志,相信这几个名字应该都耳熟能详了吧。

此外,我还要在这里重点感谢一位网友,即《时空数据库设计》一文的作者——李宏。此前

我们的文章都是由我们的各位编辑亲自撰稿的。李宏是第一位向我们投稿并被采用的作者。这篇

文章对我们的杂志来说,具有非常重要的意义,它代表了网友对我们杂志的关注以及实际的支持

和贡献。我们希望能有越来越多的人,关注我们的杂志,参与建设我们的杂志。

我们欢迎大家为我们提出宝贵意见,欢迎大家为我们踊跃投稿!

请将稿件发到《Oracle杂志》的投稿信箱:[email protected].

您的稿件,我们将通过编辑及主编的审核,优先录用。

现 行 的 投 稿 奖 励 , 请 参 见 《 CSDN 社 区 电 子 杂 志 奖 励 制 度 》

http://blog.csdn.net/ccemp/archive/2005/01/07/244057.aspx。

《Oracle 杂志》的健康发展,需要您的支持!

后,我们在这里向大家拜个早年,祝大家新年快乐,万事如意!

《CSDN 社区电子杂志——Oracle 杂志》编辑部

2005 年 1 月

2005 年 1 月 1 期 总第 3 期

- 1 -

Page 6: Csdn Emag(Oracle)第三期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

数据库实战

一次诊断和解决 CPU 利用率高的问题分析

本文作者: Allan ([email protected] )

Oracle 数据库经常会遇到 CPU 利用率很高的情况,这种时候大都是数据库中存在着严重性能

低下的 SQL 语句,这种 SQL 语句大大的消耗了 CPU 资源,导致整个系统性能低下。当然,引起

严重性能低下的 SQL 语句的原因是多方面的,具体的原因要具体的来分析,下面通过一个实际的

案例来说明如何来诊断和解决 CPU 利用率高的这类问题。

操作系统:solairs8

数据库:Oracle9.2.0.4

问题描述:现场工程师汇报数据库非常慢,几乎所有应用操作均无法正常进行。

首先登陆主机,执行 top 发现 CPU 资源几乎消耗殆尽,存在很多占用 CPU 很高的进程,而内

存和 I/O 都不高,具体如下:

last pid: 26136; load averages: 8.89, 8.91, 8.12

216 processes: 204 sleeping, 8 running, 4 on cpu

CPU states: 0.6% idle, 97.3% user, 1.8% kernel, 0.2% iowait, 0.0% swap

Memory: 8192M real, 1166M free, 14M swap in use, 8179M swap free

PID USERNAME THR PRI NICE SIZE RES STATE TIME CPU COMMAND

25725 oracle 1 50 0 4550M 4508M cpu2 12:23 11.23% oracle

25774 oracle 1 41 0 4550M 4508M run 14:25 10.66% oracle

26016 oracle 1 31 0 4550M 4508M run 5:41 10.37% oracle

26010 oracle 1 41 0 4550M 4508M run 4:40 9.81% oracle

26014 oracle 1 51 0 4550M 4506M cpu6 4:19 9.76% oracle

25873 oracle 1 41 0 4550M 4508M run 12:10 9.45% oracle

25723 oracle 1 50 0 4550M 4508M run 15:09 9.40% oracle

26121 oracle 1 41 0 4550M 4506M cpu0 1:13 9.28% oracle

于是先查看数据库的告警日志 ALERT 文件,并没有发现有什么错误存在,日志显示数据库运

行正常,排除数据库本身存在问题。

然后查看这些占用 CPU 资源很高的 Oracle 进程究竟是在做什么操作,使用如下 SQL 语句:

select sql_text,spid,v$session.program,process from

v$sqlarea,v$session,v$process

where v$sqlarea.address=v$session.sql_address

2005 年 1 月 1 期 总第 3 期

- 2 -

and v$sqlarea.hash_value=v$session.sql_hash_value

Page 7: Csdn Emag(Oracle)第三期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net 2005 年 1 月 1 期 总第 3 期

- 3 -

and v$session.paddr=v$process.addr

and v$process.spid in (PID);

用 top 中占用 CPU 很高的进程的 PID 替换脚本中的 PID,得到相应的 Oracle 进程所执行的 SQL

语句,发现占用 CPU 资源很高的进程都是执行同一个 SQL 语句:

SELECT d.domainname,d.mswitchdomainid,

a.SERVICEID,a.SERVICECODE,a.USERTYPE,a.STATUS,a.NOTIFYSTATUS,to_char(a.DATECREATED

,'yyyy-mm-dd hh24:mi:ss') DATECREATED,VIPFLAG,STATUS2,CUSTOMERTYPE,CUSTOMERID FROM

service a, gatewayloc b, subbureaunumber c, mswitchdomain d WHERE b.mswitchdomainid

= d.mswitchdomainid and b.gatewaysn = c.gatewaysn AND a.ServiceCode like c.code||'%'

and a.serviceSpecID=1 and a.status!='4' and a.status!='10' and a.servicecode like

'010987654321%' and SubsidiaryID=999999999

基本上可以肯定是这个 SQL 引起了系统 CPU 资源大量被占用,那究竟是什么原因造成这个

SQL 这么大量占用 CPU 资源呢,我们先来看看数据库的进程等待事件都有些什么:

SQL> select sid,event,p1,p1text from v$session_wait;

SID EVENT P1 P1TEXT

---------- ----------------------------------------------------------------

12 latch free 4.3982E+12 address

36 latch free 4.3982E+12 address

37 latch free 4.3982E+12 address

84 latch free 4.3982E+12 address

102 latch free 4.3982E+12 address

101 latch free 4.3982E+12 address

85 latch free 4.3982E+12 address

106 latch free 4.3982E+12 address

155 latch free 4.3982E+12 address

151 latch free 4.3982E+12 address

149 latch free 4.3982E+12 address

147 latch free 4.3982E+12 address

1 pmon timer 300 duration

从上面的查询我们可以看出,大都是 latch free 的等待事件,然后接着查一下这些 latch 的等待

都是什么进程产生的:

SQL> select spid from v$process where addr in

(select paddr from v$session where sid in(84,102,101,106,155,151));

SPID

------------

25774

26010

25873

25725

由此看出 latch free 这个等待事件导致了上面的那个 SQL 语句都在等待,占用了大量的 CPU

资源。我们来看看究竟主要是那种类型的 latch 的等待,根据下面的 SQL 语句:

Page 8: Csdn Emag(Oracle)第三期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net 2005 年 1 月 1 期 总第 3 期

- 4 -

SQL> SELECT latch#, name, gets, misses, sleeps

FROM v$latch

WHERE sleeps>0

ORDER BY sleeps;

LATCH# NAME GETS MISSES SLEEPS

---------- ----------------------------------------------------------------

15 messages 96876 20 1

159 library cache pin allocation 407322 43 1

132 dml lock allocation 194533 213 2

4 session allocation 304897 48 3

115 redo allocation 238031 286 4

17 enqueue hash chains 277510 85 5

7 session idle bit 2727264 314 16

158 library cache pin 3881788 5586 58

156 shared pool 2771629 6184 662

157 library cache 5637573 25246 801

98 cache buffers chains 1722750424 758400 109837

由上面的查询可以看出 主要的 latch 等待是 cache buffers chains,这个 latch 的等待表明数据

库存在单独的 BLOCK 的竞争这些 latch,我们来看这个 latch 存在的子 latch 及其对应的类型:

SQL> SELECT addr, latch#, gets, misses, sleeps

FROM v$latch_children

WHERE sleeps>0

and latch# = 98

ORDER BY sleeps desc;

ADDR LATCH# GETS MISSES SLEEPS

---------------- ---------- ---------- ---------- ----------

000004000A3DFD10 98 10840661 82891 389

000004000A698C70 98 159510 2 244

0000040009B21738 98 104269771 34926 209

0000040009B227A8 98 107604659 35697 185

000004000A3E0D70 98 5447601 18922 156

000004000A6C2BD0 98 853375 7 134

0000040009B24888 98 85538409 25752 106

……………

接着我们来查看 sleep 较多的子 latch 对应都有哪些对象:

SQL> select distinct a.owner,a.segment_name,a.segment_type from

dba_extents a,

(select dbarfil,dbablk

from x$bh

where hladdr in

(select addr

from (select addr

from v$latch_children

Page 9: Csdn Emag(Oracle)第三期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net 2005 年 1 月 1 期 总第 3 期

- 5 -

order by sleeps desc)

where rownum < 5)) b

where a.RELATIVE_FNO = b.dbarfil

and a.BLOCK_ID <= b.dbablk and a.block_id + a.blocks > b.dbablk;

OWNER SEGMENT_NAME SEGMENT_TYPE

---------------------------------------------------------------------------

TEST I_SERVICE_SERVICESPECID INDEX

TEST I_SERVICE_SUBSIDIARYID INDEX

TEST SERVICE TABLE

TEST MSWITCHDOMAIN TABLE

TEST I_SERVICE_SC_S INDEX

…………………

我们看到在开始的那个 SQL 语句中的几个对象都有包括在内,于是来看看开始的那个 SQL 的

执行计划:

SQL> set autotrace trace explain

SQL>SELECT d.domainname,d.mswitchdomainid,

a.SERVICEID,a.SERVICECODE,a.USERTYPE,a.STATUS,a.NOTIFYSTATUS,to_char(a.DATECREATED

,'yyyy-mm-dd hh24:mi:ss') DATECREATED,VIPFLAG,STATUS2,CUSTOMERTYPE,CUSTOMERID FROM

service a, gatewayloc b, subbureaunumber c, mswitchdomain d WHERE b.mswitchdomainid

= d.mswitchdomainid and b.gatewaysn = c.gatewaysn AND a.ServiceCode like c.code||'%'

and a.serviceSpecID=1 and a.status!='4' and a.status!='10' and a.servicecode like

'010987654321%' and SubsidiaryID=999999999;

Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT Optimizer=CHOOSE

1 0 NESTED LOOPS

2 1 NESTED LOOPS

3 2 NESTED LOOPS

4 3 TABLE ACCESS (FULL) OF 'SUBBUREAUNUMBER'

5 3 TABLE ACCESS (BY INDEX ROWID) OF 'GATEWAYLOC'

6 5 INDEX (UNIQUE SCAN) OF 'PK_GATEWAYLOC' (UNIQUE)

7 2 TABLE ACCESS (BY INDEX ROWID) OF 'MSWITCHDOMAIN'

8 7 INDEX (UNIQUE SCAN) OF 'PK_MSWITCHDOMAIN' (UNIQUE)

9 1 TABLE ACCESS (BY INDEX ROWID) OF 'SERVICE'

10 9 AND-EQUAL

11 10 INDEX (RANGE SCAN) OF 'I_SERVICE_SERVICESPECID' (NON

-UNIQUE)

12 10 INDEX (RANGE SCAN) OF 'I_SERVICE_SUBSIDIARYID' (NON-

UNIQUE)

根据开始查到的引起 latch free 等待中的对象和 SQL 语句的执行计划,觉得 SERVICE 表上的

索引有问题,似乎存在了过多的扫描,于是将同样的 SQL 语句在别的地市的同样的数据库上执行

一下,查看相应的执行计划:

Page 10: Csdn Emag(Oracle)第三期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net 2005 年 1 月 1 期 总第 3 期

- 6 -

SQL> set autotrace trace explain

SQL>SELECT d.domainname,d.mswitchdomainid,

a.SERVICEID,a.SERVICECODE,a.USERTYPE,a.STATUS,a.NOTIFYSTATUS,to_char(a.DATECREATED

,'yyyy-mm-dd hh24:mi:ss') DATECREATED,VIPFLAG,STATUS2,CUSTOMERTYPE,CUSTOMERID FROM

service a, gatewayloc b, subbureaunumber c, mswitchdomain d WHERE b.mswitchdomainid

= d.mswitchdomainid and b.gatewaysn = c.gatewaysn AND a.ServiceCode like c.code||'%'

and a.serviceSpecID=1 and a.status!='4' and a.status!='10' and a.servicecode like

'010987654321%' and SubsidiaryID=999999999;

Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT Optimizer=CHOOSE

1 0 TABLE ACCESS (BY INDEX ROWID) OF 'SERVICE'

2 1 NESTED LOOPS

3 2 NESTED LOOPS

4 3 NESTED LOOPS

5 4 TABLE ACCESS (FULL) OF 'SUBBUREAUNUMBER'

6 4 TABLE ACCESS (BY INDEX ROWID) OF 'GATEWAYLOC'

7 6 INDEX (UNIQUE SCAN) OF 'PK_GATEWAYLOC' (UNIQUE)

8 3 TABLE ACCESS (BY INDEX ROWID) OF 'MSWITCHDOMAIN'

9 8 INDEX (UNIQUE SCAN) OF 'PK_MSWITCHDOMAIN' (UNIQUE)

10 2 INDEX (RANGE SCAN) OF 'I_SERVICE_SC_S' (NON-UNIQUE)

对比两个执行计划,发现索引 I_SERVICE_SERVICESPECID 和 I_SERVICE_SUBSIDIARYID

是不应该走的,于是又对比了两个地方 SERVICE 表上的索引个数:

SQL> select index_name from user_indexes where table_name='SERVICE';

INDEX_NAME

------------------------------

I_SERVICE_ACCOUNTNUM

I_SERVICE_CID

I_SERVICE_DATEACTIVATED

I_SERVICE_PRICEPLANID

I_SERVICE_SC_S

I_SERVICE_SERVICECODE

I_SERVICE_SERVICESPECID

I_SERVICE_SUBSIDIARYID

PK_SERVICE_SID

SQL> select index_name from user_indexes where table_name='SERVICE';

INDEX_NAME

------------------------------

I_SERVICE_ACCOUNTNUM

I_SERVICE_CID

I_SERVICE_DATEACTIVATED

I_SERVICE_SC_S

I_SERVICE_SERVICECODE

PK_SERVICE_SID

Page 11: Csdn Emag(Oracle)第三期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

发现存在问题的数据库中的 SERVICE 表上不知道怎么多出了 I_SERVICE_PRICEPLANID、

I_SERVICE_SERVICESPECID 、I_SERVICE_SUBSIDIARYID 三个索引,而这些索引就是导致了

开始那个 SQL 语句用了不该用的索引,引起 latch free 等待和 CPU 占用很高的罪魁祸首,于是删

除了那三个索引,重新执行相应的 SQL 语句,很快就得出了结果,CPU 的利用率也马上下降为正

常了,观察结果如下:

last pid: 26387; load averages: 1.61, 1.38, 1.21

195 processes: 194 sleeping, 1 on cpu

CPU states: 96.2% idle, 1.6% user, 1.7% kernel, 0.5% iowait, 0.0% swap

Memory: 8192M real, 1183M free, 14M swap in use, 8179M swap free

PID USERNAME THR PRI NICE SIZE RES STATE TIME CPU COMMAND

26383 oracle 1 59 0 4550M 4506M sleep 0:12 4.52% oracle

409 root 15 59 0 7168K 7008K sleep 173.1H 0.53% picld

25653 oracle 1 59 0 4550M 4508M sleep 2:12 0.48% oracle

26384 root 1 59 0 2800K 1912K cpu2 0:00 0.21% top-3.5b8-sun4u

25569 oracle 1 59 0 4550M 4508M sleep 0:12 0.09% oracle

25717 oracle 1 59 0 4550M 4507M sleep 0:07 0.05% oracle

25571 oracle 1 59 0 4550M 4507M sleep 0:10 0.04% oracle

25681 oracle 1 59 0 4550M 4508M sleep 0:10 0.04% oracle

25544 oracle 1 58 0 4554M 4501M sleep 0:14 0.03% oracle

25703 oracle 1 59 0 4550M 4506M sleep 0:23 0.03% oracle

………………

对于 CPU 利用率过高的情况,如果是 SQL 语句性能比较低下引起的基本上都可以按照这个思

路来诊断和解决问题,当然具体问题还得具体分析,解决问题的方法也有很多种,这里不过是抛

砖引玉一下,只要能 终达到我们解决问题的目的就可以了。

2005 年 1 月 1 期 总第 3 期

- 7 -

Page 12: Csdn Emag(Oracle)第三期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

作者简介:

网名 coolyl 照片

暂缺 CSDN eMag Oracle 电子杂志主编

现任 itpub Oracle 管理版版主。

擅长数据库的维护,对于数据库的安装,调整,备份方面有自己独到的经验。同时也给一些

国内的大型企业做过 oracle 的培训,有一定的培训经验。

曾做过很多大型项目的数据库维护和支持工作,对 oracle 的维护有相当多的实际经验,善于

现场解决问题。

曾任职于国内某大型软件企业做 oracle 数据库的技术支持,客户遍及全国各个行业,尤其是

电信,政府行业。

现任职于某外资电信企业华北区分公司,DBA,负责华北区 40 多个数据库系统的维护,对大

型数据库管理经验丰富。

《Oracle 数据库 DBA 专题技术精粹》一书的主编及主要作者.

Mail地址: [email protected]

2005 年 1 月 1 期 总第 3 期

- 8 -

Page 13: Csdn Emag(Oracle)第三期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

关于 cursor_sharing = similar

本文作者: biti_rainy ([email protected])

摘要:本文通过简单实验来尝试说明 cursor_sharing=similar 的含义。

1.1. 实验现象

我们先看看在表没有分析无统计数据情况下的表现

SQL> alter session set cursor_sharing = similar;

Session altered.

SQL> select name,value from v$sysstat where name like '%parse%';

NAME VALUE

---------------------------------------------------------------- ----------

parse time cpu 4948

parse time elapsed 4468

parse count (total) 170148

parse count (hard) 1619 (硬分析次数)

parse count (failures) 80

SQL> select count(*) from t where object_id = 1000;

COUNT(*)

----------

0

SQL> select name,value from v$sysstat where name like '%parse%';

NAME VALUE

---------------------------------------------------------------- ----------

parse time cpu 4948

parse time elapsed 4468

parse count (total) 170172

parse count (hard) 1620

parse count (failures) 80

2005 年 1 月 1 期 总第 3 期

- 9 -

Page 14: Csdn Emag(Oracle)第三期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net 2005 年 1 月 1 期 总第 3 期

- 10 -

SQL> /

NAME VALUE

---------------------------------------------------------------- ----------

parse time cpu 4948

parse time elapsed 4468

parse count (total) 170176

parse count (hard) 1620

parse count (failures) 80

SQL> select count(*) from t where object_id = 1000;

COUNT(*)

----------

0

SQL> select name,value from v$sysstat where name like '%parse%';

NAME VALUE

---------------------------------------------------------------- ----------

parse time cpu 4948

parse time elapsed 4468

parse count (total) 170178

parse count (hard) 1620

parse count (failures) 80

SQL> select count(*) from t where object_id = 1001;

COUNT(*)

----------

0

SQL> select name,value from v$sysstat where name like '%parse%';

NAME VALUE

---------------------------------------------------------------- ----------

parse time cpu 4948

parse time elapsed 4468

parse count (total) 170180

parse count (hard) 1620(即使 object_id 发生

变化依然没有硬解析)

parse count (failures) 80

Page 15: Csdn Emag(Oracle)第三期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

我们再来看分析表和字段信息后的表现

SQL> analyze table t1 compute statistics for table for columns object_id;

Table analyzed.

SQL> select name,value from v$sysstat where name like '%parse%';

NAME VALUE

---------------------------------------------------------------- ----------

parse time cpu 4973

parse time elapsed 4495

parse count (total) 170982

parse count (hard) 1640

parse count (failures) 80

SQL> select count(*) from t1 where object_id = 5000;

COUNT(*)

----------

0

SQL> select name,value from v$sysstat where name like '%parse%';

NAME VALUE

---------------------------------------------------------------- ----------

parse time cpu 4973

parse time elapsed 4495

parse count (total) 170984

parse count (hard) 1641

parse count (failures) 80

SQL> select count(*) from t1 where object_id = 5000;

COUNT(*)

----------

0

SQL> select name,value from v$sysstat where name like '%parse%';

NAME VALUE

---------------------------------------------------------------- ----------

parse time cpu 4973

parse time elapsed 4495

parse count (total) 171008

2005 年 1 月 1 期 总第 3 期

- 11 -

Page 16: Csdn Emag(Oracle)第三期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net 2005 年 1 月 1 期 总第 3 期

- 12 -

parse count (hard) 1641 (重复执行没发

生变化)

parse count (failures) 80

SQL> select count(*) from t1 where object_id = 5001;

COUNT(*)

----------

0

SQL> select name,value from v$sysstat where name like '%parse%';

NAME VALUE

---------------------------------------------------------------- ----------

parse time cpu 4973

parse time elapsed 4495

parse count (total) 171010

parse count (hard) 1642 (当 object_id 变

化的时候产生硬分析)

parse count (failures) 80

SQL>

SQL> select sql_text,child_number from v$sql where sql_text like 'select count(*)

from t1 where%';

SQL_TEXT

------------------------------------------------------------------------------

CHILD_NUMBER

------------

select count(*) from t1 where object_id = :"SYS_B_0"

0

select count(*) from t1 where object_id = :"SYS_B_0"

1

1.2. 结论

可以看出若存在 object_id 的 histograms ,则每次是不同的值的时候都产生硬解析 ,若不存在

histograms,则不产生硬解析。换句话说,当表的字段被分析过存在 histograms 的时候,similar 的

表现和 exact 一样,当表的字段没被分析,不存在 histograms 的时候,similar 的表现和 force 一样。

Page 17: Csdn Emag(Oracle)第三期

《CSDN社区电子杂志——Oracle杂志》

http://emag.csdn.net

这样避免了一味地如 force 一样转换成变量形式,因为有 histograms 的情况下转换成变量之后就容

易产生错误的执行计划,没有利用上统计信息。而 exact 呢,在没有 histograms 的情况下也要分别

产生硬解析,这样的话,由于执行计划不会受到数据分布的影响(因为没有统计信息)重新解析

是没有实质意义的。而 similar 则综合了两者的优点。

作者简介: 网名 coolyl

Oracle 专家。有丰富的 Oracle 实践经验,对体系结构、备份恢复、SQL

优化、整体性能优化、Oracle Internal 都有深入研究。

个人教育和成长经历:

对数据库应用设计中如何正确地应用 oracle 特性以扬长避短具有深刻理解。

有丰富的 oracle 实践经验,对数据库的体系结构、备份恢复、sql 优化、数据库整体性能优化、

oracle internal 都有深入研究。

曾于某电信集成公司负责计费系统的开发,然后成为某系统集成公司的 DBA,再辗转在香港

一家跨国公司珠海研发中心担任技术负责人(公司主要产品就是 sql 与数据库优化工具,产品主要销

往欧洲和北美),此后成为自由职业者,为客户提供独立的 oracle 数据库的技术服务和高级性能调整

等培训,同时提供 ITPUB 华南和华东的培训。

目前服务于国内某大型电子商务网站,维护系统数据库并提供开发支持.

擅长的技术领域:oracle

目前的工作动态:alibaba DBA

个人Blog:http://blog.itpub.net/biti_riany

E-mail:[email protected]

2005 年 1 月 1 期 总第 3 期

- 13 -

Page 18: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

数据库设计

时空数据库设计

本文作者: 李宏([email protected])

1.1. 需求前提:

数据每年变化 1~2 次,软件预计生命周期 50 年

1.2. 实践环境:

Oracle Spatial

1.3. 术语表:

时空对象,快照

1.3.1. 时空对象

一个地理目标从诞生到消亡所经历的空间和时间范围及其属性信息。这是一个为处理时空数

据方便而抽象出来的概念,相当于全信息模型中的全信息对象。为了理解时空对象,我们以二维

地物为例。二维地物在二维空间中占据一定的空间范围,表现为一个二维几何体,也就是它的几

何属性。如果再增加一条时间轴,成为(x,y,t)坐标系,并认为任何的空间对象都有诞生和消

亡,则这个二维地物就在(x,y,t)坐标系中占据了一定的三维空间。我们就把二维地物从诞生

到消亡这一时间段所占据的空间-时间范围称之为“时空对象”。同理,也可以将时空对象扩展为

三维的空间对象在时间维度上的延续,也就是四维对象。时空对象的属性信息是一张二维表。

2005 年 1 月 1 期 总第 3 期

- 14 -

Page 19: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

1.3.2. 快照

一个地理目标在某一特定时刻所占据的空间范围及其属性信息,或者说:时空对象在某一特

定的时刻所占据的空间范围及其相应的属性信息。举例来说,地图上绘制了一个饭店的位置,大

小,这就是饭店的一个快照。因为饭店是从某一时刻才诞生的,又会在某一时刻消亡,而在诞生

和消亡之间,还可能会搬迁或扩建。所以地图上反映的仅仅是饭店在某一时刻的状态,所以称之

为饭店在某一时刻的快照或时空对象在某一特定时刻的快照。注意,快照总是对应于某一特定的

时刻,否则将失去快照的意义。快照的属性信息是时空对象属性信息表中的一条记录。

1.4. 设计方向:

以时空对象的概念组织空间数据和属性数据,使得对地物变迁历史的查询和分析成为可能。

对应用层屏蔽历史数据的处理过程,将历史数据的处理当作数据库模块的功能之一。

1.5. 技术要点:

1、 Oracle 包变量的会话独立性

2、 动态视图技术(基于函数的视图)

http:

1.6. 图形解说:

//emag.csdn.net 2005 年 1 月 1 期 总第 3- 15 - 期

时间

空间

对象诞生时间

观察方向

当前观察时间 对象消亡时间

快照 3快照 2快照 1

时空对象(对象一)

对象三

对象二

Page 20: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

从以上示意图中可以清晰地看出,每一个时空对象都是由多个快照记录所描述的。观察者的

每一次观察都是基于一个特定的观察时间的。例如,图示中的观察者应该看到对象一的快照 2 和

对象三的快照 2,而无法看到对象二和对象一、三的其他快照记录。看不到对象二是因为在此观察

时间之前,对象二已经消亡。看不到对象一的快照 1 是因为对象一有更新的观察数据快照 2 可以

更好地近似反映对象二在当前观察时间所处的状态。

1.7. 数据表:

数据表的设计基于以上概念

2005 年 1 月 1 期 总第 3 期

- 16 -

表 1-1 表名 Times New Roman,小五) (黑体+

对象表

Obj_id NUMBER 时空对象标识号 <PK>

Start_time DATE 对象诞生时间

End_time DATE 对象消亡时间

Obj_Attr VARCHAR2(100) 对象属性数据 会因时间的流逝而发生

变化的属性信息。

快照记录表

Obj_id NUMBER 时空对象标识

<FK>

Snap_id NUMBER 快照数据的唯

一序号

<PK>

Snap_time DATE 快照时间

Snap_end DATE 快照结束时间 属于同一时空对象的

近的下一条快照的快照

时间。设置此列的目的是

为了查询方便。

Geom. MDSYS.SDO_GEOMETRY 快照几何数据

Attr VARCHAR2(100) 快照属性数据 会因时间的流逝而发生

变化的属性信息。

Page 21: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

1.8. 存储过程:

利用 Oracle 中包变量的会话独立性,在包中建立以下几个基本的存储过程:设置当前观察时

间,获取当前观察时间,利用当前观察时间和传入的 Snap_time,Snap_end 参数判断快照记录是否

可见(Snap_Filter)。

1.9. 视图:

建立在快照记录表上的视图,基于存储函数 Snap_Filter 实现对表中记录的筛选。传入参数为:

Snap_time,Snap_End.,返回值为此快照是否可见。

SELECT Obj_id, Snap_time, Geom, Attr

FROM 快照记录表

WHERE Snap_Filter(Snap_time, Snap_end) > 0;

Obj_id NUMBER 时空对象标识号

Snap_time DATE 快照时间

Geom. MDSYS.SDO_GEOMETRY 快照几何数据

Attr VARCHAR2(100) 快照属性数据

1.10. 触发器:

视图上的触发器,使应用层用户可以在视图中插入,修改,删除数据。

要点: 1、维护表中数据时要避免出现时间悖论,造成时间逻辑混乱。

2、快照记录表中的 Snap_end 列的维护稍微麻烦一些,应小心谨慎。

1.11. 扩展与变化:

1.11.1. 支持多种观察模式。

为了查询功能的灵活性,可以增加几个扩展功能的存储过程:设置当前的观察模式,获取当

2005 年 1 月 1 期 总第 3 期

- 17 -

Page 22: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

前的观察模式,重写 Snap_Filter 函数以支持多种观察模式。

例如:

【对象历史追溯模式】此时当前观察时间这一参数失效,Snap_Filter 的行为发生变化,视图

中看到的是某一(或某几个)指定对象的所有快照。这种模式便于对单个对象的整个历史变迁过

程加以追踪。

【时间段观察模式】此时需要设置的观察时间不是一个时间点,而是一个时间段。Snap_Filter

的返回值也有了更丰富的含义,可以用不同的数字(例如:1,2,4)表示某一快照记录在当前时

间段开始,结尾,中间的可见性。这种模式可以用于需要对两个不同时间点的数据进行比较的场

合。

1.11.2. 增加对象关系表以描述时空对象之间的联系

时空对象之间可能会有各种各样的联系,例如:变化,融合,分裂等。可通过以下表格加以

描述。

Obj_1 NUMBER

Obj_2 NUMBER

Relation_type NUMBER

1.12. 使用方法:

如果是查询 新信息,即观察时间为

如果是查询历史数据,只需在数据连

所有视图中可见的记录集合都是当前观察

时空对象关系表

时空对象标识号 <PK><FK>

时空对象标识号 <PK><FK>

关系类型 <PK>

系统当前时间,则直接访问视图即可。

接会话中调用存储过程来设置当前观察时间,其效果是

时间点可见的记录,其他记录不会出现在视图中。

2005 年 1 月 1 期 总第 3 期 - 18 -

Page 23: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

数据库管理

Oracle 中分区表的使用

本文作者Dinya ([email protected])

摘要:在大量业务数据处理的项目中,可以考虑使用分区表来提高应用系统的性能并方便数

据管理,本文详细介绍了分区表的使用。

在大型的企业应用或企业级的数据库应用中,要处理的数据量通常可以达到几十到几百 GB,

有的甚至可以到 TB 级。虽然存储介质和数据处理技术的发展也很快,但是仍然不能满足用户的需

求,为了使用户的大量的数据在读写操作和查询中速度更快,Oracle 提供了对表和索引进行分区

的技术,以改善大型应用系统的性能。

使用分区的优点:

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

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

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

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

Oracle 数据库提供对表或索引的分区方法有三种:

范围分区

Hash 分区(散列分区)

复合分区

下面将以实例的方式分别对这三种分区方法来说明分区表的使用。为了测试方便,我们先建

三个表空间。

create tablespace dinya_space01

datafile '/test/demo/oracle/demodata/dinya01.dnf' size 50M

create tablespace dinya_space01

datafile '/test/demo/oracle/demodata/dinya02.dnf' size 50M

2005 年 1 月 1 期 总第 3 期

- 19 -

Page 24: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net 2005 年 1 月 1 期 总第 3 期

- 20 -

create tablespace dinya_space01

datafile '/test/demo/oracle/demodata/dinya03.dnf' size 50M

1.1. 分区表的创建

1.1.1. 范围分区

范围分区就是对数据表中的某个值的范围进行分区,根据某个值的范围,决定将该数据存储

在哪个分区上。如根据序号分区,根据业务记录的创建日期进行分区等。

需求描述:有一个物料交易表,表名:material_transactions。该表将来可能有千万级的数

据记录数。要求在建该表的时候使用分区表。这时候我们可以使用序号分区三个区,每个区中预

计存储三千万的数据,也可以使用日期分区,如每五年的数据存储在一个分区上。

根据交易记录的序号分区建表:

SQL> create table dinya_test

2 (

3 transaction_id number primary key,

4 item_id number(8) not null,

5 item_description varchar2(300),

6 transaction_date date not null

7 )

8 partition by range (transaction_id)

9 (

10 partition part_01 values less than(30000000) tablespace dinya_space01,

11 partition part_02 values less than(60000000) tablespace dinya_space02,

12 partition part_03 values less than(maxvalue) tablespace dinya_space03

13 );

Table created.

建表成功,根据交易的序号,交易 ID 在三千万以下的记录将存储在第一个表空间

dinya_space01 中,分区名为:par_01,在三千万到六千万之间的记录存储在第二个表空间:

dinya_space02 中,分区名为:par_02,而交易 ID 在六千万以上的记录存储在第三个表空间

dinya_space03 中,分区名为 par_03.

根据交易日期分区建表:

SQL> create table dinya_test

2 (

3 transaction_id number primary key,

4 item_id number(8) not null,

Page 25: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net 2005 年 1 月 1 期 总第 3 期

- 21 -

5 item_description varchar2(300),

6 transaction_date date not null

7 )

8 partition by range (transaction_date)

9 (

10 partition part_01 values less than(to_date('2006-01-01','yyyy-mm-dd'))

tablespace dinya_space01,

11 partition part_02 values less than(to_date('2010-01-01','yyyy-mm-dd'))

tablespace dinya_space02,

12 partition part_03 values less than(maxvalue) tablespace dinya_space03

13 );

Table created.

这样我们就分别建了以交易序号和交易日期来分区的分区表。每次插入数据的时候,系统将

根据指定的字段的值来自动将记录存储到制定的分区(表空间)中。

当然,我们还可以根据需求,使用两个字段的范围分布来分区,如

partition by range ( transaction_id ,transaction_date),

分区条件中的值也做相应的改变,请读者自行测试。

1.1.2. Hash 分区(散列分区)

散列分区为通过指定分区编号来均匀分布数据的一种分区类型,因为通过在 I/O 设备上进行

散列分区,使得这些分区大小一致。如将物料交易表的数据根据交易 ID 散列地存放在指定的三个

表空间中:

SQL> create table dinya_test

2 (

3 transaction_id number primary key,

4 item_id number(8) not null,

5 item_description varchar2(300),

6 transaction_date date

7 )

8 partition by hash(transaction_id)

9 (

10 partition part_01 tablespace dinya_space01,

11 partition part_02 tablespace dinya_space02,

12 partition part_03 tablespace dinya_space03

13 );

Table created.

建表成功,此时插入数据,系统将按 transaction_id 将记录散列地插入三个分区中,这里也

Page 26: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

就是三个不同的表空间中。

1.1.3. 复合分区

有时候我们需要根据范围分区后,每个分区内的数据再散列地分布在几个表空间中,这样我

们就要使用复合分区。复合分区是先使用范围分区,然后在每个分区内再使用散列分区的一种分

区方法,如将物料交易的记录按时间分区,然后每个分区中的数据分三个子分区,将数据散列地

存储在三个指定的表空间中:

SQL> create table dinya_test

2 (

3 transaction_id number primary key,

4 item_id number(8) not null,

5 item_description varchar2(300),

6 transaction_date date

7 )

8 partition by range(transaction_date)subpartition by hash(transaction_id)

9 subpartitions 3 store in (dinya_space01,dinya_space02,dinya_space03)

10 (

11 partition part_01 values less than(to_date('2006-01-01','yyyy-mm-dd')),

12 partition part_02 values less than(to_date('2010-01-01','yyyy-mm-dd')),

13 partition part_03 values less than(maxvalue)

14 );

Table created.

该例中,先是根据交易日期进行范围分区,然后根据交易的 ID 将记录散列地存储在三个表空

间中。

1.2. 分区表操作

以上了解了三种分区表的建表方法,下面将使用实际的数据并针对按日期的范围分区来测试

分区表的数据记录的操作。

1.2.1. 插入记录:

SQL> insert into dinya_test values(1,12,'BOOKS',sysdate);

1 row created.

SQL> insert into dinya_test values(2,12, 'BOOKS',sysdate+30);

1 row created.

2005 年 1 月 1 期 总第 3 期

- 22 -

Page 27: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net 2005 年 1 月 1 期 总第 3 期

- 23 -

SQL> insert into dinya_test values(3,12, 'BOOKS',to_date('2006-05-30','yyyy-mm-dd'));

1 row created.

SQL> insert into dinya_test values(4,12, 'BOOKS',to_date('2007-06-23','yyyy-mm-dd'));

1 row created.

SQL> insert into dinya_test values(5,12, 'BOOKS',to_date('2011-02-26','yyyy-mm-dd'));

1 row created.

SQL> insert into dinya_test values(6,12, 'BOOKS',to_date('2011-04-30','yyyy-mm-dd'));

1 row created.

SQL> commit;

Commit complete.

SQL>

按上面的建表结果,2006 年前的数据将存储在第一个分区 part_01 上,而 2006 年到 2010 年

的交易数据将存储在第二个分区 part_02 上,2010 年以后的记录存储在第三个分区 part_03 上。

1.2.2. 查询分区表记录:

SQL> select * from dinya_test partition(part_01);

TRANSACTION_ID ITEM_ID ITEM_DESCRIPTION TRANSACTION_DATE

--------------------------------------------------------------------------------

1 12 BOOKS 2005-1-14 14:19:

2 12 BOOKS 2005-2-13 14:19:

SQL>

SQL> select * from dinya_test partition(part_02);

TRANSACTION_ID ITEM_ID ITEM_DESCRIPTION TRANSACTION_DATE

--------------------------------------------------------------------------------

3 12 BOOKS 2006-5-30

4 12 BOOKS 2007-6-23

SQL>

SQL> select * from dinya_test partition(part_03);

TRANSACTION_ID ITEM_ID ITEM_DESCRIPTION TRANSACTION_DATE

--------------------------------------------------------------------------------

5 12 BOOKS 2011-2-26

6 12 BOOKS 2011-4-30

SQL>

从查询的结果可以看出,插入的数据已经根据交易时间范围存储在不同的分区中。这里是指

定了分区的查询,当然也可以不指定分区,直接执行 select * from dinya_test查询全部记录。

在也检索的数据量很大的时候,指定分区会大大提高检索速度。

Page 28: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

1.2.3. 更新分区表的记录:

SQL> update dinya_test partition(part_01) t set t.item_description='DESK' where

t.transaction_id=1;

1 row updated.

SQL> commit;

Commit complete.

SQL>

这里将第一个分区中的交易 ID=1 的记录中的 item_description 字段更新为“DESK”,可以看

到已经成功更新了一条记录。但是当更新的时候指定了分区,而根据查询的记录不在该分区中时,

将不会更新数据,请看下面的例子:

SQL> update dinya_test partition(part_01) t set t.item_description='DESK' where

t.transaction_id=6;

0 rows updated.

SQL> commit;

Commit complete.

SQL>

指定了在第一个分区中更新记录,但是条件中限制交易 ID 为 6,而查询全表,交易 ID 为 6 的

记录在第三个分区中,这样该条语句将不会更新记录。

1.2.4. 删除分区表记录:

SQL> delete from dinya_test partition(part_02) t where t.transaction_id=4;

1 row deleted.

SQL> commit;

Commit complete.

SQL>

2005 年 1 月 1 期 总第 3 期

- 24 -

Page 29: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

上面例子删除了第二个分区 part_02 中的交易记录 ID 为 4 的一条记录,和更新数据相同,如

果指定了分区,而条件中的数据又不在该分区中时,将不会删除任何数据。

1.3. 分区表索引的使用:

分区表和一般表一样可以建立索引,分区表可以创建局部索引和全局索引。当分区中出现许

多事务并且要保证所有分区中的数据记录的唯一性时采用全局索引。

1.3.1. 局部索引分区的建立:

SQL> create index dinya_idx_t on dinya_test(item_id)

2 local

3 (

4 partition idx_1 tablespace dinya_space01,

5 partition idx_2 tablespace dinya_space02,

6 partition idx_3 tablespace dinya_space03

7 );

Index created.

SQL>

看查询的执行计划,从下面的执行计划可以看出,系统已经使用了索引:

SQL> select * from dinya_test partition(part_01) t where t.item_id=12;

Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=187)

1 0 TABLE ACCESS (BY LOCAL INDEX ROWID) OF 'DINYA_TEST' (Cost=

2 Card=1 Bytes=187)

2 1 INDEX (RANGE SCAN) OF 'DINYA_IDX_T' (NON-UNIQUE) (Cost=1

Card=1)

Statistics

----------------------------------------------------------

0 recursive calls

0 db block gets

4 consistent gets

0 physical reads

0 redo size

334 bytes sent via SQL*Net to client

309 bytes received via SQL*Net from client

2 SQL*Net roundtrips to/from client

2005 年 1 月 1 期 总第 3 期

- 25 -

Page 30: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net 2005 年 1 月 1 期 总第 3 期

- 26 -

1 sorts (memory)

0 sorts (disk)

2 rows processed

SQL>

1.3.2. 全局索引分区的建立。

全局索引建立时 global 子句允许指定索引的范围值,这个范围值为索引字段的范围值:

SQL> create index dinya_idx_t on dinya_test(item_id)

2 global partition by range(item_id)

3 (

4 partition idx_1 values less than (1000) tablespace dinya_space01,

5 partition idx_2 values less than (10000) tablespace dinya_space02,

6 partition idx_3 values less than (maxvalue) tablespace dinya_space03

7 );

Index created.

SQL>

本例中对表的 item_id 字段建立索引分区,当然也可以不指定索引分区名直接对整个表建立

索引,如:

SQL> create index dinya_idx_t on dinya_test(item_id);

Index created.

SQL>

同样的,对全局索引根据执行计划可以看出索引已经可以使用:

SQL> select * from dinya_test t where t.item_id=12;

Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=3 Bytes=561)

1 0 TABLE ACCESS (BY GLOBAL INDEX ROWID) OF 'DINYA_TEST' (Cost

=2 Card=3 Bytes=561)

2 1 INDEX (RANGE SCAN) OF 'DINYA_IDX_T' (NON-UNIQUE) (Cost=1

Card=3)

Statistics

----------------------------------------------------------

5 recursive calls

0 db block gets

10 consistent gets

0 physical reads

Page 31: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net 2005 年 1 月 1 期 总第 3 期

- 27 -

0 redo size

420 bytes sent via SQL*Net to client

309 bytes received via SQL*Net from client

2 SQL*Net roundtrips to/from client

3 sorts (memory)

0 sorts (disk)

5 rows processed

SQL>

1.4. 分区表的维护:

了解了分区表的建立、索引的建立、表和索引的使用后,在应用的还要经常对分区进行维护

和管理。日常维护和管理的内容包括:增加一个分区,合并一个分区及删除分区等等。下面以范

围分区为例说明增加、合并、删除分区的一般操作:

1.4.1. 增加一个分区:

SQL> alter table dinya_test

2 add partition part_04 values less than(to_date('2012-01-01','yyyy-mm-dd'))

tablespace dinya_spa

ce03;

Table altered.

SQL>

增加一个分区的时候,增加的分区的条件必须大于现有分区的 大值,否则系统将提示

ORA-14074 partition bound must collate higher than that of the last partition 错误。

1.4.2. 合并一个分区:

SQL> alter table dinya_test merge partitions part_01,part_02 into partition part_02;

Table altered.

SQL>

在本例中将原有的表的part_01 分区和part_02 分区进行了合并,合并后的分区为part_02,如

果在合并的时候把合并后的分区定为part_01 的时候,系统将提示ORA-14275 cannot reuse

lower-bound partition as resulting partition 错误。

Page 32: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

1.4.3. 删除分区:

SQL> alter table dinya_test drop partition part_01;

Table altered.

SQL>

删除分区表的一个分区后,查询该表的数据时显示,该分区中的数据已全部丢失,所以执行

删除分区动作时要慎重,确保先备份数据后再执行,或将分区合并。

1.5. 总结:

需要说明的是,本文在举例说名分区表事务操作的时候,都指定了分区,因为指定了分区,

系统在执行的时候则只操作该分区的记录,提高了数据处理的速度。不要指定分区直接操作数据

也是可以的。在分区表上建索引及多索引的使用和非分区表一样。此外,因为在维护分区的时候

可能对分区的索引会产生一定的影响,可能需要在维护之后重建索引,相关内容请参考分区表索

引部分的文档。

作者简介:

姓名:丁亚军

网名:dinya

曾做 Windows 程序开发。

现就职于一家制造企业,做 Oracle ERP 二次开发工作,对 Oracle ERP 二次开发和 Oracle 数据

库开发有一定研究,现任 CSDN 论坛 Oracle 开发版版主,CSDN 社区 Oracle 电子杂志编辑。

作者Mail:[email protected]

作者Blog:http://blog.csdn.net/dinya2003/

个人Blog:http://blog.itpub.net/biti_riany

E-mail:[email protected]

2005 年 1 月 1 期 总第 3 期

- 28 -

Page 33: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

数据库开发

VC+ADO 开发 Oracle 应用程序

——Oracle 应用程序开发(一)

本文作者: SnowyWolf ([email protected] )

摘要:本文提供了建立 Oracle 客户端应用程序的一种方式――使用 Visual C++ 6.0 和 ADO 接

口来访问 Oracle 数据库,并封装了两个实用类。

经常有朋友问如何将图片或文件存入 Oracle 数据库,也有朋友问如何操作 Oracle 中的 BLOB

字段,解决类似的问题有很多方法,VC+ADO 开发 Oracle 客户端应用程序即是一种不错的解决方

案。

可能很多朋友感觉 VC 很难,ADO 很麻烦,其实不然。本文通过一个 Demo,一步一步给您

演示使用 VC+ADO 开发 Oracle 客户端应用程序的步骤。

本文适用读者:有一定的 VC 开发经验,熟悉 Oracle 基本概念

难度等级:中级

1.1. 准备工作

要顺利完成本文的 Demo,您需要做好如下的准备工作:

硬件:一台 PC

操作系统:Windows NT/2000/XP/2003

编译环境:Visual Studio 6.0 + SP3/SP5/SP6

数据库:可连通的 Oracle 服务器及可用的账号、密码,Connect/Resource 权限,并配置好 Net

Config

网络:可连接到 WWW 的网络

下载:http://www.snowywolf.net/MyFolder/Source/adoSourceCode.rar(9K) 并解压到本地硬盘,

解压后是四个文件:ADOConnection.h/ADOConnection.cpp/ADORecordset.h/ADORecordset.cpp 2005 年 1 月 1 期 总第 3 期

- 29 -

Page 34: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

1.2. 建立 VC 工程

在 D:建立 VCProg 文件夹

打开 Microsoft Visual C++ 6.0

菜单:[File]->[New]

Project 选项卡中选择:MFC AppWizard(exe)

Location 中输入:D:\VCProg\

Project name 中输入:OraApp (输入的时候可以发现 Location 在同步变化)

点击 OK,弹出 MFC AppWizard - Step1,我们将创建一个基于对话框的应用程序,所以应用

程序类型选择:Dialog based

2005 年 1 月 1 期 总第 3 期

- 30 -

Page 35: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

其余参数保持默认,直接点[Finish]按键,结束向导。

http://emag.csdn.net 2005 年 1 月 1 期 总第 3 期

- 31 -

Page 36: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

点击 OK

将前面下载并解压的四的文件拷贝到 D:\VCProg\OraApp 下,文件夹内容如下所示:

2005 年 1 月 1 期 总第 3 期

- 32 -

Page 37: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

Visual C++ 6.0 中,WorkSpace 视口中选择 FileView 选项卡,在 OraApp Files 节点上右键单击,

弹出的菜单中点击[Add File to project…]

2005 年 1 月 1 期 总第 3 期

- 33 -

Page 38: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

选择拷贝过来的四个文件添加到当前工程中

2005 年 1 月 1 期 总第 3 期

- 34 -

Page 39: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net 2005 年 1 月 1 期 总第 3 期

- 35 -

打开并编辑 StdAfx.h 文件:

添加:

#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \

rename_namespace("MYADO") rename("EOF", "EndOfFile")

Page 40: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

COraApp::InitInstance()函数中 AfxEnableControlContainer();一行下添加如下代码:

if(!AfxOleInit())

{

AfxMessageBox("OLE初始化失败!");

return FALSE;

}

保存工程:菜单 [File]->[Save All]

按[F7]编译工程,应该没有错误(有一处警告),如果有错误,检查前面的步骤。

按[F5]运行程序,结果如下:

2005 年 1 月 1 期 总第 3 期

- 36 -

Page 41: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

至此,建立 VC 工程完毕。

1.3. 设计应用程序界面

WorkSpace 视口中选择 Resource View,展开 Dialog 并双击 IDD_ORAAPP_DIALOG

2005 年 1 月 1 期 总第 3 期

- 37 -

Page 42: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

删除默认的确定和取消按钮,添加如下三个按钮,并将它们的 ID 分别设为 IDC_ADD /

IDC_DEL / IDC_SHOW:

2005 年 1 月 1 期 总第 3 期

- 38 -

Page 43: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

添加四个 Static Text,姓名、电话和 Email 的不需要设置 ID,photo 的 ID 设为 IDC_PHOTO

添加三个 Edit Box,ID 分别设为 IDC_NAME/IDC_TEL/IDC_EMAIL

2005 年 1 月 1 期 总第 3 期

- 39 -

Page 44: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

还需要两个按钮,ID 分别设为 IDC_CONNECT/IDC_CREATETABLE,添加并调整布局,结

果如下所示:

Ctrl+W 调出 MFC ClassWizard,在 Member Variables 选项卡中为以下控件指定 control 类型的

绑定变量:

IDC_NAME/IDC_TEL/IDC_EMAIL/IDC_PHOTO,结果如下所示:

2005 年 1 月 1 期 总第 3 期

- 40 -

Page 45: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

OK,至此,用户界面设计完成。

1.4. 填写代码

在 IDD_ORAAPP_DIALOG 设计窗口中双击[连接]按钮,VC 弹出对话框提示创建响应函数,

保留默认函数名,点击[OK]

http://emag.csdn.net 2005 年 1 月 1 期 总第 3 期

- 41 -

Page 46: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

VC 自动转到 OraAppDlg 的代码窗口,光标在 OnConnect()函数中:

2005 年 1 月 1 期 总第 3 期

- 42 -

Page 47: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

我们先不在这里添加代码,先打开 OraAppDlg.h 文件,添加两个#include 和一个成员变量的

定义:

转回到 OnConnect()函数,添加如下代码:

void COraAppDlg::OnConnect()

{

//此处的连接参数需要根据具体情况进行修改

//参数的顺序为 SID UserName Password

m_con.OpenOracle("sunserve","sm5","sm5");

if(m_con.IsConnected())

{

AfxMessageBox("已建立到 Oracle服务器的连接");

}

else

{

AfxMessageBox("建立到 Oracle服务器的连接失败,请检查连接参数");

}

2005 年 1 月 1 期 总第 3 期

- 43 -

Page 48: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net 2005 年 1 月 1 期 总第 3 期

- 44 -

}

OK,现在可以编译并运行一下程序看一下效果了,按[F5]->是[Yes],应该没有编译错误,弹

出对话框,点连接按钮,如果连接参数正确,会弹出成功建立连接的消息。

转回 DIALOG 设计窗口,双击[建表]按钮,添加响应函数:

Page 49: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net 2005 年 1 月 1 期 总第 3 期

- 45 -

点击 OK,并在 OnCreateTable()函数中添加如下代码:

void COraAppDlg::OnCreatetable()

{

if(!m_con.IsConnected())

{

AfxMessageBox("请先点击连接按钮建立到数据库的连接");

return;

}

CString strSQL;

strSQL.Format("Drop table MyFriends");

m_con.Execute(strSQL);

strSQL.Format("Create table MyFriends("

"ID int primary key, "

"Name varchar2(20),"

"Tel varchar2(20),"

"Email varchar2(32),"

"Photo Blob default empty_blob())");

if(m_con.Execute(strSQL))

{

AfxMessageBox("建表成功!");

}

else

{

AfxMessageBox("建表失败!");

}

}

按[F5]->是(Y)编译并运行程序,如果直接点建表,会提示需要先连接,点连接按钮建立连接,

点击建表按钮,应该提示建表成功。

下面该添加记录了,很简单:

DIALOG 设计视图中双击[添加]按钮并添加默认响应函数,在 OnAdd()函数中添加如下代码:

void COraAppDlg::OnAdd()

{

if(!m_con.IsConnected())

{

AfxMessageBox("请先点击连接按钮建立到数据库的连接");

return;

}

Page 50: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net 2005 年 1 月 1 期 总第 3 期

- 46 -

CADORecordset rs; //定义 Recordset对象

rs.SetConnection(&m_con); //为 Recordset对象设置连接对象

CString strSQL;

strSQL.Format("Select * from MyFriends where 1<0"); //构造 SQL语句

rs.OpenForUpdate(strSQL); //以可更新方式打开

rs.AddNew(); //声明一下要添加记录

rs.SetIntValue(0,1); //ID

rs.SetStringValue(1,"SnowyWolf"); //Name

rs.SetStringValue(2,"12345678"); //Tel

rs.SetStringValue(3,"[email protected]"); //Email

//=======================================================

//{{ by LISJ at [2005-01-26 09:53:40]

// * 下面一段很关键,就是很多人都关心的把图片文件写入到 BLOB字段中

CFile file;

file.Open("d:\\vcprog\\lsj.jpg",CFile::modeRead); //打开图片文件

int nDataLen = file.GetLength();

BYTE * pData = new BYTE[nDataLen]; //开辟内存空间

file.Read(pData,nDataLen);

file.Close();

rs.SetBlobValue(4,pData,nDataLen); //这么简单?对!就是这么简单

//}} by LISJ at [2005-01-26 09:53:40]

//=======================================================

if(rs.Update())

{

AfxMessageBox("成功添加记录!");

}

else

{

AfxMessageBox("添加记录失败!");

}

delete []pData; //不要忘记释放内存

}

按[F5]->是(Y)编译并运行程序,还是要先点[连接]建立到数据库的连接,点[添加],提示记录

添加成功,此处可以验证一下,在 SQLPlus 中:

SQL> select id,name,tel,email,dbms_lob.getlength(photo) from myfriends;

ID NAME TEL

---------- -------------------- --------------------

EMAIL DBMS_LOB.GETLENGTH(PHOTO)

-------------------------------- -------------------------

Page 51: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net 2005 年 1 月 1 期 总第 3 期

- 47 -

1 SnowyWolf 12345678

[email protected] 44854

删除操作很简单,为[删除]按钮添加默认响应函数,OnDel()函数代码如下:

void COraAppDlg::OnDel()

{

if(!m_con.IsConnected())

{

AfxMessageBox("请先点击连接按钮建立到数据库的连接");

return;

}

CString strSQL;

strSQL.Format("truncate table myfriends");

m_con.Execute(strSQL);

}

这段代码很简单,就不过多解释了。

下面是 后一个按钮了,也是一个关键部分:

添加[显示]按钮的默认响应函数,OnShow()代码如下:

void COraAppDlg::OnShow()

{

if(!m_con.IsConnected())

{

AfxMessageBox("请先点击连接按钮建立到数据库的连接");

return;

}

int nRecCount = 0;

CADORecordset rs;

rs.SetConnection(&m_con);

//=======================================================

//{{ by LISJ at [2005-01-26 10:12:34]

// * 检查表中是否有可以显示的记录

CString strSQL;

strSQL.Format("Select Count(*) from MyFriends where id>0");

rs.OpenForReadonly(strSQL);

rs.GetIntValue(0,nRecCount);

if(nRecCount<1)

{

Page 52: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net 2005 年 1 月 1 期 总第 3 期

- 48 -

AfxMessageBox("表中没有可以显示的记录,请先添加记录");

rs.Close();

return;

}

//}} by LISJ at [2005-01-26 10:12:34]

//=======================================================

CString strName,strTel,strEmail;

strSQL.Format("Select * from MyFriends");

rs.OpenForReadonly(strSQL);

rs.GetStringValue(1,strName);

rs.GetStringValue("Tel",strTel);

rs.GetStringValue("Email",strEmail);

//=======================================================

//{{ by LISJ at [2005-01-26 10:15:07]

// * 读取 BLOB字段的数据,也不麻烦,是吧

BYTE * pData = NULL;

int nLenth = 0;

rs.GetBlobValue(4,pData,nLenth);

//}} by LISJ at [2005-01-26 10:15:07]

//=======================================================

rs.Close();

//=======================================================

//{{ by LISJ at [2005-01-26 10:30:48]

// * 显示姓名、电话和 Email

m_editName.SetWindowText(LPCTSTR(strName));

m_editTel.SetWindowText(LPCTSTR(strTel));

m_editEmail.SetWindowText(LPCTSTR(strEmail));

//}} by LISJ at [2005-01-26 10:30:48]

//=======================================================

//=======================================================

//{{ by LISJ at [2005-01-26 10:15:45]

// * 下面这段代码比较麻烦,是要显示图片

CDC *pDC = m_picPhoto.GetDC();

IStream *pStm;

HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, nLenth);

Page 53: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net 2005 年 1 月 1 期 总第 3 期

- 49 -

LPVOID pvData = NULL;

if (hGlobal != NULL)

{

if ((pvData = GlobalLock(hGlobal)) != NULL)

{

memcpy(pvData,pData,nLenth);

GlobalUnlock(hGlobal);

CreateStreamOnHGlobal(hGlobal, TRUE, &pStm);

}

}

IPicture *pPic;

if(SUCCEEDED(OleLoadPicture(pStm,nLenth,TRUE,IID_IPicture,(LPVOID*)&pPic))

)

{

OLE_XSIZE_HIMETRIC hmWidth;

OLE_YSIZE_HIMETRIC hmHeight;

pPic->get_Width(&hmWidth);

pPic->get_Height(&hmHeight);

double fX,fY;

fX =

(double)pDC->GetDeviceCaps(HORZRES)*(double)hmWidth/((double)pDC->GetDeviceCaps(HO

RZSIZE)*100.0);

fY =

(double)pDC->GetDeviceCaps(VERTRES)*(double)hmHeight/((double)pDC->GetDeviceCaps(V

ERTSIZE)*100.0);

if(FAILED(pPic->Render(*pDC,0,0,(DWORD)fX,(DWORD)fY,0,hmHeight,hmWidth,-hmHeig

ht,NULL)))

AfxMessageBox("显示图片失败!");

pPic->Release();

}

else

{

AfxMessageBox("装载图像失败!");

}

//}} by LISJ at [2005-01-26 10:15:45]

//=======================================================

delete []pData;

}

很精彩的一段代码,Isn’t it?

Page 54: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

调整一下 Dialog 的布局,[F5]编译并运行, 终效果如下所示:

1.5. 小结一下

至此,VC+ADO 实现 Oracle 客户端应用程序的 DEMO 就全部完成了,您会发现这个应用程

序有很多不足之处:

没有处理错误消息

只能处理一条记录,不能前后移动游标

不能对当前记录进行修改

… …

但它毕竟只是一个 DEMO,时间、篇幅的限制加上雪狼水平有限,还不能把它做得很完美。

但至少我们建立了一个能完成基本功能的 Oracle 应用程序,通过雪狼封装并对您提供的两个

类,您可以方便地进行如下操作:

建立/断开与数据库的连接

执行 SQL 语句

开始/提交/回滚事务

查询结果集并获取数据

2005 年 1 月 1 期 总第 3 期

- 50 -

Page 55: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

添加、修改记录

游标的自由移动

……

1.6. 两个封装类的说明

下面对两个封装类的方法作简要的说明,更详细的说明请直接查看源代码。

1.6.1. CADOConnection

数据连接类,建立/断开与数据库的连接,执行 SQL 语句

方法说明:

方法 简要说明

OpenOracle 建立与 Oracle 数据库服务器的连接

IsConnected 判断是否已连接

Close 关闭连接

Execute 执行 SQL 语句

BeginTrans 开始事务

CommitTrans 提交事务

Rollback 回滚事务

CheckError 处理错误信息

1.6.2. CADORecordset

记录集类,处理查询结果集。

方法说明:

方法 简要说明

SetConnection 设置连接对象的指针

SetSQL 设置查询 SQL 语句

OpenForReadonly 以只读方式打开

OpenForUpdate 以可更新方式打开

2005 年 1 月 1 期 总第 3 期

- 51 -

Page 56: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

IsOpen 判断记录集是否已打开

CanUpdate 判断是否要执行更新操作

IsBOF 是否到记录集头

IsEOF 是否到记录集尾

IsEmpty 记录集是否为空

MoveFirst 移到第一条记录

MovePrev 移到前一条记录

MoveNext 移到后一条记录

MoveLast 移到 后一条记录

GetFieldName 指定序号获取字段的名字

GetFieldType 指定序号或名字获取字段的类型

GetFieldCount 获取字段的数目

GetIntValue

GetDoubleValue

GetStringValue

GetBlobValue

获取指定字段的值

SetIntValue

SetDoubleValue

SetStringValue

SetBlobValue

设置指定字段的值

AddNew 添加新的记录

Update 提交更新操作

1.7. 后续工作

CADORecordset 类还需要完善,如添加 FindFrist/FindPrev/FindNext/FindLast 方法。

添加 CADOCommand 类,可以用来处理带参数的存储过程

增加对其他数据类型的读写,如时间类型等

2005 年 1 月 1 期 总第 3 期

- 52 -

Page 57: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

1.8. 完整源代码下载

http://www.snowywolf.net/MyFolder/Source/vcprog.rar

作者简介:

姓名:李绍俊

网名:SnowyWolf

照片

暂缺

CSDN eMag Oracle 电子杂志主编

现任 itpub Oracle 电子文档版版主.

作品展示:

Oracle 9i/10g 部分在线文档(chm 版)

http://www.snowywolf.net/chm.htm

Ask Tom 历年问题合订本(chm 版)

http://www.snowywolf.net/chm.htm

DBA 小工具 OraExplore

http://www.snowywolf.net/OraExplore/index.htm

个人主页:http://www.snowywolf.net

E-mail:[email protected]

[email protected]

2005 年 1 月 1 期 总第 3 期

- 53 -

Page 58: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

数据库探秘

深入了解 Oracle 数据字典

——深入了解 Oracle 数据字典,提高自学习 Oracle 能力

本文作者: eygle ([email protected] )

摘要:我们知道 Oracle 通过数据字典来管理和展现数据库信息,这些信息至关重要。正确理

解这部分内容有助于加强我们的 oracle 学习能力。

本文对 Oracle 数据字典的关系进行探讨。

接下来我们介绍一下怎样通过数据库本身来学习研究数据库。

首先,Oracle 的字典表和视图基本上可以分为三个层次。

1.1. X$表

这一部分表是 Oracle 数据库的运行基础,在数据库启动时由 Oracle 应用程序动态创建。

这部分表对数据库来说至关重要,所以 Oracle 不允许 SYSDBA 之外的用户直接访问,显式授权不

被允许。

如果显式授权你会收到如下错误:

SQL> grant select on x$ksppi to eygle;

grant select on x$ksppi to eygle

*

ERROR at line 1:

ORA-02030: can only select from fixed tables/views

2005 年 1 月 1 期 总第 3 期

- 54 -

1.2. GV$和 V$视图

从 Oracle8 开始,GV$视图开始被引入,其含义为 Global V$.

除了一些特例以外,每个 V$视图都有一个对应的 GV$视图存在。

Page 59: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

GV$视图的产生是为了满足 OPS 环境的需要,在 OPS 环境中,查询 GV$视图返回所有实例信

息,而每个 V$视图基于 GV$视图,增加了 INST_ID 列判断后建立,只包含当前连接实例信息。

注意,每个 V$视图都包含类似语句:

where inst_id = USERENV('Instance')

用于限制返回当前实例信息。

我们从 GV$FIXED_TABLE 和 V$FIXED_TABLE 开始

SQL> select view_definition from v_$fixed_view_definition where

view_name='V$FIXED_TABLE';

VIEW_DEFINITION

------------------------------------------------------------------------------

select NAME , OBJECT_ID , TYPE , TABLE_NUM from GV$FIXED_TABLE where inst_id =

USERENV('Instance')

这里我们看到 V$FIXED_TABLE 基于 GV$FIXED_TABLE 创建。

SQL> select view_definition from v_$fixed_view_definition where

view_name='GV$FIXED_TABLE';

VIEW_DEFINITION

------------------------------------------------------------------------------

select inst_id,kqftanam, kqftaobj, 'TABLE', indx from x$kqfta

union all

select inst_id,kqfvinam, kqfviobj, 'VIEW', 65537 from x$kqfvi

union all

select inst_id,kqfdtnam, kqfdtobj, 'TABLE', 65537 from x$kqfdt

这样我们找到了 GV$FIXED_TABLE 视图的创建语句,该视图基于 X$表创建。

1.3. GV_$,V_$视图和 V$,GV$同义词

这些视图是通过 catalog.ql 创建。

当 catalog.sql 运行时:

create or replace view v_$fixed_table as select * from v$fixed_table;

create or replace public synonym v$fixed_table for v_$fixed_table;

create or replace view gv_$fixed_table as select * from gv$fixed_table;

create or replace public synonym gv$fixed_table for gv_$fixed_table;

我们注意到,第一个视图 V_$和 GV_$首先被创建,v_$和 gv_$两个视图。

2005 年 1 月 1 期 总第 3 期

- 55 -

Page 60: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

然后基于 V_$视图的同义词被创建。

所以,实际上通常我们访问的 V$视图,其实是指向 V_$视图的同义词。

而 V_$视图是基于真正的 V$视图(这个视图是基于 X$表建立的)。

而 v$fixed_view_definition 视图是我们研究 Oracle 对象关系的一个入口,仔细理解 Oracle 的数

据字典机制,有助于深入了解和学习 Oracle 数据库知识。

1.4. 再进一步

2005 年 1 月 1 期 总第 3 期

- 56 -

1.4.1. X$表

关于 X$表,其创建信息我们也可以从数据字典中一窥究竟。

首先我们考察 bootstrap$表,该表中记录了数据库启动的基本及驱动信息。

SQL> select * from bootstrap$;

LINE# OBJ# SQL_TEXT

------------------------------------------------------------------------------

-1 -1 8.0.0.0.0

0 0 CREATE ROLLBACK SEGMENT SYSTEM STORAGE ( INITIAL 112K NEXT 1024K

MINEXTENTS 1 M

8 8 CREATE CLUSTER C_FILE#_BLOCK#("TS#" NUMBER,"SEGFILE#"

NUMBER,"SEGBLOCK#" NUMBER)

9 9 CREATE INDEX I_FILE#_BLOCK# ON CLUSTER C_FILE#_BLOCK# PCTFREE

10 INITRANS 2 MAXT

14 14 CREATE TABLE SEG$("FILE#" NUMBER NOT NULL,"BLOCK#" NUMBER NOT

NULL,"TYPE#" NUMBE

5 5 CREATE TABLE CLU$("OBJ#" NUMBER NOT NULL,"DATAOBJ#" NUMBER,"TS#"

NUMBER NOT NULL

6 6 CREATE CLUSTER C_TS#("TS#" NUMBER) PCTFREE 10 PCTUSED 40 INITRANS

2 MAXTRANS 255

7 7 CREATE INDEX I_TS# ON CLUSTER C_TS# PCTFREE 10 INITRANS 2 MAXTRANS

255 STORAGE (

....

这部分信息,在数据库启动时 先被加载,跟踪数据库的启动过程,我们发现数据库启动的

第一个动作就是:

create table bootstrap$ ( line# number not null, obj#

number not null, sql_text varchar2(4000) not null) storage (initial

50K objno 56 extents (file 1 block 377))

Page 61: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

这部分代码是写在 Oracle 应用程序中的,在内存中创建了 bootstrap$以后,Oracle 就可以从 file

1,block 377 上读取其他信息,创建重要的数据库对象。从而根据这一部分信息启动数据库,这就

实现了数据库的引导,类似于操作系统的初始化。

这部分你可以参考 biti_rainy 的文章。

X$表由此建立。这一部分表可以从 v$fixed_table 中查到:

SQL> select count(*) from v$fixed_table where name like 'X$%';

COUNT(*)

----------

394

共有 394 个 X$对象被记录。

1.4.2. GV$和 V$视图

X$表建立以后,基于 X$表的 GV$和 V$视图得以创建。 这部分视图我们也可以通过查询 V$FIXED_TABLE 得到。 SQL> select count(*) from v$fixed_table where name like 'GV$%';

COUNT(*)

----------

259

这一部分共 259 个对象。 SQL> select count(*) from v$fixed_table where name like 'V$%';

COUNT(*)

----------

259

同样是 259 个对象。

v$fixed_table 共记录了:

394 + 259 + 259 共 912 个对象。

我们通过 V$PARAMETER 视图来追踪一下数据库的架构:

SQL> select view_definition from v$fixed_view_definition a where

a.VIEW_NAME='V$PARAMETER';

VIEW_DEFINITION

------------------------------------------------------------------------------

2005 年 1 月 1 期 总第 3 期

- 57 -

Page 62: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net 2005 年 1 月 1 期 总第 3 期

- 58 -

select NUM , NAME , TYPE , VALUE , ISDEFAULT , ISSES_MODIFIABLE , ISSYS_MODIFIA

BLE , ISMODIFIED , ISADJUSTED , DESCRIPTION, UPDATE_COMMENT from GV$PARAMETER wh

ere inst_id = USERENV('Instance')

我们看到 V$PARAMETER 是由 GV$PARAMETER 创建的。 SQL> select view_definition from v$fixed_view_definition a where

a.VIEW_NAME='GV$PARAMETER';

VIEW_DEFINITION

-----------------------------------------------------------------------------

select x.inst_id,x.indx+1,ksppinm,ksppity,ksppstvl,ksppstdf,

decode(bitand(kspp

iflg/256,1),1,'TRUE','FALSE'),

decode(bitand(ksppiflg/65536,3),1,'IMMEDIATE',2,

'DEFERRED', 3,'IMMEDIATE','FALSE'), decode(bit

and(ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE'),

decode(bitand(ksppstvf,2)

,2,'TRUE','FALSE'), ksppdesc, ksppstcmnt from x$ksppi x, x$ksppcv y where (x.i

ndx = y.indx) and ((translate(ksppinm,'_','#') not like '#%') or (ksppstdf = 'F

ALSE'))

在这里我们看到 GV$PARAMETER 来源于 x$ksppi,x$ksppcv 两个 X$表。 x$ksppi,x$ksppcv 基

本上包含所有数据库可调整参数,v$parameter 展现的是不包含"_"开头的参数。以"_"开头的参数我

们通常称为隐含参数,一般不建议修改,但很多因为功能强大经常使用而广为人知。

Page 63: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

作者简介:

盖国强,网名 eygle

曾任 ITPUB MS 版版主,现任 itpub Oracle 管理版版主。

曾任职于某国家大型企业,服务于烟草行业,开发过基于 Oracle 数据库的大型 ERP 系统,属国家

信息产业部重点工程.同时负责 Oracle 数据库管理及优化,并为多家烟草企业提供 Oracle 数据库管

理、优化及技术支持.

目前任职于北京某电信增值业务系统提供商企业,首席DBA,负责数据库业务.管理全国 30多个

数据库系统。项目经验丰富,曾设计规划及支持中国联通增值业务等大型数据库系统.

实践经验丰富,长于数据库诊断、性能调整与 SQL 优化等。对于 Oracle 内部技术具有深入研

究。

高级培训讲师,培训经验丰富,曾主讲 itpub dba 培训及 itpub 高级性能调整等主要课程.

《Oracle 数据库 DBA 专题技术精粹》一书的主编及主要作者。

本书的部分章节及介绍你可以从以下链接得到:

http://www.eygle.com/orabk/index-book-5.htm

新书《Oracle 数据库性能优化》(暂定名)即将出版,敬请期待。

你可以在http://www.eygle.com上找到关于作者的更多信息.

2005 年 1 月 1 期 总第 3 期

- 59 -

Page 64: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

Oracle 10g 新特性

浅谈 ORACLE 10G 闪回恢复区

——(FLASH RECOVERY AREA)

本文作者: Fenng ([email protected])

1.1. 何为闪回恢复区

Oracle 10g 有一项新功能称为:自动的基于磁盘的备份与恢复( Automatic Disk-Based Backup

and Recovery )。实现该功能的基础为本文要讲述的闪回恢复区( Flash Recovery Area )。闪回恢复区

是 Oracle 10g 中的新事物。简单的说,闪回恢复区是一块用以存储恢复相关的文件的存储空间。

允许用户集中存储所有恢复相关的文件。

闪回恢复区可以放在如下几种存储形式上:

目录

一个文件系统

自动存储管理(ASM)磁盘组

在 RAC 环境中,这个该位置必须为 集群文件系统 (cluster file system) 或是 ASM 磁盘组亦

或是通过 NFS 控制的文件共享目录,还要注意的是,所有实例的位置和操作系统的磁盘限额 (disk

quota) 必须一致。

如下几种文件可以放到闪回恢复区中:

控制文件

归 档 的 日 志 文 件 ( 注 : Oracle 手 册 上 所 说 的 在 设 定 flash recovery area 之 后 ,

2005 年 1 月 1 期 总第 3 期

- 60 -

Page 65: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

LOG_ARCHIVE_DEST_10 的值将自动设定为 flash recovery area 的位置,这个变化在笔者测试

过程中观察不到)

闪回日志

控制文件和 SPFILE 自动备份

RMAN 备份集

数据文件拷贝

1.2. 为何要用闪回恢复区?

如前所述,闪回恢复区提供了一个集中化的存储区域,很大程度上减小了管理开销。这是其

主要的优点。与 RMAN 结合使用可以进行快速恢复。

近年来随着存储技术的发展,单个磁盘的存储能力已经加强。这使自动的基于磁盘的备份与

恢复的技术实现成为可能。而闪回恢复区恰是基于磁盘的备份与恢复的基础。把闪回恢复区和

OMF 与 ASM 结合运用看起来是比较完美的方案。当然,不可否认的是,自动备份恢复技术还远

远不够成熟。

1.3. 设定闪回恢复区

如果您使用 DBCA 创建的数据库,在安装时可以设定闪回恢复区的位置以及大小(点击这里查

看安装截图)--这也是 Oracle 10g OUI 的新功能之一。如果在开始的时候没有启用闪回恢复区,可

以通过如下方式设定。调整如下两个动态初始化参数(无需重新启动实例):

SQL> ALTER SYSTEM SET db_recovery_file_dest_size=2g SCOPE=BOTH;

System altered.

SQL>

SQL> ALTER SYSTEM SET

db_recovery_file_dest='/u01/app/oracle/flash_recovery_area'

2 SCOPE=BOTH;

System altered.

2005 年 1 月 1 期 总第 3 期

- 61 -

Page 66: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

SQL>

之后查看所作的修改是否生效:

SQL> SHOW parameter db_recovery_file_dest

NAME TYPE VALUE

---------------------------------------------------------------------------

db_recovery_file_dest string /u01/app/oracle/flash_recovery_area

db_recovery_file_dest_size big integer 2G

SQL>

如上所示,我们设定了闪回恢复区,位置在 /u01/app/oracle/flash_recovery_area,上限为 2G。

如果要撤销闪回恢复区,把初始化参数 DB_RECOVERY_FILE_DEST 的值清空即可。

注意:DB_RECOVERY_FILE_DEST_SIZE 只有在 DB_RECOVERY_FILE_DEST 清空之后才

可以清空。

初始化参数 db_recovery_file_dest_size 的设定有一点点需要注意的地方:

文件的第 0 块和操作系统数据块头的空间大小不包含在内

该参数并不代表实际占用的空间大小。如果空间被压缩、镜像、RAID 的话,该参数的值意

义是不一样的

2005 年 1 月 1 期 总第 3 期

- 62 -

1.4. 管理并监控闪回恢复区

我们先看看闪回恢复区内的文架结构层次

SQL> host tree /u01/app/oracle/flash_recovery_area

/u01/app/oracle/flash_recovery_area

|-- DEMO

| |-- archivelog

| | |-- 2004_12_07

| | | |-- o1_mf_1_10_0vbwz2fm_.arc

| | | |-- o1_mf_1_11_0vc1yj14_.arc

| | | |-- o1_mf_1_12_0vc6vvws_.arc

| | | |-- o1_mf_1_13_0vcbv6cg_.arc

| | | |-- o1_mf_1_14_0vchlxb3_.arc

| | | |-- o1_mf_1_15_0vcnh2bz_.arc

| | | |-- o1_mf_1_5_0vbk8goo_.arc

| | | |-- o1_mf_1_6_0vbkq6dk_.arc

| | | |-- o1_mf_1_7_0vbktl5f_.arc

| | | |-- o1_mf_1_8_0vbo97xp_.arc

| | | ̀ -- o1_mf_1_9_0vbrrlo6_.arc

Page 67: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net 2005 年 1 月 1 期 总第 3 期

- 63 -

| | ̀ -- 2004_12_08

| | |-- o1_mf_1_16_0vcnyqvf_.arc

| | |-- o1_mf_1_17_0vcp58bj_.arc

| | |-- o1_mf_1_18_0vcv4qxb_.arc

| | |-- o1_mf_1_19_0vczcsl0_.arc

| | |-- o1_mf_1_20_0vd34svw_.arc

| | |-- o1_mf_1_21_0vd7tg4h_.arc

| | |-- o1_mf_1_22_0vddq7lc_.arc

| | |-- o1_mf_1_23_0vdk0nbh_.arc

| | |-- o1_mf_1_24_0vdojjky_.arc

| | |-- o1_mf_1_25_0vdtg1rq_.arc

| | |-- o1_mf_1_26_0vdz23h2_.arc

| | |-- o1_mf_1_27_0vf3nlnw_.arc

| | |-- o1_mf_1_28_0vf6hon5_.arc

| | |-- o1_mf_1_29_0vf867lt_.arc

| | |-- o1_mf_1_30_0vf86pkg_.arc

| | ̀ -- o1_mf_1_31_0vfjphqm_.arc

| ̀ -- backupset

| |-- 2004_12_07

| | |-- o1_mf_ncsn1_TAG20041207T150715_0vboq7kv_.bkp

| | ̀ -- o1_mf_nnnd1_TAG20041207T150715_0vboo3t2_.bkp

| ̀ -- 2004_12_08

| |-- o1_mf_ncsnf_TAG20041208T161219_0vffxv2n_.bkp

| |-- o1_mf_ncsnf_TAG20041208T165456_0vfjcvgl_.bkp

| ̀ -- o1_mf_nnndf_TAG20041208T161219_0vffv40q_.bkp

`-- tracking.dbf

7 directories, 33 files

闪回恢复区中添加或删除文件等变化都将记录在数据库的 alert 日志中,Oracle 10g 也针对该

新特性提供了一个新的视图, DBA_OUTSTANDING_ALERTS,通过该视图可以得到相关的信息。

DBA_OUTSTANDING_ALERTS 视图的存在体现了 Oracle 愈加人性化的一面。我们先来看一下

该视图的基本结构,后面会用到。

SQL> DESC dba_outstanding_alerts

Name Null? Type

--------------------------------------------------------------------------

SEQUENCE_ID NUMBER

REASON_ID NOT NULL NUMBER

OWNER VARCHAR2(30)

OBJECT_NAME VARCHAR2(513)

SUBOBJECT_NAME VARCHAR2(30)

OBJECT_TYPE VARCHAR2(64)

REASON VARCHAR2(4000)

TIME_SUGGESTED TIMESTAMP(6) WITH TIME ZONE

Page 68: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net 2005 年 1 月 1 期 总第 3 期

- 64 -

CREATION_TIME TIMESTAMP(6) WITH TIME ZONE

SUGGESTED_ACTION VARCHAR2(4000)

ADVISOR_NAME VARCHAR2(30)

METRIC_VALUE NUMBER

MESSAGE_TYPE VARCHAR2(12)

MESSAGE_GROUP VARCHAR2(64)

MESSAGE_LEVEL NUMBER

HOSTING_CLIENT_ID VARCHAR2(64)

MODULE_ID VARCHAR2(64)

PROCESS_ID VARCHAR2(128)

HOST_ID VARCHAR2(256)

HOST_NW_ADDR VARCHAR2(256)

INSTANCE_NAME VARCHAR2(16)

INSTANCE_NUMBER NUMBER

USER_ID VARCHAR2(30)

EXECUTION_CONTEXT_ID VARCHAR2(60)

ERROR_INSTANCE_ID VARCHAR2(142)

SQL>

10g 的新视图 V$RECOVERY_FILE_DEST 包含闪回恢复区的相关信息:

SQL> desc V$RECOVERY_FILE_DEST

Name Null? Type

-----------------------------------------------------------------------------

NAME VARCHAR2(513)

SPACE_LIMIT NUMBER

SPACE_USED NUMBER

SPACE_RECLAIMABLE NUMBER

NUMBER_OF_FILES NUMBER

SQL> SELECT NAME, space_limit, space_used, space_reclaimable space_rec,

2 number_of_files file_num

3 FROM v$recovery_file_dest;

NAME SPACE_LIMIT SPACE_USED SPACE_REC FILE_NUM

----------------------------------------------------------------------------

/u01/app/oracle/flash_recovery_area 2147483648 1106849280 602410496 30

SQL>

在一些 10g 的动态视图里 (V$CONTROLFILE , V$LOGFILE , V$ARCHIVED_LOG ,

V$DATAFILE_COPY等)的新的列 IS_RECOVERY_DEST_FILE ,指明相关的文件是否在恢复区内。

SQL> SELECT recid, blocks, is_recovery_dest_file

2 FROM v$archived_log

3 WHERE recid < 5;

Page 69: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net 2005 年 1 月 1 期 总第 3 期

- 65 -

RECID BLOCKS IS_RECOVERY_DEST_FILE

---------- ---------- ----------------------------------------

1 20072 YES

2 19566 YES

3 19566 YES

4 19566 YES

SQL>

1.5. 闪回恢复区中文件的保持策略

持久文件从不会被删除。

通过 RMAN 配置策略过期的文件会被删除。

已经拷贝到磁带上的临时性文件会被删除。

在 Data Guard 环境中,当已归档的重作日志文件可以从闪回恢复区中删除的时候,可以应用

归档的重作日志删除策略进行自动删除 (在恢复管理器中 CONFIGURE ARCHIVELOG

DELETION POLICY TO ......)

在闪回恢复区中的空间使用超过 85% 的时候,数据库将会向 alert 文件中写入告警信息。而

当超过 97%的时候将会写入严重告警信息。当闪回恢复区空间不够的时候,Oracle 将报告如下类

似的错误:

ORA-19809: limit exceeded for recovery files

ORA-19804: cannot reclaim 52428800 bytes disk space from 1258291200 limit

这个时候查询 dba_outstanding_alerts:

SQL> select reason,object_type,suggested_action from dba_outstanding_alerts;

REASON OBJECT_TYPE SUGGESTED_ACTION

------------------------------ --------------- ----------------------------------------

db_recovery_file_dest_size of RECOVERY AREA Add disk space and increase db_recovery_

1258291200 bytes is 88.20% use ile_dest_size, backup files to tertiary

d and has 148509184 remaining device, delete files from recovery area

bytes available. using RMAN, consider changing RMAN reten-

tion policy or consider changing RMAN a

rchivelog deletion policy.

1 rows selected.

SQL>

会给出相关的原因和建议的操作。

Page 70: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

1.6. 注意事项

自动化的东西总是给人不确定性。如果您在测试环境中启用了闪回恢复区,那么一定要注意

监控空间的使用。在生产数据库上使用(如果有这样的人的话),必须要把闪回恢复区放到单独的磁

盘上。

1.7. 结束语

本文介绍了闪回恢复区 -- Oracle 10g 的又一个华而不实的新功能 -- 的基本功能。在后续的

文档中我会结合 RMAN 的新特性展示闪回恢复区的其他方面。

1.8. 参考信息

Oracle Database Backup and Recovery Basics 10g Release 1 (10.1) Part Number B10735-01

在 http://tahiti.oracle.com 可以得到 新的 Oracle 参考文档。

2005 年 1 月 1 期 总第 3 期

- 66 -

Page 71: Csdn Emag(Oracle)第三期

《CSDN 社区电子杂志——MS-SQL Server 杂志》

http://emag.csdn.net

作者简介:

姓名:冯大辉

网名:Fenng

照片

暂缺

某美资公司 DBA,业务方向为电信增值服务,负责数据库相关技术。业余时间喜欢混

迹于各数据库相关的技术论坛。

曾先后就职于国内两家大型软件企业,熟悉电信行业业务。对数据仓库的构建流程理解较为

深刻。熟练掌握 ETL 工具。

现任 itpub 管理版版主,中国 Oracle 用户组(CNOUG)版主。

对 Oracle 数据库的管理与性能优化,以及 Oracle 与开源技术整合有一定研究,有一定的数据

库管理实践经验,长于数据库实施、诊断、优化。

曾经翻译、参与编辑技术图书若干。目前关注如何利用 ORACLE 数据库有效地构建企业应用。

对 Oracle tuning、troubleshooting 有一点研究。

个人主页:http://www.dbanotes.net

个人Blog:http://blog.csdn.net/Fenng

作品:

参与编辑《Oracle数据库DBA技术精粹》http://www.itpub.net/202219.html

参与翻译《Python 入门》 电力出版社

参与翻译《Web 安全实践》 人民邮电出版社

参与翻译《Oracle 数据库管理》 电力出版社,(可惜属名漏掉了,以后坚决不和电力出版社

合作)

书评:

《Oracle 数据库图书简评》《数据仓库图书简评》

2005 年 1 月 1 期 总第 3 期

- 67 -