数 据 库 使 用 规 则 (收集)

来源:互联网 发布:linux编译fortran 编辑:程序博客网 时间:2024/05/16 13:53

使
术语:
站点(SITE
  公司已建立的或待建立的网站,如:中文站(CHINA),国际站(ALIBABA),华商站(CHINESE)等。
OLPS
  Online process system,在线处理系统,即我们的会员可以浏览的网站所连接的数据库,也是我们所说的前台。
BOPS
  Back Office process system,后台处理系统,即我们的网站的发布系统。
BZO
  Business Object(?),公司网站低层JAVA对象,主要负责与数据库打交道。
一、 命名约定
1. 是指数据库、数据库对象如TABLESEQUENCEPROCEDURECOLUMN等的命名约定;
2. 命名富有意义英文词汇,除个别通用的(见列表),要避免使用缩写),多个单词组成的,中间以下划线分割;
3. 除数据库名称长度为18个字符,其余为130个字符,Database link名称也不要超过30个字符;
4. 命名只能使用英文字母,数字和下划线;
5. 避免使用Oracle的保留字如level、关键字如type(见列表);
6. 名表之间相关列名尽量同名;
7. 数据库的命名:网上数据库命名为“OLPS”+表示站点(SITE,以下同)的24个字符,后台数据库命名为“BOPS”+表示站点的24个字符。测试数据库命名为“OLPS|BOPS”“TEST”, 开发数据库命名为“OLPS|BOPS”+“TEST”,用模式(SCHEMAUSER)的不同来区分不同的站点。
8. INDEX命名:table_name+column_name+index_type(1 byte)+idx,各部分以下划线(_)分割。多单词组成的column name,取前几个单词首字母,加末单词组成column_name。如:samplemember_id上的index: sample_mid_idx   newstitle上的unique index:news_titile_uidx
9. SEQUENCE命名:seq_+table_name
二、 注释说明
1. 本注释说明主要用于PL/SQL程序及其它SQL文件,其它可作参考;
2. SQLPLUS接受的注释有三种:
――
 这儿是注释
/* 这儿是注释 */
REM
 这儿是注释
3. 开始注释,类似JAVAK中的开始注释,主要列出文件名,编写日期,版权说明,程序功能以及修改记录:
REM
REM
 $Header: filename, version, created date,auther
