《2022年数据库规范实用 .pdf》由会员分享,可在线阅读,更多相关《2022年数据库规范实用 .pdf(17页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、数据库编程规范名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 17 页 - - - - - - - - - 1.前言目前在软件圈内有这么一个现象,就是:DBA 不太懂写PL/SQL ,而开发人员写的又是五花八门,而且效率不高。如此以来,造成诸多弊端:1. 可读性差。读别人写的一个程序花费的时间,比自己写一个程序的花费时间还要长;非但别人看不懂,时间久了连自己也看不懂了。2. 可维护性差。程序越写越长,越改越烂,像懒婆娘的裹脚布,又臭又长。3. 可移植性差。今天用oracl
2、e 写一套,明天换成SQL Server 的时候再写一套,众多的数据库开发人员在程序的苦海中重复着低级劳动4. 效率和性能差。一个存储过程或SQL 执行效率简直可以让你感觉到对时间的绝望,你很快就理解什么是相对论了。2.编程规范概述事实上为了统一软件开发过程中关于数据库设计时的命名规范和编程规范,正规一些的IT 公司都会制定一些关于数据库对象的命名和编程规范。否则的话,你写你的我写我的,各自为战不兼容,彼此看不懂,甚至到最后连自己都弄不明白了,这样的经历相信每个人都曾经遇到过。例如下面这段简单的代码,您看的明白吗?就算暂时明白,过个一年半载您还明白吗?就算您记忆超群,想必也会忘记,不是么?A:
3、=1;b:=2;SeLeCT username from EmPLOyee where id=a aNd Type=b; 如果你改为下面这样的写法,相信稍微懂点数据库的人都应该看的明白不是?vID:=1; -A 为 ID vType=2; -B 为类型SELECT username FROM employee WHERE id=vID AND type=vType; 3.书写规范丑陋的书写规范不仅可读性较差,而且给人以敬而远之的感觉,就是您是大侠也不行啊;而良好的书名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 -
4、 - - - - - - 第 2 页,共 17 页 - - - - - - - - - 写规范则给人以享受和艺术的体验。 3.1. 大小写风格所有数据库关键字和保留字均使用大写;关于字段、变量的大小写风格在1.4 详细介绍。3.2. 缩进风格3.2.1. 规则程序块严格采用缩进风格书写,保证代码清晰易读,风格一致,缩进格数统一为2 /4 个。必须使用空格,不允许使用TAB 键。以免用不同的编辑器阅读程序时,因TAB 键所设置的空格数目不同而造成程序布局不整齐。3.2.2. 规则同一条语句需要占用多于一行时,每行的其它关键字与第一行的关键字进行右对齐。IF flag=1 THEN SELECT
5、username - 同上一行相比缩进4 个空格INTO vuserinfo -INTO 与 SELECT 进行右对齐FROM userinfo -FROM 与 SELECT 进行右对齐WHERE userid=:iuserid; -WHERE 与 SELECT 进行右对齐END IF; 3.3.空格及换行3.3.1. 规则不允许把多个语句写在一行中,即一行只写一条语句。3.3.2. 规则避免将复杂的SQL 语句写到同一行,建议要在关键字和谓词处换行。 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - -
6、 - - - 第 3 页,共 17 页 - - - - - - - - - 3.3.3. 规则相对独立的程序块之间必须加空行。BEGIN 、 END 独立成行3.3.4. 规则太长的表达式应在低优先级操作符处换行,操作符或关键字放在新行之首。划分出新行应当适当地缩进,使排版整齐,语句可读。不同类型的操作符混合使用时,建议使用括号进行隔离,以使代码清晰。3.3.5. 规则减少控制语句的检查次数,如在 IFELSE 控制语句中,对最常用符合条件,尽量前置以被检查到。DECLARE - 定义局部变量vFlag VARCHAR2(10); - 判断标志BEGIN IF (a=b AND a=c AND
7、 a=d) OR - 在 OR 处断行,可使得逻辑更为清晰 (a=e AND e=f) THEN -Process something IF vFlag=1 THEN -vFlag=1 为经常出现之条件,可有效减少判断检查次数-Process something ELSIF vFlag=2 THEN -vFlag=2 为次之出现的条件-Process something ELSE -Process something END IF; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4
8、 页,共 17 页 - - - - - - - - - 3.4. 其它3.4.1. 规则避免使用SELECT * 语句;不要用 * 来代替所有字段,应给出字段列表,以避免表结构发生变化时应用程序出现无法识别的情况。3.4.2. 规则INSERT 语句必须给出字段列表,以避免表结构发生变化时发生编译错误。3.4.3. 规则当一个 PL/SQL 或 SQL 语句中涉及到多个表时,始终使用别名来限定表名和字段名,这使其它人阅读起来更方便,避免了含义模糊的引用,并能够别名中清晰地判断出表名和相关字段名。3.4.4. 规则确保变量和参数在类型和长度与表数据列类型和长度相匹配。说明:如果与表数据列宽度不匹
9、配,则当较宽或较大的数据传进来时会产生运行异常。DECLARE - 定义相关表字段变量vDeptNo salary.Deptno%type; -not VARCHAR2(10) ,以适应变化vEmployeeNo salary.EmployeeNo%type; -not VARCHAR2(10) ,以适应变化vSalary salary.Salary%type; -not NUMBER ,以适应变化BEGIN -Process something END; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - -
10、 - - - - 第 5 页,共 17 页 - - - - - - - - - 4.命名规范一千个读者就有一千个哈姆雷特,对于命名规范来说,想做到完全统一的确是不可能的任务。命名规范更多的是个人层面的爱好,就算有命名规范,也不过是体现制订规范的相关人的爱好而已。因此即使无法完全做到一致,但是我们仍然要尽量去遵守,必要的时候需要通过代码检查和专家评审来进行约束,因为一个不成熟的规范总会胜过没有规范。4.1. 表和字段命名规范在此仅提供几种常见的命名方法( 表和字段的命名方式雷同) 。以用户权限字段/ 表为例: UserPrivilege适合那些英文比较好,并且喜欢抑扬顿挫和有艺术美感的人。use
11、rprivilege适合那些英文好,且比较严谨的人,毕竟全部小写很容易与数据库关键字相区别。tbl_user_privilege适合那些做开发的人,开发的人会习惯性的给变量加前缀。(这里指表的命名,字段一般很少加前缀)yhqx热爱中文的人,前提是恐怕您得对这些缩写先做好相关备注,等大家习惯了才行。实际上这几种命名规范各有千秋,很难去指责或否定哪种更好,完全取决于整个公司多数人的习惯,记住没有十全十美的命名规范,只有绝大多数人心甘情愿的去遵从了,那就是好的命名规范。就我个人而言,我更偏向于第一种命名习惯。4.1.1. 规则不建议使用数据库关键字和保留字(不建议并不意味着不能使用), 只是为了避免
12、不必要的冲突和麻烦;例如 name,id,level,remark,description 等等。有兴趣的话,大家可以参考下SELECT * FROM v$reserved_words WHERE reserved=Y 实际上oracle 不建议大家使用v$reserved_words 表中所有的关键字,无奈这些关键字太多了;reserved=Y 的关键字则是被完全禁止的。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 17 页 - - - - - - - - - 4.1
13、.2. 规则严禁使用带空格的名称来对字段和表命名;在产生数据库脚本并重新加载的时候可能会出现意想不到的错误而被迫终止。4.2. 其它对象命名用户自定义的数据库对象名包括表、视图、主外键、索引、触发器、函数、存储过程、序列、同义词、数据库链接、包和包体等等。4.2.1. 规则其它对象的命名也与表和字段的命名规则类似,风格保持一致即可4.2.2. 规则除数据库名称长度为1-8 个字符,其余为1-30 个字符, database link 名称也不要超过30 个字符;命名只能使用英文字母,数字和下划线4.2.3. 规则除表外,其它各种对象的命名最好用不同的前缀加以区别。采用前缀的方式来命名对象则很容
14、易通过排序对对象进行区别。如在命名规范中各组成部分以_ 分割,则前缀建议也以_ 分割;反之则可加可不加对象名 前缀 范例 表(table)tb_/t_ ( 或不加前缀) userinfo/t_user_info/ tb_user_info视图 (view)v_v_user_info序列 (sequence)seq_seq_user_info名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 17 页 - - - - - - - - - 簇(cluster)c_c_user_i
15、nfo触发器 (trigger)trg_trg_user_info存储过程 (procedure)sp_/p_sp_user_info/p_user_info函数 (function)f_/fn_fn_user_info/f_user_info物化视图 (materialized view)mv_mv_user_info包和包体 (package & package body)pkg_pkg_user_info类和类体 (type & type body)typ_typ_user_info主键 (primary key)pk_pk_user_info外键 (foreign key)fk_fk_
16、user_info_fieldname唯一索引 (unique index)uk_uk_user_info_fieldname普通索引 (normal index)idx_idx_user_info_fieldname位图索引 (bitmap index)bk_bk_user_info_fieldname同义词 (synonym)依据于所分配的表所属模块/ 模式 数据库链接 (database link)无特殊要求 5.变量命名5.1. 规则所有 PL/SQL 中的变量与对象命名规则相似变量类型 前缀 范例 输入变量 i_i_user_id名师资料总结 - - -精品资料欢迎下载 - - -
17、- - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 8 页,共 17 页 - - - - - - - - - 输出变量 o_o_user_name输出输入变量 io_io_user_name普通变量 v_v_user_id全局变量 gv_gv_user_id常量 大写 PI游标 cur_cur_userinfo用户自定义类型 type_type_user_info保存点 (save point)spt_spt_user_info5.2. 规则命名不允许使用中文或者特殊字符。命名中若使用特殊约定或缩写,则要注释说明。5.3. 规则使用有意义、
18、易于记忆、描述性强、简短及唯一的英文单词/ 拼音缩写。自己特有的命名风格,要自始自终保持一致,不可来回变化。说明:个人命名风格,在符合所在项目组的命名规则的前提下,才可以使用。5.4. 规则对于变量命名,禁止取单个字符( 如 i 、j ) ,建议除了要有具体含义外,还能表明变量类型等。说明:变量,尤其是局部变量,如果用单个字符表示,很容易敲错( 如 i 写成 j) ,而编译时又检查不出来,有可能为了这个小小的错误而花费大量的时间。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 9 页
19、,共 17 页 - - - - - - - - - 6.注释规范注释规范是判断一个开发人员优劣和成熟度的重要指标。一个优秀的研发人员必然是经过深思熟虑然后才洋洋洒洒妙笔生花的,注释的书写体现了一个人思考问题的全过程和步骤;话又说回来,就算代码写的烂,只要注释写的好,至少也会给人以良好的感觉;同时也能造福后人,不是么?呵呵。6.1. 规则一般情况下,源程序有效注释量必须在30% 左右。说明:注释的原则是有助于对程序阅读理解,在该加的地方都加了,注释不宜太多也不能太少,注释语言须准确、易懂、简洁、精炼。6.2. 规则统一文件头的注释。主要是对相关过程、函数进行功能性描述、修订记录、以及入参出参说明
20、。对存储过程、函数的任何修改,都需要在注释后添加修改人、修改日期及修改原因等修订说明。/* 名称 : sp_xxx 功能描述:修订记录:版本号编辑时间编辑人修改描述1.0.0 2010-01-01 John 1 、创建此存储过程1.0.1 2010-02-01 Sandy 2 、增加传入参数入参出参描述:iparameter1 IN V ARCHAR2(20) 传入参数 1 iparameter2 IN V ARCHAR2(20) 传入参数 2 iparameter1 OUT VARCHAR2(20) 传入参数1 iparameter2 OUT VARCHAR2(20) 传入参数2 名师资料总
21、结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 10 页,共 17 页 - - - - - - - - - 返回值描述: ( 主要针对函数) 0 - Success 1 - normal fail */ 6.3. 规则所有变量定义需要加注释,说明该变量的用途和含义。6.4. 规则注释内容要清晰、明了、含义准确,防止注释二义性。在代码的功能、意图层次上进行注释,提供有用、额外的信息。避免在一行代码或表达式的中间插入注释。尽量使用“ - ”进行注释;行尾注释须使用“- ” 。6.5. 规则对程序分
22、支必须书写注释。说明:这些语句往往是程序实现某一特定功能的关键,对于维护人员来说,良好的注释帮助更好的理解程序,有时甚至优于看设计文档。在程序块的结束行右方加注释,以表明程序块结束。6.6. 规则注释应与其描述的代码相似,对代码注释应放在其上方或右方( 对单条语句的注释) 相近位置, 不可放在下面。注释与所描述的内容进行同样的缩排。注释上面的代码应空行隔开。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 11 页,共 17 页 - - - - - - - - - 6.7. 建议注释用
23、中文书写有一次,同事写了一个900 行的存储过程,里面定义了十几个游标以进行遍历,这个存储过程缺乏注释,执行一次居然要一天一夜,已经达到了无法容忍的地步。因为缺乏注释,我花了整整一天的时间来对该存储过程进行分析,然后用了半天时间来进行改写和调试。其实很简单定义,我定义了一些对应的临时表,把游标遍历替换成SQL 的集合操作,把整个的一个大事务分割成若干小事务,只是修改了部分代码,结果执行时间就变成了短短的3 分钟。当然游标也并非不可触及的,既然存在就有他存在的理由。7.语法规范良好的语法规范有助于书写出高效、完备的PL/SQL 程序,同时有助于提高系统的容错性、健壮性、可追溯性。7.1. 规则避
24、免隐式的数据类型转换。说明:在书写代码时,必须确定表的结构和表中各个字段的数据类型,特别是书写查询条件时的字段就更要注意了。这个是导致SQL 性能不佳常犯的错误之一。7.2. 规则为了方便不同的数据库平台的移植,尽量使用SQL99 标准,而不要使用Oracle 的方言。例如: DECODE 函数完全可以用CASE WHEN 语句代替,而且可编程性更强。(+)= 右关联用RIGHT OUTER JOIN 语句代替。=(+) 左关联用LEFT OUTER JOIN 语句代替。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整
25、理 - - - - - - - 第 12 页,共 17 页 - - - - - - - - - 7.3. 规则对于非常复杂的SQL( 特别是多层嵌套,带子句或相关的查询) ,应该先考虑是否设计不当引起的,对于复杂的一些SQL 可以考虑使用程序实现,原则上遵循一句话只做一件事情。关于处理的优先级1、静态 SQL 动态 SQL 2、绑定变量的SQL 动态 SQL (在 OLTP 系统中建议这么做)3、 SQLPL/SQL 的过程,极端复杂的SQL 除外4、 SQL 游标遍历5、 Oracle 函数 自定义函数6 、尽量使用Oracle 分析函数代替同一个表多次的关联。7.4. 规则原则上不要使用动
26、态SQL ,如果非得使用动态SQL ,建议使用绑定变量。7.5. 规则一定要及时关闭和释放游标7.6. 规则建议在异常处理中,把收集到错误信息记入错误日志表,以备查询和分析。CREATE OR REPLACE PROCEDURE sp_increament_xxx /* 名称 : sp_increament_xxx 功能描述: xxx 表/ 模块数据增量更新,错误原因分析通过tbl_task_table 日志表修订记录:版本号编辑时间编辑人修改描述1.0.0 2010-05-01 John 1 、创建此存储过程名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - -
27、 - - - - - - - 名师精心整理 - - - - - - - 第 13 页,共 17 页 - - - - - - - - - 1.0.1 2010-06-01 Sandy 2 、更新 xxx 字段在 xxx 处入参出参描述: N/A 返回值描述: ( 主要针对函数) N/A */ AS v_err_num NUMBER; v_err_msg VARCHAR2(100); v_begin_date DATE; v_end_date DATE; BEGIN v_err_num:=0; v_err_msg:=; - 某表增量更新步骤 BEGIN SAVEPOINT spt_xxx; - 从
28、任务表中获取更新初始时间 SELECT lasttime INTO v_begin_date FROM tbl_task_table T WHERE id=sp_increament_xxx; - 从源数据表中获取更新最后时间 SELECT MAX(oper_date) INTO v_end_date FROM tbl_table_source; - 为提高执行效率,将增量数据写入临时表中 INSERT INTO tmp_tbl_table_source (fieldname1,fieldname2,fieldname3, 名师资料总结 - - -精品资料欢迎下载 - - - - - - -
29、- - - - - - - - - - - 名师精心整理 - - - - - - - 第 14 页,共 17 页 - - - - - - - - - fieldname4,fieldname5,fieldname6) SELECT fieldname1,fieldname2,fieldname3, fieldname4,fieldname5,fieldname6 FROM tbl_table_source sourcetable WHERE sourcetable.create_date v_begin_date AND sourcetable.create_date = v_end_date
30、; - 再讲增量数据从临时表更新到最终目标表 MERGE INTO tbl_table_original_dest desttable USING tmp_tbl_table_source tmptable ON (desttable.primarykey = tmptable.primarykey) - 匹配判断标准,根据主键判断 WHEN MATCHED THEN - 如果已存在,更新原纪录 UPDATE SET desttable.fieldname1 = tmptable.fieldname1, desttable.fieldname1 = tmptable.fieldname1, d
31、esttable.fieldnamem = tmptable.fieldnamem, desttable.fieldnamen = tmptable.fieldnamen WHEN NOT MATCHED THEN - 如果不存在,插入新纪录 INSERT (fieldname1,fieldname2,fieldname3, fieldname4,fieldname5,fieldname6) VALUES (tmptable.fieldname1,tmptable.fieldname2,tmptable.fieldname3, tmptable.fieldname4,tmptable.fiel
32、dname5,tmptable.fieldname6); - 更新任务表相应的状态、时间 UPDATE tbl_task_table SET lasttime_=v_end_date,status=SUCCESS WHERE id=sp_increament_xxx; COMMIT; - 异常处理,把错误记入相关日志表,可以及时找到错误原因并进行分析。 EXCEPTION WHEN OTHERS THEN 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 15 页,共 17 页 - -
33、 - - - - - - - ROLLBACK TO SA VEPOINT spt_xxx; v_err_num := SQLCODE; v_err_msg := SUBSTR(SQLERRM, 1, 100); UPDATE tbl_task_table SET lasttime_=v_begin_date,status=FAIL WHERE id=sp_increament_xxx; COMMIT; END; - 某表增量更新步骤 BEGIN . END; END; 本例为数据库定时调用存储过程,同时也只是为了演示存储过程的全部过程;对于常用的由客户端调用的存储过程,建议不要捕获异常,而由
34、客户程序进行直接处理。7.7. 规则不要将空的变量值直接与比较运算符( 符号 ) 比较。如果变量可能为空,应使用IS NULL 或 IS NOT NULL 或 NVL 函数进行比较。7.8. 规则尽可能地使用相关表字段的类型定义,形如%TYPE 、%ROWTYPE 。这样做当表结构发生变动的时候,能够最大程度的做到容错性和健壮性。7.9. 规则存储过程中变量的声明应集中在AS 和 BEGIN 关键字之间,不允许在代码中随意定义变量,定义变名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第
35、 16 页,共 17 页 - - - - - - - - - 量时,完成相同功能模块的变量应放在一起,与不同模块的变量应空行隔开,增加代码的可读性。8.脚本规范脚本规范有助于进行版本基线的管理、版本控制,也有助于系统的自动部署、定位和解决部署过程中出现的问题。8.1. 规则所有脚本按分类或内容分开存放,并按以下顺序存储:1.创建数据库角色、用户脚本2.创建数据库表空间、数据文件脚本3.创建数据类型脚本,自定义的数据类型4.创建业务表脚本,表是其他依赖关系的基础5.创建临时表脚本,可能会在过程脚本中用到6.创建视图脚本7.创建主外键脚本8.创建索引脚本9.创建触发器脚本10.创建函数、存储过程脚本11.初始化数据脚本12.创建作业脚本8.2. 规则创建每个对象代码的首部应该有对象注释8.3. 规则每个函数、存储过程应单独创建脚本,在配置库上按照功能模块存放到不同的目录下。并在相应的目录下,创建一个运行所有脚本的总脚本。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 17 页,共 17 页 - - - - - - - - -
限制150内