《Oracle9i&10g编程艺术》读后感

《Oracle9i&10g编程艺术--深入数据库体系结构》即为《Expert one to one oracle》的升级版本,不过升级后可能会变为三本书,这本书强调的是深入数据库体系结构的讲解,本书的作者Thomas Kyte(即Tom)无疑是Oracle界最为知名的人物,而这本书可以说基本是专为开发人员而写的,因为我个人觉得书中讲的东西大部分DBA都是懂的,但对于开发人员来讲估计大部分都不懂,Thomas Kyte抓住了怎么给开发人员讲才能讲清的方法,对于书中的每项内容Thomas会讲解什么时候这么做、为什么要这么做、什么时候不能这么做以及为什么不这么做,要说服开发人员,很多时候除了告诉怎么做以外,还必须得告诉为什么要这么做,否则很难说服,而Tom在书中则很好的做到了这点,Tom会告诉你Oracle是怎么去实现的,所以你要这么做或者不能这么做,这本书除了让我学习到了更多的Oracle知识外,还让我更加明白了数据库在系统中的重要性以及充分发挥数据库的功能是多么重要的一件事,还有一个附加的好处就是让我们可以窥探到部分Oracle的设计,对于自己实现应用系统也是会找到一些可参考的地方,这本书写的实在是太好了,强烈推荐给开发人员看。
按照书中所讲的东西,个人觉得开发人员对于数据库应了解如下内容:
1、读一致性
      Oracle在读数据时采用的是保证数据一致的方法,也就是说查询出的所有数据均为发起查询时的数据,Oracle这么做的主要原因是为了避免读阻塞写,这么设计的目的是为了支持高并发,而其他的数据库有些不是这么做的,就像在sql server中需要明确的在查询语句中加上with nolock才会避免读阻塞写。
      以一个这样的例子来说明下oracle的读一致性:
      假设现在有一张账户表,来看看同时进行的一个转账动作和查询动作:
      查询动作:查询所有账户的money的总数;
      转账动作:从A账户转400到B账户。
      查询到A账户的money为:600
                                                                    更新A账户的钱为200
      查询到C账户的money为:100
                                                                    更新B账户的钱为500+400
                                                                    提交。
      此时查询才查询到B账户,那么
      这个时候查询到的B账户的money到底是500还是900呢?
      按照oracle的读一致性非常明显这个时候查询到的B账户的money会是500,这就是读一致性的概念,在其他的读会阻塞写的数据库中确实不会出现这样的疑问(因为转账的动作得等到查询动作结束后才能执行),但那样的方式很大程度降低了数据库的可并发性,在后面的redo&undo中会讲讲oracle的这种读一致性是怎么实现的。                                    
2、锁机制
      Oracle主要有行级锁和表级锁,大多数情况下Oracle都只会出现行级锁,很少会出现表级锁,所以在oracle中出现死锁的现象还是非常少的,开发人员在设计系统时应尽量避免等待行锁的现象,也就是避免多人共同修改同一行,只要解决了这种现象,其实也就意味着Oracle支持高并发是完全没有任何问题的,关于锁定机制最容易出现的问题就是丢失更新这个问题了。     
3、丢失更新
      丢失更新的实际例子就是:A、B均已读出数据并开始进行修改,当A提交数据后,B再提交就出现了B覆盖掉A修改的内容的情况。
      丢失更新的解决方法通常都是采用版本列、时间戳列这样的方法来实现,不过只有在多并发共同修改同一行的系统中才需要慎重的考虑这个问题。
4、索引
      索引无疑是数据库中非常重要的机制,尽管这个更多的可以交给DBA来进行调优设计,不过开发人员还是要大概的有所了解,至少要知道索引有哪几种(B树索引、函数索引、bitmap索引、聚簇索引、对部分行建索引等),什么场合下适合用哪种索引。
      Tom在书中强调了很多次,没有"fast=true"这种银弹式的提速开关,只能是根据实际情况来分析,也就是说不是说只要加了索引性能就会提升的,索引主要是为了查询大表中的少量数据的,Tom在书中讲解了索引的查找数据的方法(索引中映射到的为rowid,在查找到索引后查找数据时oracle是根据每个rowid去表存储的块中读取的),按照其查找数据的方法完全有可能出现查找索引比全表扫描还慢的现象,举例来说明下:
      假设一张表有100,000行记录,现在我们要读取其中的20,000行,假设每行的大小约为80字节,数据库的块大小为8k,在这种情况下表中的记录大约会产生1000个块,那么这个时候使用索引读取的话就要做20,000次Table access by rowid,而整个表都只有1000个块,也就是说即使全表扫描也只需要做1000次的动作,但现在竟然要做20,000次,自然慢多了。
       索引还和物理组织呀、聚簇因子呀等等都有关系。
5、Oracle文件
      Oracle文件主要有服务器参数文件、数据文件、控制文件、密码文件、在线日志文件等等,这些开发人员也应该大概的了解下。