REM
REM Copyright
REM
REM FUNCTION
REM function explanation
REM
REM NOTES
REM
REM MODIFIED
 (yy/mm/dd
REM who when - for what, recently goes first
4. 块注释,如表注释,PROCEDURE注释等,同JAVA:
/*
* This table is for TrustPass
* mainly store the information
* of TrustPass members
*/
5. 单行注释,如列注释:
login_id VARCHAR2(32) NOT NULL, --
会员标识

三、 缩进
低级别语句在高级别语句后的,一般缩进4个空格:
DECLARE
v_MemberId VARCHAR2(32),
BEGIN
SELECT admin_member_id INTO v_MemberId
FROM company
WHERE id = 10;
DBMS_OUTPUT.PUT_LINE(v_MemberId);
END;

同一语句不同部分的缩进,如果为sub statement,则通常为2个空格,如果与上一句某部分有密切联系的,则缩至与其对齐:
BEGIN
FOR v_TmpRec IN
(SELECT login_id,
gmt_created, -- here indented as column above
satus
FROM member -- sub statement
WHERE site = 'china'
AND country='cn' )
LOOP
NULL;
END LOOP;
END;
四、 断行
一行最长不能超过80字符
同一语句不同字句之间
逗号以后空格
其他分割符前空格
SELECT
 offer_name
||','
||offer_count as offer_category,
id
FROM category
WHERE super_category_id_1 = 0;
五、 大小写
属于ORACLE的关键字大小,表名、列名等小写。
六、 列类型的选择
CHAR(1)代替布尔值;
应尽量使用VARCHAR2代替CHAR类型;
• VARCHAR(2)
最多4000字符;
• DATE
精确到微秒,而非天;
使用CLOB代替LONGBLOB代替LONG RAW
• ORACLE
只有NUMBER一种数据类型,使用时请给定长度;
七、 主键选择
选择有意义的,不太长且能唯一标识记录行的列做主键,没有这种列时,才考虑使用SEQUENCE做主健。
八、 列长度的选择
应当根据实际需要选择列长度。有对应web 页面的,与页面上对应列长度一致。

对数据的验证除数据库端实现外还要尽可能在表现层控制。
九、 使用SQL语句的约定
1. 尽量避免在循环中使用SQL语句。
2. 避免在WHERE字句中对列施以函数:
SELECT
 * 
FROM
 service_promotion
WHERE TO_CHAR(gmt_modified,’yyyy-mm-dd’)
= ‘20001-09-01’;
  而应使用:
SELECT *
FROM service_promotion
WHERE gmt_modified
>= TO_DATE(‘2001-9-01’,’yyyy-mm-dd’)
AND gmt_modified
< TO_DATE(‘2001-9-02’,’yyyy-mm-dd’);

3. 避免使用数据库的类型自动转换功能:
SELECT * FROM category
WHERE id = ‘123’; -- id’s type is number
4. 避免无效的连接:
SELECT count(*)
FROM offer a, count_by_email b
WHERE a.email(+) = b.email;
5. 连接(join)时要使用别名:
SELECT a.*,b.offer_count(*)
FROM offer a, count_by_email b
WHERE a.email(+) = b.email;
6.
TABLE META信息:
SELECT *
FROM table_name
WHERE rowid is null (or rownum = 1 or pk = impossible_value);
可考虑使用:
SELECT *
FROM table_name
WHERE 1 = 0 ;



十、 关于ALIBABA表的约定
如果使用ALIBABA BZO,设表至少有如下字段:
site VARCHAR2(32)
gmt_create DATE
gmt_modified DATE
如果从IdBizObject继承,则还有一个NUMBER型的列,通常是主键,并与某一个SEQUENCECF 对应;如果从StrIdBizObject继承,则还有一个VARCHAR2型的列。
十一、 列值约定
1. 有固定值列表的列,如status, action, site, 其值取小写;
2. 应尽可能选择数字来代表固定值列表中的值,相应的列定义为NUMBER型;
3. CHAR1)表示布尔值的取大写:“Y”“N”
十二、 关于表重复属性的定义
不能有多择一的重复属性列;

对于能多选的重复属性列,如果不做查询列并且重复次数较多,应使用ID_VARRAY代替,如要用作查询列,重复次数多的,应另建一表,次数少的且列值为二择一时,应使用NUMBER类型,加位操作。
十三、 数据修改约定
发现Production环境中数据有误,需要改正的,应在RA TERMINAL上提交数据更新表单,由数据库操作员在当日17时前修改完毕。

数据库更程序更新的结构变动及数据更新,类似处理。

提交SQTT测试需要准备数据或更新结构的,暂时先写入测试请求中,由SQTT同志MAIL(注明测试请求表单链接即可)通过数据库操作员修改数据库。待内部网TEAM增加新的表单后,测试请求分开提交。
十四、 数据库设计流程
在新项目设计阶段会议,应有DBA参加。在SCHEMA确定以后方可开始编码。


缩写字列表:
payment pymt
my trade activity mta

