Oracle-数据库设计规范建议

来源于项目资料

目的

本规范的主要目的是希望规范数据库设计,尽量提前避免由于数据库设计不当而产生的麻烦;同时好的规范,在执行的时候可以培养出好的习惯,好的习惯是软件质量的很好的保证。数据库设计是指对于一个给定的应用环境,构造最优的数据库模式,建立数据库及其应用系统,有效存储数据,满足用户信息要求和处理要求。

数据对象的命名规范

通用规范

使用英文:要用简单明了的英文单词,不要用拼音,特别是拼音缩写。主要目的很明确,让人容易明白这个对象是做什么用的; 一律大写,特别是表名:有些数据库,表的命名乃至其他数据对象的命名是大小写敏感的,为了避免不必要的麻烦,并且尊重通常的习惯,最好一律用大写;

数据库对象命名规范

表的命名

表名的前缀:前缀表名T。为表的名称增加一个或者多个前缀,前缀名不要太长,可以用缩写,最好用下划线与后面的单词分开;其目的有这样几个:

  1. 为了不与其他项目或者其他系统、子系统的表重名;

  2. 表示某种从属关系,比如表明是属于某个子系统、某个模块或者某个项目等等。表示这种从属关系的一个主要目的是,从表名能够大概知道如何去找相关的人员。比如以子系统为前缀的,当看到这个表的时候,就知道有问题可以去找该子系统的开发和使用人员;

视图命名:相关表名_V(或者根据需要另取名字);

程序包命名:程序包名_PKG(用英文表达程序包意义);

存储过程命名:存储过程名_PRO(用英文表达存储过程意义);

函数命名:函数名称_FUN(用英文表达函数作用);

触发器命名:触发器名称_TRI(用英文表达触发器作用);

