数据库设计的艺术

一、数据库设计简介

1.1为什么要进行数据库设计

优良的设计 糟糕的设计
减少数据冗余 存在大量数据冗余
避免数据维护异常 存在数据插入、更新,删除异常
节省存储空间 浪费大量的存储空间
高效的访问 访问数据低效

1.2 数据库设计简介

1.2.1 数据库设计的过程(六个阶段)

  1. 需求分析阶段

准确了解与分析用户需求(包括数据与处理)
是整个设计过程的基础,是最困难、最耗费时间的一步

  1. 概念结构设计阶段

是整个数据库设计的关键
通过对用户需求进行综合、归纳与抽象,形成一个独立于具体DBMS的概念模型

  1. 逻辑结构设计阶段

将概念结构转换为某个DBMS所支持的数据模型
   对其进行优化

  1. 数据库物理设计阶段

为逻辑数据模型选取一个最适合应用环境的物理结构(包括存储结构和存取方法)

  1. 数据库实施阶段

运用DBMS提供的数据语言、工具及宿主语言,根据逻辑设计和物理设计的结果
建立数据库,编制与调试应用程序,组织数据入库,并进行试运行

  1. 数据库运行和维护阶段

数据库应用系统经过试运行后即可投入正式运行。
在数据库系统运行过程中必须不断地对其进行评价、调整与修改

1.2.2 设计特点

在设计过程中把数据库的设计和对数据库中数据处理的设计紧密结合起来将这两个方面的需求分析、抽象、设计、实现在各个阶段同时进行,相互参照,相互补充,以完善两方面的设计。

1.3三大范式

通俗地理解三个范式,对于数据库设计大有好处。在数据库设计中,为了更好地应用三个范式,就必须通俗地理解三个范式(通俗地理解是够用的理解,并不是最科学最准确的理解):
第一范式:1NF是对属性的原子性约束,要求属性具有原子性,不可再分解;
第二范式:2NF是对记录的惟一性约束,要求记录有惟一标识,即实体的惟一性;
第三范式:3NF是对字段冗余性的约束,即任何字段不能由其他字段派生出来,它要求字段没有冗余.
没有冗余的数据库设计可以做到。但是,没有冗余的数据库未必是最好的数据库,有时为了提高运行效率,就必须降低范式标准,适当保留冗余数据。具体做法是:在概念数据模型设计时遵守第三范式,降低范式标准的工作放到物理数据模型设计时考虑。降低范式就是增加字段,允许冗余。

1.4 数据库选型

CA数据库满足数据的一致性和高可用性,但没有可扩展性,不考虑分区容忍性,对应的数据库就是普通的关系型数据库RDBMS,如MySQL、Oracle的单节点。

CP数据库考虑的是一致性和分区容错性,这种数据库对分布式系统内的通信要求比较高,因为要保持数据一致,就需要做大量的交互。
AP数据库考虑的是实用性和分区容忍性,即外部访问数据,可以更快的得到回应,例如博客系统等。

二、使用技巧

  1. 设计数据库之前(需求分析阶段)
  1. 理解客户需求,询问用户如何看待未来需求变化。让客户解释其需求,而且随着开发的继续,还要经常询问客户保证其需求仍然在开发的目的之中。
  2. 了解企业业务可以在以后的开发阶段节约大量的时间。
  3. 重视输入输出。
     在定义数据库表和字段需求(输入)时,首先应检查现有的或者已经设计出的报表、查询和视图(输出)以决定为了支持这些输出哪些是必要的表和字段。
     举例:假如客户需要一个报表按照邮政编码排序、分段和求和,你要保证其中包括了单独的邮政编码字段而不要把邮政编码糅进地址字段里。
  4. 创建数据字典和ER 图表
      ER 图表和数据字典可以让任何了解数据库的人都明确如何从数据库中获得数据。ER图对表明表之间关系很有用,而数据字典则说明了每个字段的用途以及任何可能存在的别名。对SQL 表达式的文档化来说这是完全必要的。
  5. 定义标准的对象命名规范
      数据库各种对象的命名必须规范。
  1. 表和字段的设计(数据库逻辑设计)

表设计原则
  1) 标准化和规范化
  数据的标准化有助于消除数据库中的数据冗余。标准化有好几种形式,但Third Normal Form(3NF)通常被认为在性能、扩展性和数据完整性方面达到了最好平衡。简单来说,遵守3NF 标准的数据库的表设计原则是:“One Fact in One Place”即某个表只包括其本身基本的属性,当不是它们本身所具有的属性时需进行分解。表之间的关系通过外键相连接。它具有以下特点:有一组表专门存放通过键连接起来的关联数据。
  举例:某个存放客户及其有关定单的3NF 数据库就可能有两个表:Customer 和Order。Order 表不包含定单关联客户的任何信息,但表内会存放一个键值,该键指向Customer 表里包含该客户信息的那一行。
  事实上,为了效率的缘故,对表不进行标准化有时也是必要的。
  2) 数据驱动
  采用数据驱动而非硬编码的方式,许多策略变更和维护都会方便得多,大大增强系统的灵活性和扩展性。
  举例,假如用户界面要访问外部数据源(文件、XML 文档、其他数据库等),不妨把相应的连接和路径信息存储在用户界面支持表里。还有,如果用户界面执行工作流之类的任务(发送邮件、打印信笺、修改记录状态等),那么产生工作流的数据也可以存放在数据库里。角色权限管理也可以通过数据驱动来完成。事实上,如果过程是数据驱动的,你就可以把相当大的责任推给用户,由用户来维护自己的工作流过程。
  3) 考虑各种变化
  在设计数据库的时候考虑到哪些数据字段将来可能会发生变更。
  举例,姓氏就是如此(注意是西方人的姓氏,比如女性结婚后从夫姓等)。所以,在建立系统存储客户信息时,在单独的一个数据表里存储姓氏字段,而且还附加起始日和终止日等字段,这样就可以跟踪这一数据条目的变化。
  字段设计原则
  4) 每个表中都应该添加的3 个有用的字段