特殊字列表:
ACCESS DECIMAL INITIAL ON START
ADD NOT INSERT ONLINE SUCCESSFUL
ALL DEFAULT INTEGER OPTION SYNONYM
ALTER DELETE INTERSECT OR SYSDATE
AND DESC INTO ORDER TABLE
ANY DISTINCT IS PCTFREE THEN
AS DROP LEVEL PRIOR TO
ASC ELSE LIKE PRIVILEGES TRIGGER
AUDIT EXCLUSIVE LOCK PUBLIC UID
BETWEEN EXISTS LONG RAW UNION
BY FILE MAXEXTENTS RENAME UNIQUE
FROM FLOAT MINUS RESOURCE UPDATE
CHAR FOR MLSLABEL REVOKE USER
CHECK SHARE MODE ROW VALIDATE
CLUSTER GRANT MODIFY ROWID VALUES
COLUMN GROUP NOAUDIT ROWNUM VARCHAR
COMMENT HAVING NOCOMPRESS ROWS VARCHAR2
COMPRESS IDENTIFIED NOWAIT SELECT VIEW
CONNECT IMMEDIATE NULL SESSION WHENEVER
CREATE IN NUMBER SET WHERE
CURRENT INCREMENT OF SIZE WITH
DATE INDEX OFFLINE SMALLINT

CHAR VARHCAR VARCHAR2 NUMBER DATE LONG
CLOB BLOB BFILE
INTEGER DECIMAL
SUM COUNT GROUPING AVERAGE
TYPE


only
供参考,欢迎大家讨论


 

技术 PL/SQL

应遵循的PL/SQL编码规则

作者:Steven Feuerstein

提高编写PL/SQL代码数量及质量的四个简单易行指导方针

我从1990年就开始编写PL/SQL代码。这意味着我已经编写了几万行的软件代码,但我确信,其中的绝大多数代码都非常拙劣,而且难以维护。

幸运地是,我发现找到并遵循编写出更好代码的新方法还为时不晚。就是在去年,我的代码质量有了显著改进;这些改进主要是由于制定了一些简单的规则,并像纪律一样加以遵守。

本文为PL/SQL新手及有经验的开发人员提出了四条建议;遵守其中任何一条,你的代码质量都会有提高。这四点建议都采纳,你可能会惊奇地猛然发现:你竟然是一个非常好的程序员,要远远超乎你的想象。

所有工作都独自完成

我们很少有人是孤立工作的;大多数PL/SQL开发工作是在相对较大的机构中进行的。但我们基本上还是在自己的小隔间里用自己的设备独自工作。几乎没有PL/SQL开发小组进行正规的代码复查或系统测试。

我不可能通过这篇文章改变你们开发小组的基本状态。因此,我仔细地选取出以下几点建议。实施其中任何一点并不需征得管理人员同意。不论你的小组是大是小,都不必让其中的每个人都赞同这些编码规则。你只需按以下建议来改变你的本人的编码方式:

1. 严格遵循命名约定,好像它们就是你的生命支柱。
2.
戒除编写SQL的嗜好:编写的SQL越少越好。
3.
使执行部分短小:告别"意大利面条式的代码"
4.
找一位伙伴:非常赞同找个人来监督你的工作。

1. 遵循命名约定

如果你建立并严格遵循一套命名约定,特别是对于应用程序组件的,你就可以节省很多时间。

当然,遵循命名约定的想法并没有什么新意,你可能已经听烦了。所以我并不提出什么宏伟的命名计划,而是给出一些非常具体而明确的约定,然后证明这些约定会多么有用。

前几个月我一直在为PL/SQL开发人员设计、构建一种新工具。它名为Swyg(可以在www.swyg.com中找到),可以帮助程序员完成代码的生成、测试及重用的工作。它具有几个独特的组件。我为每个组件指定了一个由两个字母组成的缩写名称,如下所示:

SF-Swyg的基础部件
SM-Swyg的元数据
SG-Swyg的生成程序
SL-Swyg的代码库
ST-Swyg的单元测试

于是,我便遵循1中的命名约定,同时使用这些缩写。遵循这些约定有什么好处呢?一般来讲,如果我要求一致的命名规则,我就可以更流畅更高效地编写代码。

