{aa27aa} 本文大纲
作为一名使用 Oracle 的开发人员,在写这个系列博文之前,我原打算仅对常用 DDL 和 DML 做一个总结就算了。但在本人阅读《剑破冰山——Oracle 开发艺术》第一章——《大话数据库编程规范》时,对书中内容产生了强烈的共鸣,因此决定先写 数据库编程规范。本文核心内容来自该书第一章,有删改,且增加了一些本人对书中内容的理解和实际开发中的经验之谈。
良好的书写规范给人以享受和艺术的体验,而糟糕的书写不仅可读性差,还给人敬而远之的感觉。数据库编程作为应用程序开发的一部分,也应当要有相应的书写规范。
我相信一定会有人对这个规范持怀疑态度!我也曾为 SQL 语句到底该用大写还是用小写纠结了好几年!在学习和工作中我先后使用过大小写混合、全小写、全大写等风格,严格来说,没有任何一种是在不同场景下都绝对最好的风格,但综合来讲,数据库关键字和保留字全大写是一种相对较好的风格。
在我学习数据库编程时,我的老师用的是帕斯卡命名法,这种命名书写方便、阅读美观,于是我延续了老师的风格,并沿用到工作中,从未感觉有任何不妥。直到我第一次使用 Oracle,我用标准的帕斯卡命名法写好了表结构定义,执行成功之后,打开设计器看到表结构那一刻,我的眼神是无辜的、内心是崩溃的!因为表名和字段名全都变成了大写,那时我看着顺眼的只有帕斯卡命名法命名的表和字段。向来不愿主动放弃的我觉得一定有办法让 Oracle 支持帕斯卡命名法,还是菜鸟一个的我折腾了半天最后还是不了了之,这令我久久不能释怀,我也因此曾一度非常厌恶 Oracle。
在 Oracle 中,表名和字段名是会被彻底的强制转成大写的,而诸如:视图、函数、存储过程、触发器等对象,虽然通过工具查看时对象名也是大写的,但 DDL 语句中的名称却会保持原来的大小写。而任务的 DDL 语句甚至会被强制转成小写的。
实际上,Oracle 的表名和字段名也是有办法支持大小写的。只需要在创建表的时候,把表名和字段名用引号包裹起来,就可以任意选择帕斯卡命名法和骆驼命名法了。但问题是访问表或字段时也得用引号包裹起来才能访问,否则直接报找不到对象之类的错误。而实际项目中我从未见人这么用过,貌似大部分人都不知道这种怪异的用法!
程序块主要是指表结构、视图、函数、存储过程等数据库对象定义中的程序块。缩进必须使用空格,不允许使用 Tab 键。以免在用不同编辑器阅读程序时,因 Tab 键所设置的空格数目不同而造成程序布局不整齐。
书中说应该进行严格的右对齐,但我本人还是喜欢严格的左对齐,毕竟一般编程语言都是提倡左对齐,而且左对齐也更容易书写和控制。我个人觉得换行关键字左对齐还是右对齐都 OK,但必须是严格对齐。
左对齐代码示例
- IF v_staff_name IS NULL THEN
- SELECT t.staff_name -- 同上一行相比缩进 2 个空格
- INTO v_staff_name -- INTO 与 SELECT 进行左对齐
- FROM t_staff t -- FROM 与 SELECT 进行左对齐
- WHERE t.staff_id=:p_staff_id; -- WHERE 与 SELECT 进行左对齐
- END IF;
右对齐代码示例
- IF v_staff_name IS NULL THEN
- SELECT t.staff_name -- 同上一行相比缩进 2 个空格
- INTO v_staff_name -- INTO 与 SELECT 进行右对齐
- FROM t_staff t -- FROM 与 SELECT 进行右对齐
- WHERE t.staff_id=:p_staff_id; -- WHERE 与 SELECT 进行右对齐
- END IF;
凡是将来有可能涉及多张表的 SQL 语句,即使当下只有一个表也最好取个别名,且访问表中任何字段都用表的别名来限定,不要在一条语句中反复使用某个别名。建议养成总是给表取别名且用表的别名来限定表中字段名的好习惯,这可能会给你节省大量时间,也可能会带来意想不到的惊喜。
本人工作中曾遇到写在后端程序中的一条 SQL 语句在某个测试环境中运行正常,但在另一个测试环境中就有问题,忘记了是会报错还是查不到数据,把那条 SQL 语句拷贝到开发环境中运行也没问题。由于那条语句较长,涉及多个表且包含子查询,查询列表的字段超过 20 个,条件中涉及的字段也很多,有些表有别名,有些表又没有,部分字段有表别名限定,部分有表别名的字段又没限定,还有一些没有表别名的字段自然也就没有限定了,结果看了老半天,眼睛都看花了也找不出问题来。无奈之下我把那条语句照抄了一遍,但我给每个表都取了别名,无论查询列表还是过滤条件中的字段我都有用表别名来限定,原本我只是想按照我的习惯把语句抄写整理一遍,方便进一步查找问题,结果写好之后一测试,开发环境及所有测试环境都 OK 了!
命名规范想要做到完全一致几乎是不可能的,但我们仍要尽量去遵守,必要的时候通过代码审查和专家评审来进行约束,因为一个不成熟的规范总好过没有规范。
实际上这几种命名风格各有千秋,很难去指责或否定那种不好,完全取决于整个公司或项目中多数人的习惯,没有十全十美的命名规范,只要绝大多数人心甘情愿地去遵循,那就是好的命名规范。
查询 Oracle 中的关键字和保留字的语句如下:
- SELECT * FROM v$reserved_words WHERE reserved='Y'; -- reserved='Y' 表示已被完全禁止
实际上 Oracle 是不建议使用 v$reserved_words 表中所有关键字,但这个表里的关键字太多了。
对象名 | 前缀 | 范例 |
---|---|---|
表 (table) | t_/tbl_/ 不加前缀 | t_user/tbl_user/user |
视图 (view) | v_/view_ | v_user/view_user |
物化视图 (materialized view) | mv_ | mv_user |
函数 (function) | f_/fn_/func_ | fn_user/func_user |
存储过程 (procedure) | p_/sp_/proc_ | sp_user/proc_user |
触发器 (trigger) | trg_ | trg_user |
包和包体 (package&package body) | pkg_ | pkg_user |
类和类体 (type&type body) | typ_ | typ_user |
主键 (primary key) | pk_ | pk_user |
外键 (foreign key) | fk_ | fk_user |
唯一索引 (unique index) | uk_ | uk_user |
普通索引 (normal index) | idx_ | idx_user |
位图索引 (bitmap index) | bk_ | bk_user |
序列 (sequence) | seq_ | seq_user |
簇 (cluster) | c_ | c_user |
数据库链接 (database link) | ||
同义词 (synonym) |
变量类型 | 前缀 | 范例 |
---|---|---|
输入变量 | i_/i | i_user_id/iuserid |
输出变量 | o_/o | o_user_name/ousername |
输入输出变量 | io_/io | io_user_id/iouserid |
普通变量 | v_/v | v_user_id/vuserid |
全局变量 | gv_/gv | gv_user_id/gvuserid |
常量 | 全大写 | pi |
游标 | cur_ | cur_user_info |
用户自定义类型 | type_ | type_user_info |
保存点 (save point) | spt_ | spt_user_info |
说明:个人命名风格,在符合所在项目组的命名规则的前提下,才可以使用。
说明:在长的 SQL 语句中,变量用单个字符表示,容易写错,而编译器往往检查不出来,有可能因为这个小小的错误而花费大量的时间。
注释规范是判断一个开发人员优劣和成熟度的重要标准。一个优秀的研发人员必然是经过深思熟虑之后才洋洋洒洒妙笔生花的,注释的书写体现了一个人思考问题的全过程和步骤。
说明:注释的原则是有助于对程序阅读理解,在该加的地方都加了,注释不易太多也不能太少,注释语言需准确、易懂、简洁、精炼。
说明:这些语句往往是程序实现某一特定功能的关键,对于维护人员来说,良好的注释有助于更好的理解程序,有时甚至优于看设计文档。
良好的语法规范有助于书写出高效、完备的 PLSQL 程序,同时有助于提高系统的容错性、健壮性和可追溯性。
说明:在书写代码时,必须确定表的结构和表中各个字段的数据类型,特别是在书写查询条件时的字段就更要注意了。这个也是导致 SQL 性能不佳的原因之一。
例如:DECODE 函数完全可以用 CASE WHIN 语句代替,而且可编程性更强。(+)= 右关联用 RIGHT OUTER JOIN 语句代替。=(+) 左关联用 LEFT OUTER JOIN 语句代替。
正规的 IT 公司一般都会制定一些编程规范,但这其中仍有不少公司只片面的强调前后端编程规范,忽略了数据库编程规范,这既不可取也不合理的。
代码的可读性比说明文档更重要,这是我在工作中总结出的 "真理" 之一。如果你有被糟糕的程序结构、怪异的变量命名、凌乱的编码风格…… 折磨过的经历,那么我相信你可能也会有类似的 "名句"。
在我学习编程的时候,我的老师就要求我们取变量名时要取有意义的名字,说实在的那时候我还不能意识到这有多重要,值得庆幸的是我记住了老师的话,并落实到学习和实际工作中,就这样在无形中养成了一个好的编程习惯。
在我工作这几年中,接触的很多代码可读性都不高,这些代码的原作者一般也不在公司了,所以往往需要花比较多的时间才能弄懂个大概。比这个还闹心的是,这些代码的可维护性更差,老板可能会想当初那个人做这个功能也就花了两天,给你一天改一下应该是足够的,但他不知道的是一天时间可能你根本没法搞懂那个程序,如果你稀里糊涂的就去改,那结果可能更糟,你会发现随便一改就出来好几个 BUG,然后你再去改 BUG,等你把明显的 BUG 都消灭之后可能已经过去两天了,而且那个程序也被你改的更长更复杂了,往后更加难改了,如果老板再说要改你可能会建议把这个程序扔到垃圾桶,然后自己重新做一个更好的。
如今有大量开发人员在程序的苦海中重复着低级的劳动,其中一个重要原因就是项目当初没有遵从良好的编程规范,导致代码的可读性、可维护性、可移植性、可测试性、开发效率、运行效率等都比较差。所以在正规开发过程中,编程规范是必不可少的!
来源: