[转帖]几条Oracle数据库开发的原则归纳(上)_MySQL, Oracle及数据库讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  MySQL, Oracle及数据库讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 3594 | 回复: 0   主题: [转帖]几条Oracle数据库开发的原则归纳(上)        下一篇 
derek
注册用户
等级:中校
经验:1550
发帖:209
精华:0
注册:2011-7-21
状态:离线
发送短消息息给derek 加好友    发送短消息息给derek 发消息
发表于: IP:您无权察看 2011-9-2 15:13:57 | [全部帖] [楼主帖] 楼主

目前绝大多数的MIS系统,都是基于对数据库的交互式操作,开发人员大部分的工作都是直接或者间接与数据库打交道。作为开发人员,正确的使用数据库技术,不但可以提高数据库相关开发的效率,而且可以有效的减少投产运维阶段的工作量。本篇从笔者的实际工作体会入手,简单介绍几个Oracle相关开发原则

1、“Never Treate Database Like A blackbox”

“绝不要将数据库视为一个黑盒”是Oracle大师Thomas Kyte给所��数据库开发人员的一句忠告。作为一个开发人员,无论使用何种类型的数据库,都要遵守这个基本规则。

现实中,将数据库作为Blackbox的开发人员是很多的。很多开发人员将数据库就是作为一个数据留存的载体,通过标准化的SQL进行操作,不去对具体使用的数据库进行了解。

这个问题的原因是很多的。其中一个重要原因就是在开发人员的观念中,SQL语句都是通用标准的。只要输入相同描述SQL,数据库都能返回相同的结果。开发人员似乎不用去关注数据库本身。

这种想法其实是错误的。目前我们使用最多的关系型数据库系统,都是建立在关系数据库模型的基础之上。同时,行业中也有专门的SQL系列标准。流行的开源或者商用数据库都宣称支持标准SQL和关系模型。但是实际上,各个数据库产品在实现标准的过程中是有所取舍、有所个性化的。

比如在Oracle中,一个重要的特性就是“查询select不会被修改阻塞”,也就是任何时候都可以对数据表进行select,不在乎查询数据是否正在被修改。这个特性大大提升了Oracle数据库的并发能力。但是并不是每种RDBMS都是如此,如SQL Server或者SQLite等DBMS,就存在select被其他DML操作阻塞的情况。

另一个例子是关于锁定范围。如果要对一条记录进行修改,Oracle数据库只会对该数据行进行锁定(行锁机制)。而其他一些数据库进行锁定的范围就会有差异。比如,SQL Server就是基于对页page的锁定,而另一些DBMS甚至会对表级别进行锁定。

对这些数据库机制的了解,对我们进行开发的意义重大,可以帮助我们不犯根本性质的错误。比如,了解SQL Server中select会被DML操作阻塞,就要意识到SQL Server环境下事务Transaction是要及时的提交。

另一部分的机制了解就是SQL。SQL是一种描述性语言。同一个结果集合,使用不同的SQL描述,数据库都会生成不同的执行计划。不同的执行计划方式,意味着不同的效率。所以,书写一手“漂亮”的SQL是不容易的。需要开发人员了解优化器、SQL转换机制和执行计划。

所以,作为一个数据库相关的开发人员不是一件容易的事情。会写几句SQL,用用预定义函数绝不是数据库开发的全部。了解你的项目所使用的数据库,知道自己在做什么,是一个数据库开发人员所具备的基本素质。

2、Be Responsible To Your SQL

对于一个初学者,SQL是一种描述性语言。你需要什么样子的数据,不管什么方法,只要能描述出来,理论上DBMS都可以返回正确的结果。但是,执行效率是有差异的。相同的结果集合,好SQL可能不到一秒钟就可以返回结果,坏SQL可能几个小时不能有结果。

我们经常在开发团队遇到的场景是这样的:开发人员书写了一个SQL,测试入一个很小数据集合,可以返回正确的结果。就直接提交测试投产了。投产之后,随着数据量的积累,原有SQL执行性能下降严重,最后很可能都执行不出结果。此时,开发团队已经解散,修改源代码的可能性很少,于是变成了DBA的噩梦。

这样的场景,本质问题就出现在开发阶段开发人员对SQL的责任缺失。开发人员应该对自己书写的SQL负责,在保证结果正确的前提下,不断优化SQL的书写。这样做的目的就是让SQL在生产环境下也可以正确的执行。

做到SQL负责,听起来是一个很抽象的概念。实际中,开发人员只需要从两个方面入手:

首先,看看自己书写SQL的执行计划。查看执行计划,评估执行计划不是DBA的专利。每个开发人员应该具有看懂SQL执行计划,辨别常见Join的方式操作,识别好坏的能力。能看清SQL的缺点,才有改造的动力。

第二就是时刻注意自己的SQL在做什么?听起来这条规则很有问题,SQL几种操作,我们都能够书写出来,难道还不知道自己的SQL在做什么吗?这里笔者要强调的是数据操作范围。修改一条记录的SQL和修改一千万条记录的SQL书写起来,形式可以是一样的。但是,这样的SQL执行时候的效果是天差地别。一次性修改一千万记录的SQL也许一瞬间就让数据库处在崩溃的边缘。所以,一条SQL语句写出来,开发人员一定要明白这个SQL处理的范畴是多大?一百条还是一百万条?如果可能出现百万条的可能,就一定要预先处理,设置一次操作的范围上限。避免由于一次性的操作带来的风险。

3、Index or Not Index

这里说说Index索引这个老话题。在Oracle环境下,最常见的索引是B+平衡树索引。普通B树索引具有几个特征:

ü始终维持平衡状态。从根节点到达所有叶子节点的距离相同;

ü树节点包括三类���一个根节点、若干分支节点和若干的叶子节点;

ü叶子节点之间,通过双向链表结构加以连接。可以方便的在叶子节点层进行导航;

ü叶子节点上,保存着索引列键值和对应的行rowid;

ü索引是一个单独的段结构segment,一个enable的索引是和数据表索引列实时对应;

在开发SQL的执行计划中,我们经常可以看到两种路径方式:Full Table Scan和Index Range Scan。这是数据表访问的两个代表性的方式。

üFull Table Scan(全表扫描):此种方式是对数据表数据的全部检索。首先,Oracle会从对象的数据字典中,获取到数据段头块的信息(文件号、块号)。找到头块之后,从头块信息中,获取到该数据表所有相关extents的信息和位置。之后依据extents的分配依次检索数据块。直到检索到HWM(高水位线)下。FTS方式有个特点:堆表结构下,会检索到所有分配给的数据块(无论是否有数据内容)。所以,FTS操作的效率是随着数据表的膨胀而变化的;

üIndex Range Scan(索引范围扫描):对数据表的检索,并不直接入手数据表。而是从索引入手,通过读少量的索引块,获取定位到符合条件的叶子节点rowid列表。之后,直接借助rowid列表,就可以定位到符合条件的数据行。这种方式的特点是查询性能不随着数据表的胀大而发生变化。

通常情况下,索引路径是我们追求的优化方向。在CBO时代,索引路径因其少量的IO块读取成本通常小于FTS方式的。但是,并不是意味着所有SQL都会优化为索引路径。索引是有成本的,添加索引是会给select带来很多好处。但是,Oracle要维护数据索引列与索引树的同步结构。这也就意味着索引会带来DML操作的性能低下。所以,索引是一种有成本的优化手段,要统筹规划。




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论