索引命名:表名字段名IDX(如果存在多字段索引,取每字段前三个字符加下划线组合,如在 custom, cutting, curtail 上建立联合索引,命名为 表名cus_cut_cur_IDX,如果前三个截取字符相同,就从字段名称中不同的字符开始取三个字符加下划线组合,如在 custid, custom,custname上建立联合索引,就命名为表tid_tom_tna_IDX;

唯一索引命名:表名字段名UNI(如果存在多字段唯一索引,取每字段前三个字符加下划线组合,如在 custom, cutting, curtail上建立唯一索引,命名为 表名_ cus_cut_cur_UNI,如果前三个截取字符相同,就从字段名称中不同的字符开始取三个字符加下划线组合,如:在 custid, custom,custname上建立唯一索引,命名:表_tid_tom_tna_UNI;

主键命名:表名字段名PK(如果存在多字段主键,取每字段前三个字符加下划线组合,如在 custom, cutting, curtail上建立主键,命名为 表名cus_cut_cur_PK,如果前三个截取字符相同,就从字段名称中不同的字符开始取三个字符加下划线组合,如在 custid, custom,custname上建立主键,命名:表tid_tom_tna_PK;

外键命名:表名主表名字段名_FK;

Sequence 命名:表名列名SEQ(或者根据需要另取名字);

Synonym 命名:与对应的数据库对象同名;

JAVA 命名:遵守公司相应的JAVA命名规范;

数据库对象设计原则

表的设计

主、外键

  1. 每个表,都必须要有主键。主键是每行数据的唯一标识,保证主键不可随意更新修改,在不知道是否需要主键的时候,请加上主键,它会为你的程序以及将来查找数据中的错误等等,提供一定的帮助;

  2. 一个表的某列与另一表有关联关系的时候,如果加得上的话,请加上外键约束。外键是很重要的,所以要特别强调:

  3. 适量建外键。为了保证外键的一致性,数据库会增加一些开销,如果有确凿的并且是对性能影响到无法满足用户需求的证据,可以考虑不建外键。否则,还是应该建外键;

  4. 不要以数据操作不方便为理由而不建外键。是的,加上外键以后,一些数据操作变得有些麻烦,但是这正是对数据一致性的保护。正是因为这种保护很有效,所以最好不要拒绝它;

  5. 以缺省的方式建立外键(即用delete restrict方式),以达到保护数据一致性的目的;外键在保护数据一致方面非常有效。如果不建外键,数据库中容易出现垃圾数据,并且无人知晓。当数据量很大的时候,查找这些垃圾数据也是相当困难的。而应用程序在设计时,往往没有考虑或者也无法照顾到垃圾数据。因此垃圾数据很可能造成应用程序工作不正常,并且表现出来的现象会很奇怪,让人摸不着头脑。

列的设计

  1. 字段的宽度要在一定时间内足够用,但也不要过宽,占用过多的存储空间,对于长度不确定的列,采用可变长度的数据类型如 varchar类型;

  2. 字段的类型及宽度在设计以及后面进行开发时,往往要与应用的设计、开发人员商讨,以得到双方认可的类型及宽度;

  3. 除非必要,否则尽量不加冗余列。所谓冗余列,是指能通过其他列计算出来的列,或者是与某列表达同一含义的列,或者是从其他表复制过来的列等等。冗余列需要应用程序来维护一致性,相关列的值改变的时候,冗余列也需要随之修改,而这一规则未必所有人都知道,就有可能因此发生不一致的情况。如果是应用的特殊需要,或者是为了优化某些逻辑很复杂的查询等操作,可以加冗余列;

  1. 除非必要,否则尽量不使用LONG, TEXT, BLOB, CLOB, NCLOB, LONG, LONG RAW这一类的数据类型,而是使用其他可以替代的数据类型;优先使用varchar2类型替代CHAR类型,除非列宽有严格的要求而且得到应用严格支持;

记录数

  1. 单表的记录数一般控制在两千万条 (参考值,各应用可以根据实际情况进行适量调整) 以内;

  2. 记录数在两千万和两亿条之间的表一定要采用分区技术,并根据应用的使用情况创建合适的分区标准,单个分区内的记录数一般控制在两千万条(参考值,各应用可以根据实际情况进行适量调整)以内,同时表的索引使用对应的分区索引;

  3. 记录数超过两亿条的表一定要考虑信息生命周期,必须考虑历史数据的剥离,并在应用设计中完成对历史数据的相应处理功能(历史数据的剥离规则须经业务使用部门的确认);

索引的设计

索引是从数据库中获取数据的最高效方式之一。95%的数据库性能问题都可以采用索引技术得到解决。但大量的DML操作会增加系统对索引的维护成本,对性能会有一定影响,对于插入相当频繁的表要慎重建索引,索引也会占相当的存储空间,所以要根据硬件环境和应用需求在空间和时间上达到最好的平衡点,主要原则:

  1. 适当利用索引提高查询速度:当数据量比较大,了解应用程序的会有哪些查询,依据这些查询需求建相应的索引;最好亲自试验一下,模拟一下生产环境的数据量,在此数据量下,比较一下建索引前后的查询速度;索引对性能会有一定影响,对于DML频繁列的索引要定期维护(重建)。但是,索引的结构对于索引的更新(比如在插入数据的时候)是有一定优化的,所以不要在没有试验以前过分夸大它对性能的影响。最终还是以试验为准;

  2. 不要建实际用不上的索引,与上条相关,如果建的索引并不提高任何一应用中的查询速度,则要把它删除;有些数据库有相关工具可以发现实际未被使用的索引,可以利用一下;

  3. 索引类型的选择:要根据数据分布及应用来决定如何建立索引,一般的高基数数据列(高基数数据列是指该列有很多不同的值)时 ,建立BTree索引(一般数据库索引的缺省类型);当低基数数据列(该列有大量相同的值)时,可以考虑建立位图索引(如果所选数据库支持的话),但位图索引是压缩类型索引,所以DML(增、删、改)的代价更高,要综合考虑;

  4. 索引列的选择:如果检索条件有可能包含多列,创建联合主键或者联合索引,把最常用于检索条件的列放在最前端,其他的列排在后面;不要索引使用频繁的小型表,假如这些小表有频繁的DML就更不要建立索引,维护索引的代价远远高于扫描表的代价;

  5. 主键索引在建立的时候一定要明确的指定名称,不能让系统默认建立主键索引(可能有些数据库无法指定主键名,则例外);

  6. 外键必须需建索引。当有一定数据量,并且经常以外键所在列为关联,进行关联查询时,需要建索引(可能有些数据库自动为外键建索引,则例外);

  7. 当有联合主键或者联合索引时,注意不要建重复的索引。举例说明:

  • 更复杂的情况,比如表EMPLOYEES,有一个索引建立在列CORPID, DEPARTID, EMPLOYEEID三列上,在创建语句中也依据上述顺序,就没有必要再为CORPID建立索引;也没有必要再建立以CORPID在前,DEPARTID在后的联合索引;如果EMPLOYEEID需要索引,那么为EMPLOYEEID建立一个索引是不与上面的索引重复的;DEPARTID列也类似;

  • 表EMPLOYEES,它的主键是建立在列DEPARTID和EMPLOYEEID上的联合主键,并且创建主键的语句中DEPARTID在前,EMPLOYEEID在后。在这样一 个表里,通常就没有必要再为DEPARTID建一个索引了;联合索引的情况也一样;

控制一个表的索引数量,尽量使得一个表的索引数量小于五个;

视图的设计

  1. 在不太清楚视图用法的情况下,尽量不建。因为一旦建了,就有被滥用的危险;

  2. 如果需要建视图,只要是打算长期使用的,请写入数据库设计中。明确它的用途、目的;

  3. 建立视图时要明确写出所有要选择出的列名而不要以SELECT *来代替,可以使结构清晰可读性增强,也不会增加它对表的所有字段的依赖,而表是很可能修改的,特别是增加字段。就很有可能导致使用该视图的应用程序出错;

存储过程、函数、触发器的设计

  1. 触发器的功能通常可以用其他方式实现。在调试程序时触发器可能成为干扰。假如你确实需要采用触发器,一定要经过测试再应用在生产系统中,而且必须集中对它文档化。

  2. 请把程序包、存储过程、函数、触发器,与应用程序一同加入CVS中,进行版本控制。因为此四者包含了代码,应用程序对他们的依赖程度比对表、视图的依赖程度更高;

  3. 适量但尽量少使用存储过程、函数、触发器。使用存储过程、函数、触发器的影响:

    (1) 可以减少数据库与客户端的交互,提高性能;(2) 有的数据库还对他们进行了某种程度的编译,在执行的时候,不用再对其中的SQL等语句进行解析,从而提高速度;(3) 如果有多个应用,使用了不同的开发语言,当有某些关键的或者复杂逻辑希望共享,则可以考虑使用存储过程或者函数。因为存储过程等在数据库一级是共享的;(4) 增强了应用对数据库的依赖,如果打算将来移植数据库的话,使用得越多,则移植的困难越大;数据库中的业务逻辑越多(存储过程等),应用以及存储过程等的维护难度也会增大;(5) 通常存储过程等没有面向对象的特性,不容易设计出易于扩展的结构。当存储过程比较复杂时,或者它们相互间的调用关系比较复杂时,可能难于维护;

SQL的设计和使用

Sql 书写规范
  1. 尽量不要写复杂的SQL:过于复杂的SQL可以用存储过程或函数来代替,效率更高;甚至如果能保证不造成瓶颈的话,把条SQL拆成多条也是可以的。这与一般的编码规范很相似的,首先是要易懂。易懂也就意味着容易维护,对较为复杂的sql语句加上注释,说明算法、功能注释风格:注释单独成行、放在语句前面。

  2. 应对不易理解的分支条件表达式加注释;

  3. 对重要的计算应说明其功能;

  4. 过长的函数实现,应将其语句按实现的功能分段加以概括性说明;

  5. 每条复杂SQL语句均应有注释说明(表名、字段名 主要是说明此句SQL执行 的作用及所取得结果集的意义);

  6. 常量及变量注释时,应注释被保存值的含义(必须),合法取值的范围(可选__) ;

  7. 可采用单行/多行注释。(-- 或 /* */ 方式,不同数据库可能语法不同);

  8. 连接符or、in、and、以及=、<=、>=等前后加上一个空格;

  9. 不要用SELECT *:SELECT语句中写出必要的要选择的全部列名,增强语句可读性,避免不必要的选择;SELECT * 增加了对所有字段的依赖,当表增加了字段后,有可能发生错误;此外还可能增加了数据的流量,查询了一些实际不需要的字段;

  10. 避免长事务(Transaction):长事务容易造成死锁,应该避免,单个事务使用的数据库和系统资源不宜超过总资源1-2%(参考值,各应用可以根据实际情况进行适量调整,这种情况不适用于数据仓库);

  11. 行最长不能超过80字符,同一语句不同字句之间逗号以后空格,其他分割符前空格 where子句书写时,每个条件占一行,语句令起一行时,以保留字或者连接符开始,连接符右对齐;

  12. 多表连接时,使用表的别名来引用列;

  13. SQL中对视图的引用:在不太清楚视图用法的情况下,尽量不用。只是因为视图中有自己想要的字段就拿来用,是相当普遍和错误的用法。原因如下:

  • 增加了应用程序对视图的依赖,不必要的依赖是越少越好的。当有应用程序依赖了某个视图,不久可能其他人因为某种原因会修改此视图,原来的应用有可能会受到不同程度的影响;

  • 增加了不必要的数据流量,对你的实际需求,那很可能是一个非常复杂的视图,有大量你不需要的字段,并且关联了很多你实际不需要的表,对数据库资源 会有过多的消耗;

不要在SQL语句中使用基于rule规则的hint,因为在Oracle 10g及以后版本不再支持;

SQL 性能优化建议
  1. 系统可能选择基于规则的优化器,所以将结果集返回数据量小的表作为驱动表,即将结果集返回数据量小的表放在FROM后边最后一个表;

  2. 大量的排序操作影响系统性能,所以尽量减少order by和group by排序操作;

  3. 如必须使用排序操作,排序尽量建立在有索引的列上;

索引的使用
  1. 尽量避免对索引列进行计算。如对索引列计算较多,请提请数据库管理员建立函数索引;

  2. 尽量注意比较值与索引列数据类型的一致性(number与number比较、char与char比较),避免使用数据库的类型自动转换功能;如:SELECT * FROM categoryWHERE id = ‘123’; -- id’s type is number

  3. 对于复合索引,SQL语句必须使用主索引列;

  4. 索引字段中,尽量避免使用NULL值;

  5. 对于索引的比较,尽量避免使用NOT=(!=)

  6. 查询列和排序列与索引列次序保持一致 ;

  7. 尽量避免相同语句由于书写格式的不同,而导致多次语法分析(减少数据库的硬分析),如可使用TOAD的格式化工具对SQL语句进行格式化处理;

  8. 查询的WHERE过滤原则,应使过滤记录数最多的条件放在最前面;

  9. 在WHERE中,数据库函数、计算表达式等等,要尽可能将放在等号右边。否则会使所比较的字段上的索引失效;如:

    = TO_DATE(‘2001-9-01’,’yyyy-mm-dd’)AND gmt_modified< TO_DATE(‘2001-9-02’,’yyyy-mm-dd’);

    1. SELECT * FROM service_promotionWHERE TO_CHAR(gmt_modified,’yyyy-mm-dd’)= ‘20001-09-01’; 而应使用:SELECT *FROM service_promotionWHERE gmt_modified

  10. in、or子句常会使索引失效,尽可能不使用in、or;

  11. 尽量避免在循环中使用SQL语句;

  12. 在循环中尽量使用动态SQL语句提高执行性能;

其他与性能有关的设计原则

前面与提高数据库访问的性能相关的内容,这里就不再重复了,下面提出一些与数据库性能极为相关,但上文又未涉及的条目:

大数据量的开发环境

开发过程中,开发人员往往使用一个非常简单的、只有很少数据的数据库环境,便于程序的调试。但是,最好还提供一个数据量与真实环境相当的环境,数据量和应用的设计目标差不多,供开发人员使用。这样开发人员能立刻发现那些非常慢的数据库操作,比如写了一个非常不合理的SQL,因而能够在此时就排除,而不必等到测试或者甚至上线时才发觉。因为很多开发人员,由于对数据库的认识不够,通常只以完成功能为首要目的,容易写出效率非常低的SQL;

限制使用

这里说的限制使用是指如果能有其他的技术途径,就不要使用如下的Oracle技术,包括:DBLink, Trigger,用Java编写的存储过程等内容;

模拟测试

这里说的测试主要是指模拟实际应用对数据库的操作,进行测试,并发及访问量要模拟应用的设计需求。主要目的是了解在系统上线后,数据库的大概状况,避免一上线就崩溃或者慢得不能忍受的情况。提前发现瓶颈,做相应的优化;

应用测试

每个应用的测试阶段,特别是性能方面的测试,也要关注数据库的表现。如果出现瓶颈,则根据具体情况,根据需要必须修改部分数据库设计并修改相应程序;

数据库相关工具

为需要写SQL的开发人员提供方便的、图形化的客户端软件,可以用来执行SQL,看到表结构、索引等等,如TOAD, PL/SQL Develop软件。

oracle clob截取_Oracle数据库设计规范建议相关推荐

  1. oracle revoke 列_oracle数据库 revoke

    数据库必知词汇:数据控制语言DCL |名词定义|数据控制语言(Data Control Language, DCL)是SQL语言四大主要分类之一,是用来设置或者更改数据库用户或角色权限的语句,通过GR ...

  2. 这篇数据库设计规范建议,我必须分享给你

    为什么需要规范 在互联网项目,分工明确,拆分细致, 但一个项目往往会涉及众多参与人员,包括架构师.高级工程师.研发工程师.测试工程师.DBA等不同角色.数据库是一个项目的最底层设计, 如果设计不清晰, ...

  3. oracle 韩思捷_Oracle数据库技术服务案例精选

    目 录 案例1:某油田 1 第1章 数据迁移技术支持服务 2 1.1 项目背景 2 1.2 现有迁移方案 3 1.3 数据迁移问题解决 5 1.4 数据迁移之后确认 11 1.5 生产运行系统问题 1 ...

  4. oracle 前导列_Oracle数据库表和表列讲解

    如果将数据库比作一个存储东西的储物柜,表就像是储物柜上的各个抽屉,每个抽屉分门别类地存放了各种数据,在设计和规划数据库时,表的定义和规划往往相当重要,良好的表设计决定了程序人员编写程序的便利性与数据库 ...

  5. oracle clob导入mysql_Oracle数据库中包含CLOB字段表的导出和导入

    1.表的导出和导入 因为oracle中存储大量数据的CLOB字段默认是不导出的,所以在导出时需要特别设置一下. 我使用DBVisualizer这个工具进行导出和导入. 软件版本: DBVisualiz ...

  6. mysql与oracle链接超时_oracle数据库链接超时时间

    SQLServer访问Oracle查询性能问题解决 原文:SQLServer访问Oracle查询性能问题解决 1. 问题 系统有个模块,需要查询Oracle数据库中的数据.目前是通过建立链接服务器实现 ...

  7. oracle mysql 付费_oracle数据库要钱的吗?

    展开全部 Oracle软件本身是免费的,所以任何人都可以从Oracle官方32313133353236313431303231363533e59b9ee7ad9431333431366365网站下载并 ...

  8. oracle 韩思捷_ORACLE数据库技术实用详解:教你如何成为10g OCP

    本书系统全面地介绍了Oracle10g数据库的结构.管理和优化,内容涵盖整个10gOCP的考试范围.包括Oracle10g数据库的体系架构.存储结构.网络服务.备份与恢复.闪回(flashback)管 ...

  9. dg oracle 切换模式_Oracle数据库 DGbroker三种保护模式的切换

    1.三种保护模式 – Maximum protection 在Maximum protection下, 可以保证从库和主库数据完全一样,做到zero data loss.事务同时在主从两边提交完成,才 ...

最新文章

  1. python调用cplex求解_CPLEX的Python中Bender的分解示例
  2. CSS布局——display,position,float属性
  3. [ZJOI2010] 贪吃的老鼠(二分+差分+神仙建图网络流)
  4. 2019.02.09 bzoj4455: [Zjoi2016]小星星(容斥原理+dp)
  5. html 中 标签里面的id 和 name 有什么区别?
  6. ssh免密登录配置方法及配置
  7. 探索专有领域的端到端ASR解决之道
  8. JavaScript基础知识(四)
  9. Java设计模式与实践
  10. 使用 Java Annotation 定制 Ant Junit Report
  11. mysql 建表语句
  12. java 世界时间_Java对世界不同时区timezone之间时间转换的处理方法
  13. SAP将未审批的采购订单提交到OA去审批 程序 OA审批结果返回到SAP
  14. 华东理工大学计算机网络作业,华东理工大学计算机网络实验操作手册.pdf
  15. 深圳APP开发共享汽车APP
  16. 怎么把一副图片用PS调成简笔画?
  17. 一篇文章认识《双目立体视觉》
  18. java EE单例Singleton自启动
  19. 受到 1 万点暴击,二狗子被 DDoS 攻击的惨痛经历
  20. 蓝桥杯 分割项链 Java

热门文章

  1. 程序员面试金典 - 面试题 01.03. URL化(字符串)
  2. 剑指Offer - 面试题5. 替换空格(字符串)
  3. 回溯应用-- 0-1背包问题
  4. Java 远程mapduce_java – 如何远程运行mapreduce作业
  5. c2c旅游springboot开源_重量级开源的商城和SpringBoot等项目看看有没有正好是你需要的...
  6. MySQL - cast()函数
  7. mock模拟接口测试 vue_vue+mock.js实现前后端分离
  8. 论文浅尝 | S3QLRDF: 用于大规模RDF数据分布式SPARQL查询的关系分割架构
  9. CNCC 技术论坛 | 知识图谱赋能数字经济
  10. JavaScript每日学习日记(0)