·明确需要编写的触发器及过程;
, r) f# e8 z% r3 ]8 S
3 L ]3 O, o9 U; B& _2 M& N+ q# | ·为数据库对象选择备份和恢复策略。
6 n R$ A3 {* L! W1 z6 v/ x# S# G+ m& V7 p! b- Z5 k
在数据库设计阶段,有时未必能完全确定合适的数据库对象的特征,应用设计和开发中还可能发现不合适的地方,需要回过头来进行调整和修改。但设计阶段的工作越细致,出现问题的可能性就越小,工作的效率就越高。, K" E* R" t: O7 K
4 s3 M' ~, w& Y: x8 _) e
创建数据库对象时,要根据数据库对象的特点,结合存储设备的大小、数量及速度等,对数据库对象分类进行存储,最大限度地消除或减少资源竞争。在数据库对象创建时主要应遵循以下原则:
# f0 k7 g, z" ^) c, b
6 ?4 p5 ^" t" S: y. X! r. G8 o ·应用数据应放在单独的表空间,不要将应用数据放在系统表空间,为防止无意的使用系统表空间,将应用用户的系统表空间限额设为0。
9 l& C* M8 a& ~4 g. H8 d
r; ?2 a! h: K8 U; z ·索引和表应放在位于不同硬盘上的不同的表空间,这样会提高数据库操作的速度。7 [6 b$ k# Y1 o
& @2 l9 T/ d/ k- ` o7 T% R8 C. D9 D/ ~
·需要同时被访问的表要分开存放,利于并发访问的实施。
; C) m; M$ }* l, i j& o( b1 |% g# H: g( s
·如果磁盘数量有限,可把不常联合访问的表放在相同的磁盘上。% F! I5 G7 j, Y9 y1 P
$ o. f. X9 J. S' D, e- ]5 P ·预分配的原则。创建数据库对象(表空间、回滚段、表、索引等)时,根据对象的情况设置合适的storage参数非常重要。创建对象设计时,对对象的容量和预期的增长有一个估计,这样才能确定存储参数的大小。一般来说,应预先给表和索引等数据库对象分配足够的空间,数据库段不要太多地做动态扩展,因为会影响数据库性能。一个段(segment)由一个区(extent)构成是最理想的,initial 参数可以稍大一点,如果可能,可设为最大容量的大小,initial必须是db_block_size的整数倍;next参数的设置比较灵活,根据应用进行相应的设置,但也必须是db_block_size的整数倍;为了减少数据库碎片的产生,pctincrease参数应该尽量设为0;更新操作比较少的段,pctfree要设置得小一点,更新操作很多的段要设置得大一些;inittrans和freelists的值要相等,大小与并发事务数相关。
; {9 b( T$ I4 w4 Z
- k2 ^) ~! A, D9 G* M, H( k! U2 B ·分而治之的原则。大的数据库表和索引可考虑进行分区存放,不同的分区可位于不同的磁盘上,更好地均衡I/O。Oracle可以只对表的某些分区进行查询,这样会提高查询的速度;可对分区进行数据的删除、装载,还可以移动分区,对表的管理和控制具有更大的灵活性;可以有更多的策略选择,更好地执行备份和恢复操作。注意,对某些分区进行操作后,在Oracle8i下必须重建全局索引。
, ~4 N. Y& s l! T! N |3 a$ ]6 p7 ?* W1 g
·大小和增长趋势类似的表最好放在相同的表空间,可以有效控制硬盘碎片的产生,提高空闲块的可重用性。: K5 z8 z' t/ l! i/ s0 z$ K
: f7 G9 r$ k* f ·相同备份和恢复策略的表最好放在同一个表空间,这样有助于备份和恢复工作的完成。
3 s( O4 i( y$ ?( _& i
5 e2 p- h. \1 r8 z: k8 F ·对响应时间要求苛刻的应用所访问的对象放在速度快的磁盘上。+ b6 G. |2 Y8 q3 C, a$ u) d' z- z
数据库应用系统的设计与开发
; v. \( {5 o+ C; [4 Z+ l7 v7 g5 l9 x: q2 o. K. Z
1、应用设计3 ]1 N: W2 d0 d- e+ i3 Y
0 @8 \ |& k4 W: }! I
不论使用何种工具或语言来开发应用程序,都需要进行应用的全面设计。应用设计包括: . I7 ?- T+ S/ y1 f$ \: i+ t3 \ E* w3 I
$ R l" L! c7 W( K. I8 z. ~
首先,分析应用要完成的功能,确定应用类型,是OLTP(联机事务处理)系统、DSS(决策支持)系统还是批处理系统;
, @# U7 ]7 K* D) D7 T. o; B( [ \* J+ Q7 j% @# p+ s c
其次,了解应用在何时由谁使用、应用访问的数据、应用程序用到的组件、应用被要求的响应时间等,在设计前,必须对这些问题尽量进行解答,这对应用设计特别是大规模的应用设计非常重要;
9 w: O3 \% P% @' ]: [7 B5 E3 A& D
第三,根据上面的资料,确定应用的体系结构,是采用client/server两层架构的方式,还是采用browser/server多层架构的方式实现一个开放的分布式应用系统,如何对应用服务器进行选择与配置;
' L8 i4 {; S- T& D
b6 e: R. Y% _' \! w0 @* } 第四,将应用按功能划分为一个或多个应用程序,明确应用程序的具体功能、类型、组成,使用时间及高峰时间、事务的流量、用户组成、访问的数据库对象等,确定应用程序间的关联和互操作特性,对各个应用程序的执行时间合理地进行安排; . a: h n. `) R+ O' d
+ S5 ~7 K" n; ^. {% d% U 第五,对应用程序进行模块化设计,选择实现应用的数据库组件和开发语言及工具。
- k6 ]. k; [8 s" F p' j+ i0 e" \* q4 y7 ^: W
2、应用开发
3 Z# y; g( H7 l
0 [6 Z- {6 D) R! j. J1 f- Q 在应用开发阶段,根据应用的不同,实现的方法和步骤会有很大的差异。这里只讨论以下在应用开发中需要重点注意的几个问题。4 r$ _ l/ w" M, V( w( x# Q6 Q
: A$ z( g( X s2 ?' o% r+ T5 j
1) 在开发会话关键型应用程序时,尽可能使用Pro*C/C++或OCI。在编写后备实例和数据库失败恢复等需要进行数据库重新连接的代码时,用Pro*C/C++ 或OCI比用PL/SQL要容易实现,在Oracle8/8i中,OCI可以实现透明应用程序失败恢复(TAF)。编写数据库操作繁重的应用程序,使用OCI,OCI程序对数据库的访问是通过调用OCI库函数实现的,能够直接到达系统内核,比Pro*C/C++速度更快。3 G$ W% r+ i T
% {, G% H4 z& e( y) R" s2 ~# M
2) 在开发会话关键型应用程序时,尽量实现失败检查和恢复能力,如指定后备数据库或实例、终止出错客户进程等。5 X6 `* S- F, t* J, n$ {
+ [- S' I+ }- L; B9 Y4 u
3) 编写代码时,要考虑应用程序的可维护性,尽量将应用程序独立于数据库的变化。可使用视图、相对变量类型定义(%TYPE)、记录型变量定义(%ROWTYPE),采用表驱动的应用程序设计模式。8 g# O, a9 ] i0 S% t
5 ~1 o: e. z- e$ D" B 4) 进行充分的单元测试和模块测试,为应用集成打下坚实的基础。
: Q4 G# r6 R: U! J- ^! Y" F9 z5 W
5) 对关键表操作的应用程序实现要特别当心,必要的话,在应用中对关键表先做备份,应用成功执行后再删除备份表。
! q- S3 c9 y# R1 e8 \ _9 a7 }7 K$ \: {: d3 w4 f. j( u7 P. L: l
6) 编码结束后,应对代码进行优化。前面提到过,代码优化在数据库应用中非常重要,很高比例的性能问题与编码拙劣的应用程序有关。. t; D3 E1 j; l& g& `3 j
/ x; W% o7 K7 i: f9 m7 U v: } 7) 定期对应用操作的数据库对象增长的情况进行监控,避免因空间不足引起的应用程序的失败。2 ^5 w2 Q' [* N2 M7 H# Y# F
2 Y7 ^- R3 |+ B/ R
8) 对应用的数据定时进行整理。有些应用中,存放在数据库表中的数据只要求保存一段时间,就需要定时对数据进行删除。如果手工进行删除操作,工作量很大,可以用Oracle提供的作业来完成, unix系统下可用cron进程来实现。笔者在工作中经常使用cron来做数据的定9 [/ ^) \4 u2 i3 j1 k
时删除,根据应用要求,编制Pro*C/C++程序,编写Shell脚本调用应用程序,将Shell脚本提交给cron进程。! ^0 b) e' k/ V3 c% \# E' _7 q
" }7 o/ t4 ~3 V' }
注意:在Shell脚本中必须设置相应的Oracle环境变量,如ORACLE_BASE、Oracle_HOME、NLS_LANG、LD_LIBRARY_PATH、PATH等,用户环境文件中的定义是无效的。
6 J: S8 v8 x% m P# k- n b4 ~" J
* K( W) d$ Q% p! n 9)对于大量删除操作的应用程序,如果表是分区存放的,可对数据分区执行截断(truncate)操作,截断操作执行速度快并且不会产生碎片,但截断后可能需要进行重建索引的工作。对大量的数据做删除(delete)操作,会引起数据库回滚段的急剧增长,建议根据删除
( K& M5 s' v! {) ~2 v0 L数据量为这类应用创建特殊的专用回滚段,为专用回滚段指定合适的storage参数。平常,专用回滚段可以是离线的(offline),在事物开始前,使专用回滚段在线(online),指定事物使用专用回滚段,事物结束后再使专用回滚段离线,笔者使用的部分代码 (Pro*C/C++) 如下所示。 3 i1 s7 C+ C3 c+ \( J
- }; V- P, ?2 T N; o.. 9 D/ ?% {! `' f5 _6 R
EXEC SQL WHENEVER SQLERROR goto Error; , M3 l9 B" l. b: M* ~' m
EXEC SQL CONNECT :uid;
2 g% s1 L8 P9 z..
]& h# O$ z9 o2 h( N9 y( w; d. QEXEC SQL ALTER ROLLBACK SEGMENT RBS_SPEC ONLINE;
) J5 Y8 g# s, A% C6 g8 WEXEC SQL SET TRANSACTION USE ROLLBACK SEGMENT RBS_SPEC;
. j, b$ J. k0 M..
. L; r; [9 t1 x8 t( a( ~EXEC SQL DELETE FROM .. WHERE ..;
" A2 R: d. r) i: ZEXEC SQL ALTER ROLLBACK SEGMENT RBS_SPEC OFFLINE; ) A+ @1 X# ~. f' [
.. |