明确地说,这些约定具有可预测性,意思是说我编写的SQL程序能生成有用的脚本。例如,通过使用1中的约定,可以生成Swyg中所有基础包的安装脚本。执行这些工作的SQL*Plus脚本如清单1所示。这类脚本非常有用,因为它意味着我不必手动维护安装脚本。当我向Swyg方案中增加另一个表,并生成一组相关包时,我只要运行我的脚本,更新后的安装脚本便会跳出来。

2. 戒除编写SQL的嗜好

编写的SQL越少越好,这似乎与我们的直觉不太一致。对于PL/SQL开发人员来说,这是一个奇特的建议,因为PL/SQL的主要优点之一就是可以毫不费力地在代码中编写SQL语句。不过,这种简易性也是这种语言的一个致命的弱点。

可以将纯粹的SQL语句直接置于PL/SQL代码中,而无需JDBCODBC之类的中间层。因此,无论何时何地,PL/SQL开发人员只要需要SQL语句,他们通常就会向其应用程序代码中嵌入SQL语句。那么这样做有什么问题吗?

PL/SQL代码中到处使用SQL语句必然会导致以下后果:

  • 尽管实际表现不同,但同一逻辑语句仍会出现重复,从而导致过多的语法分析,且难于优化应用程序的性能。
  • 暴露商务规则和方案。这直接在SQL语句中包含了执行商务规则的逻辑。这些规则总在变化,所以应用程序的维护成本会急剧增加。

当然,你要编写的每一个PL/SQL应用程序几乎都是基于基础表和视图的。你需要执行SQL语句。问题不在于是否执行,而是何时执行、如何执行。

如果你对数据结构进行封装,或者将它们隐藏于一个PL/SQL代码层(通常是一个代码包)之后,那么你的应用程序将会更健壮,而且你还会发现创建和维护变得更易多了。

我们来看一个简单的例子。 假定我需要编写一个处理某员工工作的程序。第一件事是获取该员工的全名,定义为"姓名逗号(,)姓";然后我可以进行详细分析。清单2给出了这种情况下我很可能要编写的这类代码的一个示例。

一切似乎都是这么简单和直接;这些代码可能会有什么错误呢?实际上真是非常糟糕。最主要的是我暴露了一个商务规则:全名的结构。我可能要花费数小时来对此代码及其所基于的应用程序进行测试。但就在它刚刚投入使用时,我才知道客户会不断地打电话告诉我,实际上,他们的全名应该表示为"名空格姓"

现在怎么办?搜索所有位于引号内的单个逗号?

现实的解决方案是使用隐藏所有细节、只提供一组预定义、预测试及预优化并能完成所有任务的程序包。清单3为基于封装代码重新编写的process_employee过程。hr_employee_tp包提供了用于定义保存姓名的局部变量的类型;hr_employee_rp包含有基于一种商务规则而返回全名的函数。

将显示PL/SQL语句灌入SQL代码很容易,同样,谈论封装这些语句是如何重要也不费劲。但另一方面,编写执行封装任务的代码却具有挑战性;甚至是不现实的。生成这些包或许更有意义。

几年前,我曾帮助构建这样一个生成程序。该程序段为PL/Generator,现在由Quest Software公司拥有,PL/SQL开发社区可以免费使用。你可以从我的网站www.StevenFeuerstein.com/puter/gencentral.htm下载。要知道,其封装体系结构与我在前面所概括的约定不同。PL/Generator创建了一个单独的包,它包含了一个表的类型、查询和变化逻辑的全部内容。

当你不再编写太多的SQL,而是调用执行SQL的程序时,无论你是生成还是编写自己的定制封装,你的应用程序都会受益匪浅。

3. 使执行部分短小

面对现实吧:总是与我们的判断和最新的一系列新年决议相左,我们必须停止编写意大利面条式的代码:庞大而冗长,人们实际上不可能理解它们,更不用说维护或升级了。怎样才能避免"意大利面条"?

