日期:2014-05-16  浏览次数:20521 次

数据库项目经验分享
 一、数据库的设计

  当然首先要懂得数据库的基本理论。在设计E-R模型之前,首先要进行深入的需求分析,需求了解的越透彻,数据模型才能越稳定。

  在E-R模型向关系模型转换时,既要深入理解规范化理论与转换原则,也要知道,并不是范式越高越好,为了加快查询速度可以适度加入冗余。非BCNF范式的关系虽然理论上可能会发生更新异常与冗余,但如果实际中该关系并不进行更新或更新的频度很小,其造成的负面影响也将十分有限。软件与数据库设计也是一门平衡的技术,范式究竟要达到什么程度,也要看具体的需求及平衡各方面的利弊,而没有一定之规。

  在物理设计方面,要考虑索引列及索引方法的选择,将可能同时频繁访问的数据在物理位置上分开,预计一定时期内数据的增长情况并预留出空间。需要强调(因为有不少朋友并没有意识到)的是索引不是越多越好,增加索引要慎重、要有充分的理由,增加索引会增加DML(增、删、改)操作的开销、会消耗更多的空间、还可能使原先好的查询执行计划变坏。

  有关历史数据的保留、清理与转储问题,应尽早了解用户这方面的需求,并制订合理的方案,否则可能给日后数据库的维护带来麻烦;最好能跟建设数据仓库项目结合起来考虑。

  另外,一定要利用成熟的设计工具(如IBM Rational Rose、PowerDesigner等等),这些工具使你的设计更规范、清晰、易于维护,还能产生各种报表供不同层面的人员查阅。

  二、应用软件开发

  关于这方面,我首先不赞成“一味强调软件的数据库独立性”,因为要达到该目的不仅非常困难而且成本很高。当然这也不是绝对的,也需要

  具体问题具体分析。关于这方面的详细论述,大家可以参看Thomas Kyte先生所著《Effective Oracle by Design》。

  另外,在编码调试时,开发环境应模拟真实的数据量,这样可以使许多性能问题提前暴露,有助于开发人员早期认识到性能的重要性。

  在对敏感数据(如用户口令)加密算法的选择上,不要相信数据经MD5摘要算法处理后就是安全的,现在网络上已出现相关的海量数据库,尽量穷举出各字符串对应的MD5摘要值并提供反向查询。如果口令设置得比较简单(如4位或6位全数字的口令),其被破解的可能性非常大。

  三、测试

  应组织专门的测试队伍对系统进行功能与性能方面的测试。

  应牢记,测试的目的是为了发现软件当中的错误,而不是证明软件的正确性。

  应针对不同应用建立其相应的性能测试环境,引入相关测试工具或根据实际情况自行开发一些测试驱动程序,检验系统对负荷的承载能力。

  四、数据库项目实施

  系统设备选型、规划时,不应只考虑一时的购买成本,还应考虑长远的维护成本。很多大型企业或机构在进行信息系统建设时,建设者与维护者分属不同的部门,有的建设部门往往孤立地看待每个项目,只考虑一时的购买成本,造成各类设备五花八门、平台异构情况极其复杂,不仅增大了日常维护的成本,还给日后各系统的集成与数据共享造成了很多麻烦。

  系统上线前,要充分重视原系统数据的转换与导入,做好细致的审核工作,确保数据的准确性。有条件的话建议进行新旧系统的并行测试。

  五、数据库运行维护

  建立完善的备份/恢复策略,并定期测试,确保系统发生故障时能确实恢复成功;备份与原始数据存放在不同的物理设备上。建立完善的数据库用户口令管理机制,规定口令的复杂度、有效期限等。在满足需求的前提下,尽量减少数据库用户的各类权限。每天检查数据库各种日志,定期进行阶段性的系统健康检查,尽早发现潜在的问题。实时监控数据库的运行状况,及时发现异常并处理。任何配置或数据结构的改动都要先在测试库测试成功后再应用到生产库,并准备应急恢复方案。根据运行状况,有计划地对数据库进行重组织。

  六、其它

  参加数据库应用项目的人员,要有很好的沟通能力与团队精神,这样才能保证项目的顺利完成;还要不断地学习相关的新知识、新技术(如存储、网络、安全等),有选择地应用到系统中去。

  最后强调一点“三分技术,七分管理,十二分的数据”可能被引用得有些俗了,但它确实是有关数据库应用经验的精辟概括与总结,对于大多数的数据库应用项目,技术方面往往不是决定项目成败最为关键的因素,而数据是否准确、管理是否规范与合理,才是更为关键的因素。

  应用难点技巧

  我想在这里还是有必要强调一下,关于数据库应用方面的学习,首先要重视的还是对基本理论、基本概念的理解,因为只有这样,在碰到问题的时候,才能比较容易地分析出问题的本质,并尽快找出问题的答案,自己找出解决问题的技巧。

  而许多在网上或书上、杂志出现的所谓技巧,往往都具有片面性或时间性,如果你不能认识到他们成立的条件,往往会备误导。

  比如你很可能听说过“查询中尽量不要用or,因为这样不能用到索引”,也许这个结论对多年前的某个数据库版本是成立的,某个人就把他作为技巧记录并从此传承下来了,但现在主要的数据库优化引擎经过多年的发展都没有这样的限制了,再死抱住这样的技巧也就不对了。

  再有关于子查询,有的人说不要用not in而有的人说不要用not exists,他们的结论可能在某些情况下都是正确的,但是都不具备普遍性。所以还是那句话,具体问题具体分析。

  以上是我对于技巧的一些看法,也可以算是我贡献给大家的“不是技巧的技巧”。

  下面,我也总结几条常见问题的处理技巧,供大家参考:

  1、关于Oracle字符集的设置,历来是各技术论坛经常被讨论的问题,但许多讨论都不彻底或有明显的错误,致使许多朋友在应用过程中出现乱码的烦恼。关于这方面的问题,大家可以参考《Oracle数据库字符集问题解析》一文(www.itpub.net/276524.html),其中最主要的请记住两点:(1)在数据库端:选择需要的字符集(通过create database中的CHARACTER SET与NATIONAL CHARACTER SET子句指定);(2)在客户端:设置操作系统实际使用的字符集(通过环境变量NLS_LANG设置)。

  2、Oracle 9i以来引入了“闪回”(flash back)功能,能够查询到不久前的时间点各表的数据情况,这对恢复人为差错造成的数据丢失很有用,不用使用备份及归档日志进行恢复,只要一个简单SQL即可恢复。如误删了某表的数据,可用形如下面的SQL进行恢复:

  insert into tab1

  select * from tab1 as of timestamp to_timestamp('200501010101','yyyymmddhh24mi')

  3、对于WEB查询结果集比较大,需要分页并排序显示的情况,在Oracle中可以采用形如下面的SQL:

  select *

  from ( select a.*, rownum r

  from ( select *

  from t

  where x = :host_variable

  order by y ) a

  where rownum < :HigherBound )

  where r > :LowerBound

  这样Oracle在决定执行计划时,可以不对整个结果集进行排序,而只需保证显示的当前页及之前的数据排序准确即可,系统效率得以提升。

  4、对于使用Oracle 数据库,但没有用到绑定变量的一些OLTP应用,可以考虑设置cursor_sharing参数强制使用绑定变量,我过去曾经做过一个测试,对于某个应用,强制使用绑定变量后在相同的负载情况下系统CPU使用率下降30%以上,当然也要注意使用该设置后一些大的统计查询SQL的执行计划有可能受到负面影响。所以,最好在开发阶段就使用绑定变量。

  5、对于Oracle数据库经常出现的ora 4031(unable to allocate %s bytes of shared memory)错误,首先应确定是否为Oracle的BUG所引起,尤其是ORACLE 8.1.7.0版本,存在内存泄露(memory leak)(bug no:1397603)的问题,解决的办法一是暂时设置内部参数_db_handles_cached =0,最终的解决方法是将ORACLE升级到8.1.7.2或更高的版本。如果确认不是Oracle的BUG,可以考虑利用oracle提供的包dbms_s