数据库设计 Step by Step (1)——扬帆启航
引言:一直在从事数据库开发和设计工作,也看了一些书籍,算是略有心得。很久之前就想针 对关系数据库设计进行整理、总结,但因为种种原因迟迟没有动手,主要还是惰性使然。今天也算是痛下决心开始这项卓绝又令我兴奋的工作。这将是一个系列的文 章,我将以讲座式的口吻展开讨论(个人偷懒,这里的总结直接拿去公司培训新人用)。
系列的第一讲我们先来回答下面几个问题

数据库是大楼的根基
大多数程序员都很急切,在了解基本需求之后希望很快的进入到编码阶段(可能只有产出代码才能反映工作量),对于数据库设计思考得比较少。
这给系统留下了许多隐患。许多软件系统的问题,如:输出错误的数据,性能差或后期维护繁杂等,都与前期数据库设计有着密切的关系。到了这个时候再想修改数据库设计或进行优化等同于推翻重来。
我经常把软件开发比作汽车制造。汽车制造会经过图纸设计,模型制作,样车制造,小批量试生产,最后是批量生产等步骤。整个过程环环相扣,后一过程是 建立在前一过程正确的前提基础之上的。如果在图纸设计阶段发现了一个纰漏,我们可以重新进行图纸设计,如果到了样车制造阶段发现这个错误,那么我们就要把 从图纸设计到样车制造的阶段重来,越到后面发现设计上的问题,所付出的代价越大,修改的难度也越大。
数据库是整个应用的根基,没有坚实的根基,整个应用也就岌岌可危了。
强大的数据库面对不良设计也无能为力
现代数据库管理系统(DBMS)提供了方便的图形化界面工具,通过这些工具可以很方便的创建表、定义列,但我们设计出的结构好吗?
关系数据库有许多非常好的特性,但设计不当会使这些特性部分或完全的丧失。
我们来看看以下几个数据库不良设计造成的场景:
1. 数据一致性的丧失
一个订单管理系统,维护着客户和客户下的订单信息。使用该系统的用户在接到客户修改收货地址的电话后,在系统的客户信息页面把该客户的收货地址进行了修改,但原先该客户的订单还是送错了地址。
2. 数据完整性的丧失
公司战略转移,准备撤出某地区。系统操作人员顺手把该地区的配置信息在系统中进行删除,系统提示删除成功。随后问题就来了,客服人员发现该地区的历史订单页面一打开就出错。
3. 性能的丧失
一个库存管理系统,仓库管理员使用该系统记录每一笔进出货情况,并能查看当前各货物的库存情况。在系统运行几个月后,仓库管理员发现打开当前库存页面变得非常慢,而且整个趋势是越来越慢。
上面这些场景都是由于数据库设计不当造成的,根源包括:设计时引入了冗余字段,没有设计合理的约束,对性能没有进行充足设计等,上面的例子也只是沧海一粟。

数据库平台无关性
我在这个系列博客里讨论的数据库设计不针对任何一个关系数据库产品。无论你使用的是Oracle,SQL Server,Sybase,亦或是开源数据库如:MySQL,SQLite等,都可以用来实践我们这里讨论的设计方法和设计理念,设计是这个系列博文的核心和灵魂。
注:在文中我会选用一个数据库产品来进行演示,大家可以选用自己熟悉的数据库产品来实验。本文最后会给出一些免费数据库产品的链接,大家可以下载学习。
一起学习共同进步
无论你是数据库设计师,应用架构师,软件工程师,数据库管理员(DBA),软件项目经理,软件测试工程师等项目组成员,都能从该系列博文中有所收获。大家一起讨论,共同进步。
内容涉及领域
我对这一系列博文现在的设想是涉及数据库设计的整个过程。从需求分析开始,到数据库建模(概念数据建模),进行范式化,直至转化为SQL语句。

在我们一头扎进数据库设计之前,我们先了解一下除了关系型数据库之外的数据存储方式。
平面文件(Flat File)
包括以.txt和.ini结尾的文件。
eg: 一个.ini文件的内容:
------------------------------------------------------------
[WebSites]
MyBlog=http://www.cnblogs.com/DBFocus
[Directorys]
Image=E:\DBFocus Project\Img
Text=E:\DBFocus Project\Documents
Data=E:\DBFocus Project\DB
------------------------------------------------------------
优点:
文件的存储形式非常简单,普通的编辑器都能对其进行打开、修改
缺点:
无法支持复杂的查询
没有任何验证功能
对平面文件中间的内容进行插入、删除操作其实是重新生成了一个新文件
适用场景:
存放小量,修改不频繁的数据,如应用配置信息
Windows注册表
错误的修改Windows注册表会引起系统的紊乱,故不建议把很多数据存放在注册表中。
Windows注册表为树形结构,存放着一些系统配置信息和应用配置信息。
通过把不同的配置存放在注册表的不同分支上,使得应用程序公共配置信息与用户个人配置信息分离。
eg:某文档版本管理系统,能通过配置与本主机上安装的文件比较器建立关联进行文档比较。这是一个公共配置信息,文件比较器路径可以存放在注册表的HKEY_LOCAL_MACHINE\SOFTWARE分支下。
同时该文档版本管理系统能记录用户最近打开的10个文档路径。这是用户个人配置信息,对于不同的Windows用户最近打开的10个文档可以不同,这些配置信息可存放在注册表的HKEY_CURRENT_USER\Software分支下。
Excel表单(Spreadsheets)
优点:
Excel 非常普及,用户对于Spreadsheet的表现形式非常熟悉
可以进行简单统计,方便出各种图表
缺点:
不适用于许多Spreadsheet之间关系复杂的情况
无法应对复杂查询
数据验证功能弱
适用场景:
数据量不是非常大的办公自动化环境
XML
XML是一种半结构化的数据。相比于超文本标记语言(HTML),其标签是可以自行定义的,即可扩展的。
eg:一个XML文件内容
-----------------------------------------------------
<?xml version=”1.0” encoding=”UTF-8” ?>
<ClassSchedule>
<Class Name=“Psychology” Room=”Field 3”>
<Instructor>Richard Storm</Instructor>
<Students>
<Student>
<FirstName>Ben</FirstName>
<LastName>Breaker</LastName>
</Student>
<Student>
<FirstName>Carol</FirstName>
<LastName>Enflame</LastName>
<NickName>Candy</NickName>
</Student>
</Students>
</Class>
</ClassSchedule>
-----------------------------------------------------
XML文件有几个特点。
首先,XML标签要求严格对应,且不能出现交错的现象。
其次,XML文件必须有一个根节点,该节点包含所有其他元素。
第三,同级别的不同节点内不必包含相同的元素,如上例中第二个学生Carol有一个特别的节点NickName。这个特性使得在某些场景中XML比关系数据库更能应对变化。
优点:
自然的层次型结构
文本内容通过标签是自解释的
通过XSD(XML Schema语言)可以验证XML的结构
有许多辅助型技术如:XPath, XQuery, XSL, XSLT等
一些商业数据库(如Oracle,SQL Server)已支持XML数据的存储与操作
缺点:
数据的冗余信息较多
无法支持复杂的查询
验证功能有限
对XML中间的内容进行插入、删除操作其实是重新生成一个新文件
适用场景:
适合存放数据量不大,具有层次型结构的数据,如树形配置信息
NoSQL数据库
非关系型数据库我接触的不是很多,除了给出一些产品名称之外不做很多展开。园子里已有一些文章,本文最后也给出了链接供大家学习、研究。
1. Key-Value数据库
Redis, Tokyo Cabinet, Flare
2. 面向文档的数据库
MongoDB, CouchDB
3. 面向分布式计算的数据库
Cassandra, Voldemort
这几年NoSQL非常热。我认为NoSQL并不是“银弹”,在某些SNS应用场景中NoSQL显示了其优越性,但在如金融行业等对数据的一致性、完整性、可用性、事务性高要求的场景下,现在的NoSQL就未必适用。我们应充分分析应用的需求,非常谨慎地选择技术和产品。