实际上,答案很简单:决不允许执行部分超过5060行。这种大小使你能在一页纸或一个屏幕上查看该代码块的整个逻辑结构,这也意味着你可以真实地领会该程序的意图,而且完全凭直觉就能理解它。

你可能非常同意上述观点,但同时又嘲笑我的建议:程序代码永远不超过50行。没错,你应当嘲笑,因为这当然是不可能的。毫无疑问,你需要超过50行的可执行代码;问题是你把这些代码放在哪,以及你怎样加以组织。

如果采取以下做法,你的确能够应对各种复杂的要求,并把代码限制在50行以内:

  • 将所有的商务规则和离散逻辑块置于其自已的程序(通常是函数)中,从而在任何可能的时候慎重地重用代码。
  • 尽量使用在程序的声明部分定义的局部模块、过程和函数。

假定我在编制一个呼叫中心应用程序。我需要编写一个程序,它要满足下面的要求:

"对于特定部门的每个员工,将其工作量(分派给该员工的呼叫次数)同该部门员工的平均工作量进行比较。如果某员工的工作量低于平均工作量,便将下一待处理呼叫分派给此人,并基于这种情况安排约定。"

我从以前的工作中获悉:我的朋友Claudia已经编写了一个分析包,它会返回工作量方面的信息。但是分派待处理呼叫和安排约定都是全新的工作,需求文档的其余部分对此进行了详细说明。

最初我想把这15页的内容全都看完,但我没有那样做。我使用了一种称为"逐步求精法""由顶向下设计"的技术,并先编写了清单4中的代码来实现该程序。

下面给出了清单4中最关键代码行的解释;由该程序(紧凑的执行部分)的最后开始,向上进行。这似乎有悖于直觉,但这的确是通读用逐步求精法编写的程序的最好方式。

2230行。用一个游标FOR循环(cursor FOR loop)来对指定部门的所有员工进行迭代处理。在第2425行,利用分析包中的程序判定当前的员工是否工作量不足。在第2728行,调用三个程序:assign_next_open_caseschedule_casenext_appointment。我还不知道怎样实现这些程序,但我知道它们通过其名称和参数表表达了需要事先完成的工作。

1019行。为第2728行中的三个程序创建"stub",也就是占位程序。注意,它们是局部模块,在assign_workload中进行定义,且不能从其他任何程序调用。

58行。定义一个游标,以获得指定部门的所有员工。现在可以设法编译此代码。

对这样一个小程序成功完成编译好像是个小胜利,也的确如此。完成正确编译,然后是简单测试,然后增加一点代码,再进行正确编译,以此类推,诸如此类的小胜利缔造出构造精良的程序,而且会非常满意。

我还可以验证该分析程序是有效的,并且找出了要分派的任务适当雇员。这些工作全部完成后,我将从三个程序中挑出一个,比如assign_next_open_case,进行下一步或下一级别的精细设计。我要阅读该任务的文档,并在assign_next_open_case里编写一个简短的执行部分,它可反映该任务的概况。

很快,我的局部过程有了它自己的局部过程和函数,但在该过程的每一步,我的代码都很短、可读、易于测试、可根据需要进行调整。

4. 找一位好伙伴

计算机并不会编程,人才会。

有多少次你弯着腰、驼着背坐在计算机前,因无法找出代码中的错误而感到非常郁闷?先是几分钟过去了,接着又过了几小时。最后,对自己都厌烦了,感到非常失败,你把头伸出你的小隔间并请朋友过来帮你看一看。

通常会有下面三种情况之一出现:

  • 当你的朋友从她的椅子上站起来时,一切都在瞬间变得非常清楚。
  • 你的朋友瞥了一眼屏幕,马上就指出了问题所在。
  • 你的朋友不负责该系统中你所做的部分,所以你必须说明你的程序在干什么。当你逐步讲解逻辑时,引起错误的问题所在会突然暴露在你面前。

