数据库设计规范.docx
《数据库设计规范.docx》由会员分享,可在线阅读,更多相关《数据库设计规范.docx(39页珍藏版)》请在冰点文库上搜索。
数据库设计规范
数据库设计规范
文档属性
属性
内容
客户名称
项目名称
文档主题
文档副标题
文档版本
文档日期
文档状态
作者
1前言
为明确公司项目中数据库逻辑设计及物理设计的内容和流程,特制定本规范,供数据库设计、开发及维护人员参考。
本规范属于参考性规范,由DBA组制定。
2数据库的设计方法及流程
2.1设计方法
数据库设计方法目前可分为四类:
直观设计法、规范设计法、计算机辅助设计法和自动化设计法。
其中,新奥尔良法是目前公认的比较完整和权威的一种规范设计法。
新奥尔良法将数据库设计分成需求分析(分析用户需求)、概念设计(信息分析和定义)、逻辑设计(设计实现)和物理设计(物理数据库设计)。
目前,常用的规范设计方法大多起源于新奥尔良法,并在设计的每一阶段采用一些辅助方法来具体实现。
以下是两种常用的规范设计方法:
一、基于E-R模型的数据库设计方法。
该方法是由P.P.S.chen于1976年提出的数据库设计方法,其基本思想是在需求分析的基础上,用E-R(实体—联系)图构造一个反映现实世界实体之间联系的企业模式,然后再将此企业模式转换成基于某一特定的DBMS的概念模式。
二、基于3NF的数据库设计方法。
该方法是由S·Atre提出的结构化设计方法,其基本思想是在需求分析的基础上,确定数据库模式中的全部属性和属性间的依赖关系,将它们组织在一个单一的关系模式中,然后再分析模式中不符合3NF的约束条件,将其进行投影分解,规范成若干个3NF关系模式的集合。
其具体设计步骤分为五个阶段:
a)设计企业模式,利用规范化得到的3NF关系模式画出企业模式;
b)设计数据库的概念模式,把企业模式转换成DBMS所能接受的概念模式,并根据概念模式导出各个应用的外模式;
c) 设计数据库的物理模式(存储模式);
d) 对物理模式进行评价;
e) 实现数据库。
2.2设计流程
以规范性设计为例,把数据库设计流程分为以下几个阶段:
A.需求分析阶段:
综合各个用户的应用需求(现实世界的需求)。
B.概念设计阶段:
形成独立于机器和各DBMS产品的概念模式(信息世界模型),用E-R图来描述。
C.逻辑设计阶段:
将E-R图转换成具体的数据库产品支持的数据模型,如关系模型,形成数据库逻辑模式。
然后根据用户处理的要求,安全性的考虑,在基本表的基础上再建立必要的视图(VIEW)形成数据的外模式。
D.物理设计阶段:
根据DBMS特点和处理的需要,进行物理存储安排,设计索引,形成数据库内模式。
E.数据库实施阶段
F.数据库运行与维护阶段
2.2.1需求分析阶段
需求收集和分析,得到数据字典描述的数据需求和数据流图描述的处理需求。
需求分析的重点:
调查、收集与分析用户在数据管理中的信息要求、处理要求、安全性与完整性要求。
需求分析的方法:
调查组织机构情况、各部门的业务活动情况、协助用户明确对新系统的各种要求、确定新系统的边界。
常用的调查方法有:
跟班作业、开调查会、请专人介绍、询问、设计调查表请用户填写、查阅记录。
分析和表达用户需求的方法:
主要包括自顶向下和自底向上两类方法。
采用逐层分解的方式分析系统,并把每一层用数据流图和数据字典描述。
数据流图(DataFlowDiagram,DFD)表达了数据和处理过程的关系。
系统中的数据则借助数据字典(DataDictionary,简称DD)来描述。
2.2.2概念结构设计阶段
概念模型用于信息世界的建模。
概念模型不依赖于某一个DBMS支持的数据模型。
通过对用户需求进行综合、归纳与抽象,形成一个独立于具体DBMS的概念模型,可以用E-R图表示。
概念模型可以转换为计算机上某一DBMS支持的特定数据模型。
概念模型特点:
1)具有较强的语义表达能力,能够方便、直接地表达应用中的各种语义知识。
2)应该简单、清晰、易于用户理解,是用户与数据库设计人员之间进行交流的语言。
2.2.3逻辑设计阶段
将概念结构转换为某个DBMS所支持的数据模型(例如关系模型),并对其进行优化。
将E-R图转换为关系模型实际上就是要将实体、实体的属性和实体之间的联系转化为关系模式,这种转换一般遵循如下原则:
一个实体型转换为一个关系模式,实体的属性就是关系的属性,实体的码就是关系的码。
一个多对多的联系转换为一个关系模式,两个实体的码和联系本身的属性就是关系的属性,两个实体的码就是关系的码。
数据模型的优化,确定数据依赖,消除冗余的联系,确定各关系模式分别属于第几范式。
确定是否要对它们进行合并或分解。
一般来说将关系分解为3NF的标准。
2.2.4物理设计阶段
为逻辑数据模型选取一个最适合应用环境的物理结构(包括存储结构和存取方法)。
根据DBMS特点和处理的需要,进行物理存储安排,设计索引,形成数据库内模式。
2.2.5数据库实施阶段
运用DBMS提供的数据语言(例如SQL)及其宿主语言(例如C),根据逻辑设计和物理设计的结果建立数据库,编制与调试应用程序,组织数据入库,并进行试运行。
数据库实施主要包括以下工作:
用DDL定义数据库结构、组织数据入库、编制与调试应用程序、数据库试运行。
2.2.6数据库运行维护阶段
在数据库系统运行过程中必须不断地对其进行评价、调整与修改。
内容包括:
数据库的转储和恢复、数据库的安全性、完整性控制、数据库性能的监督、分析和改进、数据库的重组织和重构造。
2.2.7建模工具
为加快数据库设计速度,目前有很多数据库辅助工具(CASE工具),如Rational公司的RationalRose,CA公司的Erwin和Bpwin,Sybase公司的PowerDesigner以及Oracle公司的oracleDesigner等。
3数据库设计规范
3.1数据库规范化的五个要求
3.1.1要求一:
表中应该避免可为空的列
虽然表中允许空列,但是,空字段是一种比较特殊的数据类型。
数据库在处理的时候,需要进行特殊的处理。
如此的话,就会增加数据库处理记录的复杂性。
当表中有比较多的空字段时,在同等条件下,数据库处理的性能会降低许多。
所以,虽然在数据库表设计的时候,允许表中具有空字段,但是,我们应该尽量避免。
若确实需要的话,我们可以通过一些折中的方式,来处理这些空字段,让其对数据库性能的影响降低到最少。
一是通过设置默认值的形式,来避免空字段的产生。
二是若一张表中,允许为空的列比较多,接近表全部列数的三分之一。
而且,这些列在大部分情况下,都是可有可无的。
若数据库管理员遇到这种情况,建议另外建立一张副表,以保存这些列。
然后通过关键字把主表跟这张副表关联起来。
将数据存储在两个独立的表中使得主表的设计更为简单,同时也能够满足存储空值信息的需要。
3.1.2要求二:
表不应该有重复的值或者列
如进销存管理中,还需要对客户的联系人进行管理。
而一个客户的联系人可能有多个,为了解决这个问题,有多种实现方式。
若设计不合理的话在,则会导致重复的值或者列。
我们可以这么设计,把客户信息、联系人都放入同一张表中。
为了解决多个联系人的问题,可以设置第一联系人、第一联系人电话、第二联系人、第二联系人电话等等。
若还有第三联系人、第四联系人等等,则往往还需要加入更多的字段。
可是这么设计的话,会产生一系列的问题。
如客户的采购员流动性比较大,在一年内换了六个采购员。
直接修改又不利于追踪。
所以,在数据库设计的时候要尽量避免这种重复的值或者列的产生。
建议,若数据库管理员遇到这种情况,可以改变一下策略。
如把客户联系人另外设置一张表。
然后通过客户ID把供应商信息表跟客户联系人信息表连接起来。
也就是说,尽量将重复的值放置到一张独立的表中进行管理。
然后通过视图或者其他手段把这些独立的表联系起来。
3.1.3要求三:
表中记录应该有一个唯一的标识符
在数据库表设计的时候,数据库管理员应该养成一个好习惯,用一个ID号来唯一的标识行记录,而不要通过名字、编号等字段来对纪录进行区分。
每个表都应该有一个ID列,任何两个记录都不可以共享同一个ID值。
另外,这个ID值最好有数据库来进行自动管理,而不要把这个任务给前台应用程序。
否则的话,很容易产生ID值不统一的情况。
另外,在数据库设计的时候,最好还能够加入行号。
ID号是用户不能够维护的。
但是,行号用户就可以维护。
这是在实际应用程序设计中对ID列的一个有效补充。
3.1.4要求四:
数据库对象要有统一的前缀名
一个比较复杂的应用系统,其对应的数据库表往往以千计。
若让数据库管理员看到对象名就了解这个数据库对象所起的作用,恐怕会比较困难。
而且在数据库对象引用的时候,数据库管理员也会为不能迅速找到所需要的数据库对象而头疼。
建议:
在开发数据库之前,最好能够花一定的时间,去制定一个数据库对象的前缀命名规范。
最常用的是根据前台应用程序的模块来定义后台数据库对象前缀名。
需要注意的是,这个命名规范应该在数据库管理员与前台应用程序开发者之间达成共识,并且严格按照这个命名规范来定义对象名。
其次,表、视图、函数等最好也有统一的前缀。
如视图可以用V为前缀,而函数则可以利用F为前缀。
如此数据库管理员无论是在日常管理还是对象引用的时候,都能够在最短的时间内找到自己所需要的对象。
3.1.5要求五:
尽量只存储单一实体类型的数据
实体类型跟数据类型不是一回事,要注意区分。
如现在有一个图书馆里系统,有图书基本信息、作者信息两个实体对象。
若用户要把这两个实体对象信息放在同一张表中也是可以的。
如可以把表设计成图书名字、图书作者等等。
可是如此设计的话,会给后续的维护带来不少的麻烦。
如当后续有图书出版时,则需要为每次出版的图书增加作者信息,这无疑会增加额外的存储空间,也会增加记录的长度。
而且若作者的情况有所改变,如住址改变了以后,则还需要去更改每本书的记录。
同时,若这个作者的图书从数据库中全部删除之后,这个作者的信息也就荡然无存了。
很明显,这不符合数据库设计规范化的需求。
遇到这种情况时,建议可以把上面这张表分解成三种独立的表,分别为图书基本信息表、作者基本信息表、图书与作者对应表等等。
如此设计以后,以上遇到的所有问题就都引刃而解了。
3.2对象命名规范
3.2.1规则
【规则-1】:
Oracle数据库对象的名字由字母、数字和一些连接符组成。
1、多个单词之间用连接符分开,连接符用“_”字符,不建议使用其他的字符;
2、例如:
存储过程:
sp_create_accbak_table
【规则-2】:
Oracle数据库对象的名字长度不超过30个字符。
1、如果超过30个字符,可以缩写,但一定要采用标准的缩写,常用标准缩写见附件。
如果表或者是字段的名称仅有一个单词,那么建议不使用缩写,而是用完整的单词;
2、例如:
表:
ATP_PARA_CFG
【规则-3】:
在创建数据库对象时,不要使用引号。
1、说明:
Oracle数据库自动转换为大写字符;避免使用系统保留字作为数据库对象的名称。
2、例:
建存储过程SP_SET_PROCESS_STATUS时写法
正确写法:
CREATEORREPLACEPROCEDUREsp_set_process_status
……
endsp_set_process_status;
错误写法:
CREATEORREPLACEPROCEDURE“sp_set_process_status”
……
endsp_set_process_status;
3.2.2表命名规范
表的命名遵循数据库对象命名的一般规则:
【规则-1】:
要求表的命名尽量采用标准的翻译,能准确地表达该表的中文含义,能根据英文猜测到表的用途。
例:
gsm_user用户资料表、user_imei用户IMEI信息。
【规则-2】对于一些特定作用的表,除了遵循普通表命名规范外,增加特定后缀表示。
例:
配置历史表表示为XXX_cfg_his。
3.2.3字段命名规范
字段命名遵循数据库对象命名的一般规则:
【规则-1】:
字段的命名由英文单词(或缩写)和下划线“_”组成,多个单词之间用下划线分开。
例:
user_id、package_code等。
【规则-2】:
要求字段名能表达字段的含义。
例如:
Fail(Fail):
失败记录表
History(His):
历史
Identity(ID):
ID号
【规则-3】:
字段长度,根据业务需要定义字典长度,对字符型字段,尽量用varchar2类型,不要用char、varchar类型。
【规则-4】:
如果相同字段在不同的表中出现,要使用相同的命名,且必须保证他们的类型和长度是相同的。
例:
gsm_user的字段gsm_user_id,和表user_package的字段gsm_user_id,长度和类型一致。
3.2.4索引命名规范
【规则-1】:
IDX_表名缩写_字段名缩写。
例:
CLERK_OPERATING_DETAIL表CHECKOUT_SRL列上的索引命名:
IDX_COD_CHECKOUT_SRL。
【规则-2】:
如果是复合索引,字段名缩写至少要包含复合索引的头两个字段名的缩写。
例如:
CLERK_OPERATING_DETAIL表(OPERATOR_ID,CHECKOUT_SRL)列上的复合索引命名为:
IDX_COD_OPID_CHKSRL;
【规则-3】:
如果是主键索引,以“PKX”为索引前缀。
例:
CLERK_OPERATING_DETAIL表(OPERATING_SRL,CODE_COUNTY)上的主键索引命名为:
PKX_COD_OPSRL_CODECTY。
【规则-4】:
给表增加主键时要显式指定约束的名字,并且要指定usingindextablespace参数。
例:
altertableCLERK_OPERATING_DETAIL
addconstraintPKX_COD_OPSRL_CODECTY--主键约束名,也是索引名
primarykey(OPERATING_SRL,CODE_COUNTY)
usingindextablespace…;
不能写成
altertableCLERK_OPERATING_DETAIL
addprimarykey(OPERATING_SRL,CODE_COUNTY);
如果不显式指定约束名系统将随机分配一个约束名字(同时也是主键索引的名字)
如果不指定usingindextablespace参数,索引会建在该用户默认的表空间上,不利于数据库性能和系统维护。
3.2.5分区命名规范
表名各单词第一个字母的缩写_P<两位数值>
例1:
BILL_ADJUST_SEQ表的分区名为:
BAS_P01~BAS_P13
例2:
按月份分区的分区分区命名:
表名各单词第一个字母的缩写_P(年月),如CLERK_OPERATING_DETAIL表分区名为:
COD_P0507~COD_P0512;
注:
COD是表的简称,0507是指2005年7月的分区。
3.2.6视图/物化视图命名规范
【规则-1】:
视图的命名规范遵循普通表的命名规范,并在视图前加上“v_”前缀,表示是视图。
例:
v_cardinfo。
【规则-2】:
物化视图命名规则:
MV_源表名_源数据库。
例:
mv_gsm_user_11,mv_gsm_user_21,mv_gsm_user_41,分别表示从zwdb1,zwdb2和zwdb4复制过来的gsm_user表的数据。
3.2.7触发器/函数/存储过程命名规范
【规则-1】:
触发器的命名规则:
trg_表名_
说明:
其中表名为触发源表名,ins/upd/del表示insert/update/delete触发器。
例如:
trg_msn_member_del,触发器的含义为:
createorreplacetriggerti_msn_member_del
beforedeleteonmsn_memberforeachrow
declare
……
begin
end
【规则-2】:
存储过程的命名以“sp_”打头
说明:
其他规范遵循普通表的命名规范,要求名字能表达存储过程的用途。
例:
sp_pre_score_modify、sp_create_scp_operation。
【规则-3】:
函数的命名以“fn_”打头
说明:
其他规范遵循普通表的命名规范,要求名字能表达函数的用途。
例:
fn_get_packname、fn_check_brand_package。
3.3数据库编程规范
3.3.1书写规范
【规则-1】:
所有代码统一使用小写字母书写。
例:
createorreplaceproceduresp_check_package(
i_package_codenumber,
i_user_idnumber,
o_flagoutnumber
)is
begin
o_flag:
=0;
endsp_check_package;
/
【规则-2】:
确保变量和参数在类型和长度上与表数据列类型和长度相匹配。
说明:
如果与表数据列宽度不匹配,则当较宽或较大的数据传进来时会产生运行异常。
【规则-3】:
参数和变量的命名符合如下规范:
1、传入参数以“i_”为前缀;
2、传出参数以“o_”为前缀;
3、变量以“v_”为前缀
4、例如:
createorreplaceprocedureSP_GET_GLOBAL(i_operator_idinnumber,
i_session_idinnumber,
o_flagoutnumber)is
v_cityIDvarchar
(2);
v_region_levelnumber
(1);
begin
….
end;
【规则-4】:
程序块中的begin、end独立成行。
【规则-5】:
程序块采用缩进风格书写,保证代码清晰易读,风格一致,缩进格数统一。
例:
……
begin
updateCFG_CDR_REFRESHsetCHANGE_TIME=sysdatewhereCFG_TYPE=5;
ifsql%rowcount=0then
insertintoCFG_CDR_REFRESH(CFG_TYPE,CHANGE_TIME,STATE)
values(5,sysdate,0);
endif;
endtrg_CFG_CITY_HOST_QRY_ALL;
【规则-6】:
不允许把多个语句写在一行中,即一行只写一条语句。
【规则-7】:
同一条语句占用多于一行时,每行的第一个关键字应当左对齐,
例:
select*intov_gsm_userfromgsm_user
wheremsisdn=to_number(trim(i_phone_number))
anduser_city=i_city_id;
【规则-8】:
对于Insert…values和update语句,一行写一个字段,字段后面紧跟注释(注释语句左对齐),values和insert左对齐,左括号和右括号与insert、values左对齐
例:
insertintotable_name
(
user_id, --用户ID,主键
user_name, --用户名
login_name --登录名
)
values
(
v_user_id,
v_user_name,
v_login_name
)
【规则-9】:
相对独立的程序块之间需加空行。
例:
--判断套餐是否可增加成员并获得专网标志
begin
selectuse_date,decode(package_type,1000,1,0)
……
exception
end;
--如果为手机号码
ifi_number_type=0then
begin
……
end;
【规则-10】:
超过110列的语句要分行书写,长表达式应在低优先级操作符处换行,操作符或关键字放在新行之首。
例:
v_exchangeable_score:
=(v_score_phone_score+v_score_bounty_score+v_score_gift_score-v_score_alr_excg_score)
+(v_pre_score_phone_score+v_pre_score_bounty_score-v_pre_score_alr_excg_score)
3.3.2注释规范
【规则-1】:
所有变量定义都要加上注释,说明变量的用途及含义。
例:
createorreplaceproceduresp_sms_zone
as
……
v_citynumber
(2);--监控信息变量
v_dbnumber
(2);--数据库代码
v_Totalnumber(10):
=0;--发送总数
v_Succnumber(10):
=0;--成功数
v_Failnumber(10):
=0;--没有发送数
v_Srlnumber(10);--记录流水
o_flagnumber;--调用sp_send_query_sms返回的标识
……
endsp_sms_zone;
/
【规则-2】:
注释内容要清晰、明了,含义准确,防止注释二义性。
例:
正确:
ret_codeoutinteger,--返回代码(0成功,其它:
错误,参见:
错误代码定义);
错误:
ret_codeoutinteger,--返回代码
【规则-3】:
对存储过程的任何修改,都需要在注释最后添加修改人、修改日期及修改原因等信息。
例:
/*
修改原因:
修改积分兑换和积分转赠
修改人:
***
修改时间:
2006-01-05
*/
【规则-4】:
对程序分支必须书写注释。
例:
--如果为手机号码
ifi_number_type=0then
begin
……
end;
【规则-5】:
在代码的功能、意图层次上进行注释,帮助维护人员理解代码。
例:
caserdm_type1
when1then--积分奖励
......
when2then--扣减(停用)
......
when3then--积分兑换
......
endcase;
【规则-6】:
代码注释应放在描述的代码上方或右方相近位置,不可放在下面。
例:
--查询转出用户的积分信息
SP_SCORE_QUERY(
s_user_id,--用户id
rdm_city_id,--地市id
……
)
【规则-7】:
注释与所描述的内容进行同样的缩排。
例:
--未达到可兑换标准
ifv_score_change_flag=0then
--对于兑换类型为961的,取消1000分门限的限制。
ifrdm_type2=961orrdm_type2=962then
endif;
endif;
【规