开发Oracle数据库应用的正确和不正确的方法

看书的目的在于深入理解Oracle到底能做什么,尽量多的学习Oracle的功能,避免重复发明轮子。提高工作效率的一个原则就是做正确的事情,如果花费几个月的心血才研究实现出来的东西,却能够通过简单的配置Oracle就能实现,那么未免效率太过低下了。



1. 基于数据库应用开发的基本原则在于, 如果功能能够在数据库中实现,那么就优先在数据库中实现。尽量用一条SQL语句来完成工作,如果实在是不能用一条SQL实现,那么考虑用PLSQL来实现。 SQL所引起的性能问题,能够非常方便地诊断并且修改过来,而如果是把数据库当成黑盒而引发的性能问题,则非常难以修正。


2. 位图索引应该只用在只读的数据表中,并且是low cardinality的列,如果同时存在并发地写,那么位图索引将不可避免地同时锁定很多行记录,接近于表锁。


3. 如果有些表的数据会经常性地按照日期添加和删除,像队列一样,那么最好是使用Oracle的Advanced Queue,这是优化好的队列表,对于此种应用,比普通表要性能好。


4. 如果不使用绑定变量,会耗费资源进行硬解析。但这个仍然不是主要问题所在,硬解析会大量使用一种轻量级的锁latch,而latch是访问并发内存共享数据的控制设备, 所以在不使用绑定变量的情况下,latch被占用,导致很多其他程序等待latch,从而使整个系统变慢,让系统本应该拥有的性能下降一个数量级。


绑定变量还有一个作用就是预防SQL注入攻击,通过在可输入的字符串,日期等,加入SQL语句,用以查看表,查看用户信息表,最后获得密码。 只要有1个这样的可输入SQL的非绑定变量,那么所有的信息安全都将白费。

cursor_sharing=force 通过配置这个变量,可以默认实现所有的变量自动绑定。 所有的where条件中的value都采用绑定变量的方式重写。 副作用在于可能把一些能够影响到优化器的value,也用作了绑定变量,让优化器做出错误的决定。 比如1000行的表,value<900, 返回900行数据,那么这个时候采用全表扫描会更好,但是优化器绑定变量后,可能会采用索引查询,效率变得比较差。


5. Oracle的锁为行锁,甚至可以说是列锁, 只锁定一行的几列。select for update on column1。 实现的方式为,在数据块上标记被锁定的行列。当有并发访问该数据块的时候,就能够侦测到该数据是否被锁定。


6. Oracle的读操作,不会被写操作阻塞。当需要读取一起数据的时候,如果发现某个数据的版本(时间戳),和开始读的时候的时间戳不一致,那么这个读操作将会从undo的日志中找到该数据原来的版本,然后返回。其并不会等待写操作完成。

Oracle的并发模型为 读一致read-consist,多版本multi-version。

举例:

一个session打开基于某个表的游标
另一个session删除该表的数据
此时第一个session仍然能够返回该表的数据

非阻塞读的副作用在于,需要手工控制丢失更新的情况。多并发同时修改同一行,最先提交的线程修改可能会被之后的线程覆盖。这里需要进行手工控制。采用悲观锁select for update,或者采用乐观锁比较hash值来避免。


7. 关于11g的闪回的特性,能够快速地将数据库恢复到某一点。理论依据是,flashback采用磁盘进行备份数据和日志,而不是磁带。这样就能够很好的访问备份的内容。DBA能够利用这些备份内容手工恢复数据库,而Oracle则能够利用这些备份,更加便捷地自动恢复数据。 之前没有这个功能是因为大量的备份内容存储在廉价的磁带上,因磁带是顺序读写而无法实现。现在磁盘非常廉价,所以才能够实现这个功能。


8. Oracle的B-tree索引不会为null值添加索引,column=null是不对的,应该采用coloum is null


9. Oracle中不推荐在存储过程中DDL创建临时表,使用完成后就Drop。 而是预先创建好Global Temperary Table,每个session在里面存的数据只有这个session才能访问,session完成后,表中数据也随之消失。


10. Oracle的默认隔离级别是Read Comitted, 支持非重复读和幻读的特性。 在一个事务中能够读到事务开始后,已经被其他事务更新提交的行的数据, 以及能够读到表中其他事务新插入的行。

Serializable于Read Commited的区别在于,遇到多个事务对同一数据进行写操作,前者会抛出异常, 而后者会进行等待。仅此而已, 而不是一直以来所认为的是所有操作串行完成。


11. 内联视图和标量子查询 是oracle非常有用的特性, 前者是在结果集进行查询, 后者是每个column运行一个查询。  特别是标量子查询,可读性非常好,同时可以减少join的层次.


12. 通过配置文件,可以确保访问数据库的用户在DB中只有一个session,而不是采用一些"有创意的代码"来实现。


13. 追求数据库的独立性可能不是一个正确的决定,特别是对应于复杂的应用系统。Hibernate,EJB等用作表现层的应用尚可,如果需要进行复杂的业务运算,那么效率和性能则不敢恭维。


14. Exadata, 基于Oracle的存储区网络设备。通过移动数据文件,可以让响应时间成数量级的缩短。

猜你喜欢

转载自zzhonghe.iteye.com/blog/1689549