主要内容回顾
1.数据库设计对于软件项目成功的关键作用
2.本课程与数据库产品无关,核心是设计的理念和方法
3.各种数据存储所适用的场景
参考资料
1. Oracle Database 10g Express Edition
2. SQL Server 2008 R2 Express – Overview
4. NoSQL数据库笔谈
数据库设计 Step by Step (1)——扬帆启航的更多相关文章
- 数据库设计 Step by Step (2)——数据库生命周期
引言:数据库设计 Step by Step (1)得到这么多朋友的关注着实出乎了我的意外.这也坚定了我把这一系列的博文写好的决心.近来工作上的事务比较繁重,加之我期望这个系列的文章能尽可能的系统.完整 ...
- SQL Server 维护计划实现数据库备份(Step by Step)(转)
SQL Server 维护计划实现数据库备份(Step by Step) 一.前言 SQL Server 备份和还原全攻略,里面包括了通过SSMS操作还原各种备份文件的图形指导,SQL Server ...
- e2e 自动化集成测试 架构 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step (三) SqlServer数据库的访问
上一篇文章“e2e 自动化集成测试 架构 京东 商品搜索 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step 二 图片验证码的识别” ...
- enode框架step by step之消息队列的设计思路
enode框架step by step之消息队列的设计思路 enode框架系列step by step文章系列索引: enode框架step by step之开篇 enode框架step by ste ...
- Step by Step
数据库设计Step by Step篇目整理及下载地址 系列篇目 1. 数据库设计 Step by Step (1)——扬帆启航 2. 数据库设计 Step by Step (2)——数据库生命周期 3 ...
- WPF Step By Step 自定义模板
WPF Step By Step 自定义模板 回顾 上一篇,我们简单介绍了几个基本的控件,本节我们将讲解每个控件的样式的自定义和数据模板的自定义,我们会结合项目中的具体的要求和场景来分析,给出我们实现 ...
- enode框架step by step之事件驱动架构(EDA)思想的在框架中如何体现
enode框架step by step之事件驱动架构(EDA)思想的在框架中如何体现 上一篇文章,我给大家分享了我的一个基于DDD以及EDA架构的框架enode,但是只是介绍了一个大概.接下来我准备用 ...
- enode框架step by step之框架的物理部署思路
enode框架step by step之框架的物理部署思路 enode框架系列step by step文章系列索引: enode框架step by step之开篇 enode框架step by s ...
- enode框架step by step之Staged event-driven architecture思想的运用
enode框架step by step之Staged event-driven architecture思想的运用 enode框架系列step by step文章系列索引: 分享一个基于DDD以及事件 ...
随机推荐
- 为什么要重写hashCode()方法和equals()方法及如何重写
我想写的问题有三个: 1.首先我们为什么需要重写hashCode()方法和equals()方法 2.在什么情况下需要重写hashCode()方法和equals()方法 3.如何重写这两个方法 **** ...
- 自己写一个chrome扩展程序 - 右键菜单扩展
最近在学习Spring,心想dotnet如何实现类似形式呢.于是想认真学习Casetle组件,发现没有书籍!而spring的书多得很.于是只好找网上教程了.发现系统的文章不多.Terrylee好多文章 ...
- leetcode - [6]Binary Tree Postorder Traversal
Given a binary tree, return the postorder traversal of its nodes' values. For example:Given binary t ...
- (转)私有代码存放仓库 BitBucket介绍及入门操作
转自:http://blog.csdn.net/lhb_0531/article/details/8602139 私有代码存放仓库 BitBucket介绍及入门操作 分类: 研发管理2013-02-2 ...
- python的基础socket知识
对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. 代码意思if __name__ == '__main__':是主文件的话就先执行main函数, ...
- Servlet组件之 jsp 技术
JSP 简称java服务器页面(java server page),jsp和servlet实现了我们的开发需求.对于jsp技术我们首先需要知道他的组成 HTML+java+jsp内置对象=jsp ...
- java锁类型
转载链接在每个锁类型后边 线程锁类型 1.自旋锁 ,自旋,jvm默认是10次吧,有jvm自己控制.for去争取锁 锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchroni ...
- noah
1.url:controller/method 2.在index.php中设置display_errors:1 能看到错误提示
- shell 命令 -- 漂亮的资源查看命令 htop
htop 相较top,htop更加直接和美观.
- double float的精度问题
三部曲 1: #include <iostream> #include <stdio.h> #include <string.h> using namespace ...