事实就是自己很难调试自己的代码,因为你自己对它太投入、太专注了。

下一步

阅读
Oracle数据库10g的更多信息
oracle.com/database

Feuerstein的更多文章
otn.oracle.com/oramag/webcolumns/2003


这个问题最好的解决办法是由开发经理创造这样一种文化:各种想法是共享的、不懂是可以原谅的并不会受到处罚、定期进行建设性的代码评审。不幸的是,这些文化上的改变是难以实现的。

与此同时,我建议在帮助改变你所在小组的文化的过程中你应起带头作用。找到另一位开发人员,最好比你经验丰富,并建立一种"伙伴"关系:在出现问题时,他可以充当你的参谋,当然,你也可以充当他的参谋。事前达成共识:不知道所有问题的答案并没有什么不对。

然后为你自己制定一条简单的规则:不要为一个错误苦思冥想超过半个小时。30分钟过去后,把你的伙伴叫过来,让人类心理学为你服务,而不是跟你作对。

获得一种新工作方式的四个步骤

本文为你提供了可以采取的用于改变你的编程体验四个步骤,而无须投资新的工具或改变整个小组的工作流程。这四步甚至可以不全部遵循,只要遵守一步都会让你受益。

Steven Feuerstein (steven@stevenfeuerstein.com) PL/SQL语言方面的一位权威人士。Feuerstein撰写了9本有关PL/SQL (全部由O'Reilly & Associates出版公司出版)的书籍,其中包括《Oracle PL/SQL最佳实践(Oracle PL/SQL Best Practices)》和《Oracle PL/SQL编程(Oracle PL/SQL Programming)》。他还是Quest Software公司的资深技术顾问。

对象

名称结构

注释

生成(DDL)文件

<abbrev>_<entity>

表名,如SM_TASK,用于在普通的Mentat组件中定义的任务。

<abbrev>_<entity>.tab

主键列

id

标准是:(几乎)每个表都包含一个按一个序列生成的id列。对于交叉表等有一些例外。

N/A

用于生成主键的序列

<abbrev>_<entity>_seq

用于一个表主键的序列名,如SG_SCRIPT_SEQ,它为Mentat产生脚本表生成一个新主键。

<abbrev>_<entity>.seq

查询封装包

<abbrev>_<entity>_qp

包含用以在基础表(如SL_SOURCE_QP)中检索数据的标准API,它有助于在Mentat可重用库中查询各元素的源代码。

说明:<abbrev>_<entity>_qp.pks
主体:<abbrev>_<entity>_qp.pkb

改变封装包

<abbrev>_<entity>_cp

包含用以改变(INSERTUPDATEDELETE)某基础表(如ST_UNITTEST_CP)中的数据的标准API,它使我能够维护单元测试定义。

说明:<abbrev>_<entity>_cp.pkb
主体:<abbrev>_<entity>_cp.pks

类型封装包

<abbrev>_<entity>_tp

包含用于指定表(如SG_GEN_RUN_TP)的预定义类型--包括集合、REF CURSORS、记录。

说明:<abbrev>_<entity>_tp.pks
主体:NA (type definitions do not need a package body)

规则封装包

<abbrev>_<entity>_rp

包含程序,通常是函数,它隐藏了关系到该实体的商务规则的细节。

说明:<abbrev>_<entity>_rp.pks
主体:<abbrev>_<entity>_rp.pkb

其他物件包

<abbrev>_<entity>_xp

包含特定实体的自定义逻辑。

说明:<abbrev>_<entity>_xp.pks
主体:<abbrev>_<entity>_xp.pkb

 

关键字

  • <abbrev>是由两个字母组成的缩写。对于Swyg,它可以是SFSMSGSLST
  • <entity>是商务实体名,如TASK用于定义某人要完成任务列表;SCRIPT用于代码生成模板;等等。

 

 

原创粉丝点击