6、事务
      事务对于并发系统而言也是非常重要的机制,所以开发人员要对这块比较了解,Oracle建议是否提交事务要根据数据逻辑的完整性来决定,而不是说越快提交越好,oracle会保证语句级的原子性(例如执行语句时的触发器、存储过程都会控制在统一的事务范围),同时oracle还支持像分布式事务、自治事务等。
      对于开发人员而言,要把握的就是什么时候提交事务,应该注意的就是事务应该控制在自己手里来决定什么时候提交,像对于使用jdbc的java开发人员而言,要注意,jdbc默认是执行一条就提交一条的。
7、redo&undo
      redo和undo绝对是oracle中非常重要的两个东西,redo用来记录所有的操作,以便oracle在遇到断电等等意外的情况下也可准确的恢复实例和之前的动作,而undo则是用来记录所有的操作的逆动作,以支持像回滚、读一致性这样的操作,从这里我们就可以知道当undo设置的太小或查询执行时间太长的时候,就可能会出现snapshoot too old这种错误。
      从这个章节中还得学会评估redo、undo产生的大小,另外就是遵循Tom所说的生产环境一定要是archivelog模式的,否则数据丢了也就只能哭了。
8、数据库表
      要了解下oracle中的堆组织表、索引组织表、聚簇索引表等几种表的形式。
9、数据类型
      要了解下oracle中的varchar2、number、lob这些类型。
10、表和索引分区
        应该了解oracle支持哪几种表和索引分区,什么时候用,怎么去用,开发人员要了解的原因是其实表和索引分区要高效的使用是得根据业务分析来形成的,随意的表和索引分区很有可能会造成性能下降。
这些方面应该是开发人员至少应该了解的,在数据库方面的开发上开发人员最应该关注的就是基本的SQL编写优化法则、并发和锁的控制机制、事务使用机制,因为对于开发而言,会带来挑战的就是在并发的情况下,设计人员则应根据数据库的并发实现机制来尽量减少锁等待的现象,其他的调优工作可以由DBA来完成,但开发人员也应该提供辅助,像表分区的做法等等。
根据Tom在书中描述的数据库的锁机制、并发机制等等,可以看出每种数据库在实现这些方面都是不一样的,所以要做到数据库独立性其实是不可能的,就像Tom说的,付出了那么高的价格买下了数据库,难道你就只是把它当成一个简单的文件系统而使用,而不去充分使用/发挥它的功能,因为很多时候你付出了巨大努力实现的东西对于数据库而言也许就只是简单的一句话而已,所以从此我对数据库独立性也say NO!,即使是使用Hibernate这种相对来讲可以使数据库独立的东西,几个简单的例子来说明在数据库切换时要做的工作:
1、is null和字段=null
      在Oracle和SQL Server中采用的均为is null,而在有些数据库里采用的则是字段=null的方式来获取。
2、函数
      例如sql server的dateadd、identity这些,到了oracle中自然要切换。
3、锁机制
      这个是最麻烦的,就像你在oracle中可以使用select而不必担心读会阻塞写,但在sql server中就得带上with nolock。
4、事务
      虽然表面看起来事务类型都是一样的,但各种数据库实现事务机制方法的不同决定了在切换的时候还得考虑事务使用上是不是要修改。
对于1、2两点你可以尽量的避免,3、4两点则是无法避免的,所以在是使用数据库上不用过多的去考虑数据库独立性的实现,当然,这并不意味着hibernate这些ORM的东西就不需要了,:),我倒是一直非常希望有哪个ORM工具能透明实现数据库的切换,包括上面所说的那些机制的自动转换,但这相对而言几乎是不可能的,因为要对每种数据库都精通才能做得到。

posted on 2007-08-10 12:20 BlueDavy 阅读(4318) 评论(3)  编辑  收藏 所属分类: 业界随想

评论

# re: 《Oracle9i&10g编程艺术》读后感 2007-08-10 18:08 mingj

1、is null和字段=null
这种在oracle和sql server中非常明显,前者为oracle的,后者为sql server的。


sql server 是 is null  回复  更多评论   

# re: 《Oracle9i&10g编程艺术》读后感 2007-08-11 09:41 BlueDavy

@mingj
多谢提醒。
看来是其他的数据库才支持字段=null的这种方式,oracle和sql server均为采用is null的方式。
  回复  更多评论   

# re: 《Oracle9i&10g编程艺术》读后感 2010-09-28 23:25 youlong699

哈哈,您的读后感很棒,“Thomas Kyte抓住了怎么给开发人员讲才能讲清的方法,对于书中的每项内容Thomas会讲解什么时候这么做、为什么要这么做、什么时候不能这么做以及为什么不这么做,要说服开发人员,很多时候除了告诉怎么做以外,还必须得告诉为什么要这么做,否则很难说服”。
您的分布式JAVA什么时候也打磨到这个水平啊~~  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 

公告

 









feedsky
抓虾
google reader
鲜果

导航

<2007年8月>
2930311234
567891011
12131415161718
19202122232425
2627282930311
2345678

统计

随笔分类

随笔档案

文章档案

Blogger's

搜索

最新评论

阅读排行榜

评论排行榜