dRecordCreationDate,在VB 下默认是Now(),而在SQL Server   • 下默认为GETDATE()
sRecordCreator,在SQL Server 下默认为NOT NULL DEFAULT   • USER
nRecordVersion,记录的版本标记;有助于准确说明记录中出现null 数据或者丢失数据的原因   •
  5) 对地址和电话采用多个字段
  描述街道地址就短短一行记录是不够的。Address_Line1、Address_Line2 和Address_Line3 可以提供更大的灵活性。还有,电话号码和邮件地址最好拥有自己的数据表,其间具有自身的类型和标记类别。
  6) 使用角色实体定义属于某类别的列
  在需要对属于特定类别或者具有特定角色的事物做定义时,可以用角色实体来创建特定的时间关联关系,从而可以实现自我文档化。
  举例:用PERSON 实体和PERSON_TYPE 实体来描述人员。比方说,当John Smith, Engineer 提升为John Smith, Director 乃至最后爬到John Smith, CIO 的高位,而所有你要做的不过是改变两个表PERSON 和PERSON_TYPE 之间关系的键值,同时增加一个日期/时间字段来知道变化是何时发生的。这样,你的PERSON_TYPE 表就包含了所有PERSON 的可能类型,比如Associate、Engineer、Director、CIO 或者CEO 等。还有个替代办法就是改变PERSON 记录来反映新头衔的变化,不过这样一来在时间上无法跟踪个人所处位置的具体时间。
  7) 选择数字类型和文本类型尽量充足
  在SQL 中使用smallint 和tinyint 类型要特别小心。比如,假如想看看月销售总额,总额字段类型是smallint,那么,如果总额超过了$32,767 就不能进行计算操作了。
  而ID 类型的文本字段,比如客户ID 或定单号等等都应该设置得比一般想象更大。假设客户ID 为10 位数长。那你应该把数据库表字段的长度设为12 或者13 个字符长。但这额外占据的空间却无需将来重构整个数据库就可以实现数据库规模的增长了。

三、数据库之父Codd的12条法则

1.信息法则
关系数据库中的所有信息都用唯一的一种方式表示——表中的值。
2.保证访问法则
依靠表名、主键值和列名的组合,保证能访问每个数据项。
3.空值的系统化处理
支持空值(NULL),以系统化的方式处理空值,空值不依赖于数据类型。
4.基于关系模型的动态联机目录
数据库的描述应该是自描述的,在逻辑级别上和普通数据采用同样的表示方式,即数据库必须含有描述该数据库结构的系统表或者数据库描述信息应该包含在用户可以访问的表中。
5.统一的数据子语言法则
一个关系数据库系统可以支持几种语言和多种终端使用方式,但必须至少有一种语言,它的语句能够一某种定义良好的语法表示为字符串,并能全面地支持以下所有规则:数据定义、视图定义、数据操作、约束、授权以及事务。(这种语言就是SQL)
6.视图更新法则
所有理论上可以更新的视图也可以由系统更新。
7.高级的插入、更新和删除操作
把一个基础关系或派生关系作为单个操作对象处理的能力不仅适应于数据的检索,还适用于数据的插入、修改个删除,即在插入、修改和删除操作中数据行被视作集合。
8.数据的物理独立性
不管数据库的数据在存储表示或访问方式上怎么变化,应用程序和终端活动都保持着逻辑上的不变性。
9.数据的逻辑独立性
当对表做了理论上不会损害信息的改变时,应用程序和终端活动都会保持逻辑上的不变性。
10.数据完整性的独立性
专用于某个关系型数据库的完整性约束必须可以用关系数据库子语言定义,而且可以存储在数据目录中,而非程序中。
11.分布独立性
不管数据在物理是否分布式存储,或者任何时候改变分布策略,RDBMS的数据操纵子语言必须能使应用程序和终端活动保持逻辑上的不变性。
12.非破坏性法则
如果一个关系数据库系统支持某种低级(一次处理单个记录)语言,那么这个低级语言不能违反或绕过更高级语言(一次处理多个记录)规定的完整性法则或约束,即用户不能以任何方式违反数据库的约束。

四、其他

  • 降低对数据库功能的依赖

功能应该由程序实现,而非DB实现。原因在于,如果功能由DB实现时,一旦更换的DBMS不如之前的系统强大,不能实现某些功能,这时我们将不得不去修改代码。所以,为了杜绝此类情况的发生,功能应该有程序实现,数据库仅仅负责数据的存储,以达到最低的耦合。

  • 定义实体关系的原则

当定义一个实体与其他实体之间的关系时,需要考量如下:
牵涉到的实体 识别出关系所涉及的所有实体。
所有权 考虑一个实体“拥有”另一个实体的情况。
基数 考量一个实体的实例和另一个实体实例关联的数量

你可能感兴趣的:(数据库领域)