数据库设计理论之软件

     数据库的设计在系统设计当中是一个非常重要的环节,目前很多开发商忽略了它的重要性,把数据库设计基本等同于创建业务所需要的所有对象,这样系统就存在很多隐患。对于数据库的设计,除了一些必要的对象创建之外,还有更多需要考虑在系统运行的整个生命周期中,按照实际的情况及以后可能发生的变化做一些前瞻性的设计,以满足系统生命周期里的各方面需求,避免发生大的修改或升级。

    前期的数据库设计一定要弄清楚数据库的类型,一般说来,把业务分两类,在线事务处理系统(OLTP)和在线分析系统(OLAP)或者DSS(决策支持系统),这两类系统在数据库的设计上是大不相同的,甚至有些地方的设计是貌似相悖的。比如OLTP系统强调数据库的内存效率,强调内存各种指标的命中率,强调绑定变量,强调并发操作;而OLAP系统则强调数据分析,强调SQL执行时长,强调磁盘I/O,强调分区等。因为这些区别,在数据库设计的阶段,弄清楚数据库类型是至关重要的,只有在这个前提下,才能够讨论数据库的具体设计,否则一切都是盲目的空谈。

    1.OLTP数据库

     OLAP和OLTP是两类完全不同的系统,对数据库的要求也不同。一般来说,OLTP(在线事务处理系统)的用户并发数都很多,但他们只对数据库做很小的操作,数据库侧重于对用户操作的快速响应,这是对数据库最重要的性能要求。对OLTP系统来说,数据库的内存设计很重要,如果数据可以在内存中处理,那么数据库的性能无疑会提高很多。有些对处理速度要求很高的系统,已经采用了一些内存数据库,比如oracle的times ten。

     内存的设计通常是通过调整Oracle和内存相关的初始化参数来实现的,比较重要的几个是内存相关的参数,包括SGA的大小(Date Buffer,Shared Pool)、PGA大小(排序区,Hash区等)等,这些参数在一个OLTP系统里显得至关重要,OLTP系统是一个数据块变化非常频繁、SQL语句提交非常频繁的系统。对于数据块来说,应尽可能让数据块保存在内存当中,对于SQL来说,尽可能使用变量绑定技术来达到SQL的重用,减少物理I/O和重复的SQL解析,能极大的改善数据库的性能。

     关于一些初始化参数的设定的问题,没有一个确定的标准,这和每个数据库上运行的业务直接相关,能够确定这些参数值的唯一方法就是测试,先给这些参数设定一个经验值,然后通过搭建测试环境对数据库进行测试,通过一些性能报告作为依据,不断地调整这些参数值,以达到最佳性能。

    除了内存、没有绑定变量的SQL会对OLTP数据库造成极大的性能影响之外,还有一些因素也会导致数据库的性能下降,比如热块(hot block)的问题,当一个块被多个用户同时读取的时候,oracle 为了维护数据的一致性,需要使用一种称为Latch的东西来串行化用户的操作。当一个用户获得这个Latch后,其他的用户就只能被迫等待。获取这个数据块的用户越多,等待就越明显,就造成了这种热块问题。这种热块可能是数据块,也可能是回滚段块。对于数据块来讲,通常是数据块上的数据分布不均匀导致,如果是索引的数据块,可以考虑创建反向索引来达到重新分布数据的目的,对于回滚段数据块,可以适当多增加几个回滚段来避免这种争用。

     2.OLAP数据库

     OLAP数据库在内存上可优化的余地很小,用户对OLAP系统性能的期望远远没有对OLTP性能的期望那么高。内存的优化,对OLAP影响很小,因为对于海量的数据,全部在内存中操作是很难的,也是没有必要的,由于这些数据块很少重用,缓存起来也没有意义,倒是物理I/O相当大,这种系统的瓶颈往往是在磁盘I/O上面。

     对于OLAP系统,SQL的优化非常重要,例如:如果一张表中只有几千条数据,无论执行全表扫描或是使用索引,差别都很小,几乎感觉不出来,但是当数据量是几亿甚至几十亿的时候,全表扫描、索引可能导致极大的性能差异,因此此时的SQL优化显得十分重要。

     分区技术在OLAP数据库中很重要,这种重要主要体现在数据管理上,比如数据加载,可以通过分区交换的方式实现(具体过程可见另一篇文章),备份可以通过备份分区表空间实现,删除数据可以通过分区进行删除,分区一般情况下性能都是优于非分区的,但是不能一概而论,下面讨论几种使用分区的情况:

     1)当查询的范围正好落在某个分区的时候

         这时候分区的效率自然是高于没有分区的,因为SQL在有分区的表上只扫过一个分区的数据,而对于没有分区的需要进行全表扫描。

     2)当查询的范围跨越几个分区时

         这时候的分区可能并不绝对是最优的,此时的分区效率不一定比非分区的效率高,甚至可能效率低于非分区的效率。例如:一张分区表和一张非分区表,两表的结构和数据完全一样,不同点在于一个分区一个未分区,两表都在同一列创建索引,使用同一条SQL语句(如select  /* +index ffs (t t ind)*/ count(*)from table)让CBO使用FAST INDEX FULL SCAN的方式扫描索引,此时在分区表的执行效率明显低于非分区表的效率,这是因为分区索引在做FFS(FAST INDEX FULL SCAN)的时候只能够在本地索引上进行,如果涉及其他的分区,还需要按照访问索引的方式去访问其他索引(如先找到其他分区索引的根数据块,再找到最左边的叶块,然后执行FFS操作),这样,查询跨过的分区越多,这种额外的代价就越大,而在这种情况下,非分区表使用全局索引只需要定位到一个叶块,然后执行一次FFS就能够扫过所有的索引叶块,这样性能就会好于分区索引。

      在OLAP环境中,分区主要的功能是方便管理,它并不能绝对保证查询性能的提高,有时候分区会带来性能上的提高,有时候甚至会降低。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值