一个优秀的数据库设计,应该是满足需求的前提下,实现性能最优的综合考虑,因此,数据库表的设计都应经过 2 个阶段:逻辑设计阶段(将需求转化为数据库表达的方式),物理设计阶段(对逻辑设计的结果物理调优设计)。
1.表规范
1.1 逻辑设计方法及规范
一个优秀的数据库设计,应该是满足需求的前提下,实现性能最优的综合考虑,因此,数据库表的设计都应经过 2 个阶段:逻辑设计阶段(将需求转化为数据库表达的方式),物理设计阶段(对逻辑设计的结果物理调优设计)。
1.1.1 采用 ER 模型进行逻辑设计
实体关系模型(ER 模型,以下简称 ER 模型)是人们认识客观世界的一种方法、工具。ER 模型的设计过程,基本上是两大步:
l 先设计实体类型(此时不要涉及到“联系”);
l 再设计联系类型(考虑实体间的联系)。
具体设计时,有时“实体”与“联系”两者之间的界线是模糊的。数据库设计者的任务就是要把现实世界中的数据以及数据间的联系抽象出来,用“实体”与“联系”来表示。E-R 模型还描述了数据库对其内容必须遵守的某些约束,一个重要概念是映射基数,它表示通过某个联系集与另外一个实体的关联的实体数目,包括:一对一,一对多,多对一,多对多。另外, ER 模型应该充分反映用户需求,ER 模型要得到用户的认可才能确定下来。
建议采用主流的模型设计软件工具 PowerDesigner,ERWin 等进行数据库设计。
1.1.2 首先遵循范式设计
在设计前,要考虑表的规范化级别,即要求所有的关系模式都达到第几范式。由于函数依赖是现实环境中最重要的、最大量的数据依赖,一般提出 3NF 或 BCNF 的要求就足够了。简单来说,第三范式以上的设计消除了字段的冗余,能有效避免出现数据变化时容易产生的不一致的情况,设计范式定义如下:
第一范式(1NF):数据库表中的字段都是单一属性的,不可再
分。
第二范式(2NF):数据库表中不存在非关键字段对任一候选关键字段的部分函数依赖(部分函数依赖指的是存在组合关键字中的某些字段决定非关键字段的情况),也即所有非关键字段都完全依赖于任意一组候选关键字。
实体表中一般不会出现违反 2NF 的情况,因为都是“一个”主键列,而关系表是两个以上列的“复合”主键,故而关系表容易出现违反 2NF 的情况。
第三范式(3NF):在第二范式的基础上,数据表中如果不存在非关键字段对任一候选关键字段的传递函数依赖则符合第三范式。所谓传递函数依赖,指的是如果存在"A → B → C"的决定关系,则 C 传递函数依赖于 A。因此,满足第三范式的数据库表应该不存在如下依赖关系:关键字段 → 非关键字段 x → 非关键字段 y
违反 3NF 的情况,绝大多数是在含有外键的表中
鲍依斯-科得范式(BCNF):在第三范式的基础上,数据库表中如果不存在任何字段对任一候选关键字段的传递函数依赖则符合 BCNF 范式。
当处理表间的关联约束所付出的代价(常常是使用性上的代价)超过了保证不会出现修改、删除、更改异常所付出的代价,并且数据冗余也不是主要的问题时,表设计可以不符合四个范式。四个范式确保了不会出现异常,但也可能由此导致过于纯洁的设计,使得表结构难于使用,所以在设计时需要进行综合判断,但首先确保符合四个范式,然后再进行精化修正是刚刚进入数据库设计领域时可以采用的最好办法。
1.1.3 根据实际需要进行反规范化设计
数据库规范化设计目前占数据库设计主导地位,规范化设计达到了数据存储空间最佳利用和控制数据冗余,但是也带来了查询性能的降低,因此在适当的条件下,对数据库进行反规范化设计也是必要的。
反规范化设计通过增加数据冗余,数据分片等策略来改进原有规范设计,以达到改善数据库性能的目的。
反规范化设计的几个原则:
1)确信对系统的逻辑设计有全面的了解
使系统设计人员清楚,当改变数据库设计时,会对其它部分造成哪些影响。
2)尽量采取索引、数据存储等技术来提升数据库性能
分析系统的数据量,对于数据量不大,响应时间不高的尽量通过数据库本身技术来提升性能。
3)数据完整性维护
使用反规范带来最大的问题使数据完整性,在程序设计中充分考虑到数据库事务的处理,增删改查保证数据库操作一致性;完整性约束还可以通过批处理及触发器实现(不建议)。
反规范化设计的几个方法
1) 增加冗余列
在表中增加经常需要访问而频繁访问其它表的列,导致多个表有相同的列,即冗余列。常用在两个地方:(1)关系表中的冗余:在关系表中增加相关实体表的相关属性,以达到关连查询时减少表的关联数量的目的(2)层次关系中的冗余:在多层次的子父表关系中,将父表的属性存储在“子表”或者“孙子表”或者“重孙表”中。
2) 数据分片
主要有三种方式:水平分片,垂直分片,混合分片
水平分片:是指按一定规则,将数据库所有行划分成若干不相交的子集,即多个表。在数据库比较庞大的情况下,通常在以下几个情况下使用:一是数据访问频率差别极大时候,可以将经常访问的数据放在一个表中,不常访问的放在另外一个表,比如历史表;一个是数据表中数据本身有独立性,如状态表中状态字段。
垂直分片:是指把一个数据库属性集分成若干子集,在每个子集上做投影运算,每个投影称为垂直分片。比如可以将一个表中主键和经常访问的列放在一个表中,主键和不常访问的放在另一表中。优点是查询是可以直接查找经常访问的表,减少了 IO 操作,缺点是查询所有数据时需要多表连接。
混合分片:实际应用中,根据需要将水平分片及垂直分片结合使用的做法。
2.1 基本规范
2.1.1 长度规范
凡是需要命名的对象其标识符均不能超过 30 个字符,也即: Oracle 中的表名、字段名,函数名,过程名,触发器名,序列名,视图名的长度均不能超过 30 个字符;
2.1.2 构成规范
数据库各种名称必须以字母开头,但严禁使用 SYS 开头;名称只能含有字母,数字和下划线“_”三类字符,“_”用于间隔名称中的各语义字段;不要使用 DUAL 作表名;
2.1.3 大小写规范
构成 Oracle 数据库中的各种名称(表明,字段名,过程名,视图名等等)的所有字符,必须使用大写,也就是不能在脚本中,对任何名称添加双引号“”来设定字符的大小写形式,只要不采用“”限制, Oracle 自动会将各名称转化成大写。
2.1.4 主键规范
主键设计应遵循以下规范:1、除临时表和外部表,以及流水表,日志表外,其他表都要建立主键;2、主键不能使用含有实际语义的列,应该增加一个 xx_id 字段做主键,类型为 number,取值来自序列sequence;3、对于 500 万以上的表,请数据组参与设计实施,采用先建唯一索引再添加主键约束的方式来创建主键;




