数据库设计的基本步骤:以“网上书店“为例,看一座数据大厦如何拔地而起
设计一个数据库就好比建造一座大厦。没有人会拿起砖头就乱垒一气一座经得起风雨、住得舒心的大厦背后必有一套严谨的建造流程从勘察地形、绘制蓝图到搭建框架、精装养护步步为营、环环相扣。数据库设计同样如此。一个优秀的数据库绝不是程序员心血来潮、随手敲几条建表语句就能造就的它需要遵循一套完整而规范的步骤从摸清需求到落地实现循序渐进方能建成一座结构合理、坚固耐用的数据大厦。然而空谈步骤往往让人难以捉摸。本文将另辟蹊径自始至终贯穿一个具体的案例——为一家网上书店设计数据库。我们将跟随这个案例一步一步地走过数据库设计的六个基本步骤让每一步都落到实处、看得见摸得着从而真正理解一座数据大厦究竟是如何从一片荒地上拔地而起的。一、第一步需求分析——勘察地形弄清这家书店要管什么万丈高楼平地起平地起楼的头一件事绝不是搬砖砌墙而是搞清楚我们到底要造一座什么样的楼。数据库设计的第一步需求分析干的正是这件事它要弄清楚这个数据库究竟为谁服务、要存放什么数据、要支持哪些操作。现在我们就以网上书店为例来做一番需求分析。我们要去和书店的老板、店员、以及将来要用这个系统的人充分交流把他们的需求一条条挖出来、理清楚。经过一番调研我们梳理出了网上书店的核心需求。从数据上看这家书店需要管理这样几类信息。第一类是图书信息每本书都有书号、书名、作者、出版社、价格、库存数量。第二类是顾客信息每位注册顾客都有顾客编号、姓名、电话、收货地址。第三类是订单信息顾客每下一次单就产生一份订单订单有订单编号、下单日期、订单总额。从操作上看这家书店需要支持这样一些处理。顾客可以浏览和查询图书顾客可以下订单购买图书而且一份订单里可以同时购买好几种不同的书每种书还可以买好几本店员需要查看订单、统计某本书的销量、查询某位顾客的历史订单等等。我们还特别注意到一个关键的业务细节一份订单可以包含多种图书而同一种图书也会出现在许多不同的订单里。这个多对多的购买关系是这家书店业务的核心必须在后续设计中妥善处理。把这些数据需求和处理需求整理成一份清清楚楚的需求说明需求分析这一步就算扎实地完成了。它就像勘察清楚了地形、明确了要造一座什么样的楼为后面的一切打下了根基。二、第二步概念结构设计——绘制蓝图画出书店的E-R图地形勘察清楚、目标明确之后下一步不是动工而是请建筑师绘制蓝图。蓝图用图纸的形式把这座楼的整体结构和各部分关系描绘出来但它不关心用什么牌子的水泥。数据库设计的第二步概念结构设计干的正是绘制蓝图这件事它要把上一步的需求抽象成一个不依赖任何具体数据库产品的概念模型最常用的工具就是实体联系图也就是E-R图。我们现在就来为网上书店绘制E-R图。E-R图有三个核心元素实体、属性、联系。先确定实体。根据需求分析我们提炼出三个核心实体图书、顾客、订单。在图中它们各用一个矩形框表示。再为每个实体确定属性也就是它们的特征在图中用椭圆表示。图书这个实体有书号、书名、作者、出版社、价格、库存这些属性其中书号能唯一标识一本书作为它的标识属性。顾客实体有顾客编号、姓名、电话、地址顾客编号作为标识。订单实体有订单编号、下单日期、总额订单编号作为标识。最关键的是确定实体之间的联系在图中用菱形表示并且要标明联系的类型。我们来分析。顾客和订单之间是什么关系呢一位顾客可以下多份订单但一份订单只属于一位顾客所以顾客和订单之间是一对多的联系我们叫它下单。再看订单和图书之间前面需求分析特别强调过一份订单可以包含多种图书一种图书也能出现在多份订单里所以订单和图书之间是多对多的联系我们叫它包含。而且这个包含联系本身还带有属性那就是每种书在这份订单里购买数量是多少这个数量既不属于订单也不单独属于图书而是属于这个购买关系所以它是联系上的属性。把图书、顾客、订单三个实体连同它们各自的属性以及顾客与订单之间的一对多下单联系、订单与图书之间的多对多包含联系用规范的图形组合起来一张网上书店的E-R图就绘制完成了。它清清楚楚地展现了这家书店要管理图书、顾客、订单三类事物每类事物有哪些特征事物之间又是何种关联。这张蓝图便于我们和书店老板反复推敲确认此时若发现遗漏或错误改改图纸即可代价很小。概念结构设计正是为数据大厦绘制了一张承上启下的建筑蓝图。三、第三步逻辑结构设计——把蓝图转化为具体的表蓝图描绘的是整体构思还不能直接施工。施工队需要的是具体到每一面墙的施工详图。从概念蓝图到可施工的详图需要一道转化工序。数据库设计的第三步逻辑结构设计就是把E-R图按照一套成熟的规则转化为一张张具体的二维表也就是关系模式。我们现在就来转化网上书店的E-R图。转化规则是这样的每个实体转化为一张表一对多联系在多的一方加入一方的主键作外键多对多联系必须单独建一张表。先转化三个实体。图书实体转化为图书表包含书号、书名、作者、出版社、价格、库存书号作主键。顾客实体转化为顾客表包含顾客编号、姓名、电话、地址顾客编号作主键。订单实体转化为订单表包含订单编号、下单日期、总额订单编号作主键。再处理联系。顾客与订单是一对多按规则在多的一方也就是订单表里加入一方顾客的主键作为外键。于是订单表里就多了一个顾客编号列用来表明这份订单是哪位顾客下的。这样顾客表和订单表就关联起来了。而订单与图书是多对多的包含联系按规则必须单独建立一张新表我们叫它订单明细表。这张表里要包含双方的主键也就是订单编号和书号再加上联系本身的属性购买数量。于是订单明细表包含订单编号、书号、购买数量。这张表里的每一行就记录了某份订单里包含了某种书多少本这样一条信息。正是有了这张表那个核心的多对多购买关系才得以妥善表达。经过转化我们得到了四张表图书表、顾客表、订单表、订单明细表。每张表的列、主键、外键都规定得明明白白相当于把蓝图变成了施工详图。但逻辑设计还有一道精修工序叫规范化要消除数据冗余和操作异常。我们来检查一下。设想如果当初偷懒不单独建订单明细表而是把购买的书名、作者、价格统统塞进订单表里会怎样呢那么同一本书每被买一次它的书名、作者就要重复存一遍这就是冗余万一这本书改了名所有相关订单都得跟着改改漏一处就会自相矛盾这就是更新异常。而我们现在的设计订单明细表里只存书号书的详细信息统一放在图书表里要用时通过书号去关联即可每种信息只存一处干干净净没有冗余。这说明我们的设计是符合规范化要求的、合理的。逻辑结构设计正是把蓝图转化为精确而规范的施工详图。四、第四步物理结构设计——选定材料工艺让书店系统跑得又快又省施工详图有了接下来要考虑用什么材料、什么工艺。同样的图用什么结构、地基怎么打、管线怎么走关乎大厦的性能。数据库设计的第四步物理结构设计考虑的正是这类与具体实现相关、关乎性能的问题它开始紧密依赖于具体选用的数据库产品和运行环境。我们来为网上书店做物理结构设计。这一步最重要的一项是索引设计。我们要分析这家书店平时最频繁的查询是什么。顾客最常做的是按书名搜索图书店员最常做的是查询某位顾客的所有订单。针对这些高频查询我们就应该建立恰当的索引。比如在图书表的书名列上建立索引这样按书名搜书时数据库就能像查目录一样飞快地定位而不必把整张图书表一行行翻遍。再比如在订单表的顾客编号列上建立索引这样查某位顾客的订单时也能迅速找到。当然索引并非越多越好。它要占用额外的存储空间而且每当增删改数据时索引也得跟着更新反而会拖慢这些操作。所以我们要权衡像书名、顾客编号这种查询频繁的列值得建索引而像顾客地址这种很少用来检索的列就不必建。除了索引物理设计还要考虑数据怎么存储、文件怎么组织、空间怎么分配等等。比如预计这家书店图书量不大但订单量会迅速增长那就要为订单表和订单明细表预留充足的增长空间。物理结构设计正是为数据大厦选定合适的材料与工艺让它既坚固又高效。五、第五步数据库实施——正式动工把书店数据库建起来蓝图、详图、材料工艺全都备齐万事俱备终于到了正式动工的时候。数据库设计的第五步数据库实施就是把前面所有设计成果真正落实到具体的数据库系统中把数据库实实在在地建立起来。我们来实施网上书店数据库。首先根据逻辑设计和物理设计的成果编写出具体的建表语句在选定的数据库管理系统中把四张表真正创建出来把主键、外键、约束、索引统统设置妥当。比如创建图书表的语句大致是这样的。CREATETABLE图书(书号CHAR(13)PRIMARYKEY,书名VARCHAR(100)NOTNULL,作者VARCHAR(50),出版社VARCHAR(50),价格DECIMAL(7,2),库存INT);类似地把顾客表、订单表、订单明细表也都创建出来并在订单表里设置顾客编号为指向顾客表的外键在订单明细表里设置订单编号、书号分别指向订单表和图书表的外键再按物理设计在书名、顾客编号等列上建立索引。这就好比照着图纸把大楼的框架结构实实在在搭了起来。其次组织数据录入把书店现有的图书资料、注册顾客等初始数据装载进表里让原本空荡荡的表格开始有真实数据入住。然后编写调试与数据库交互的应用程序比如顾客下单的程序、店员查询的程序。最后进行试运行用真实的图书、顾客、订单数据模拟下单、查询、统计等操作检验这个数据库功能是否正确、性能是否达标。比如试着下一份包含三种书的订单看看订单表和订单明细表里是否正确地生成了相应的记录。数据库实施正是正式动工、把数据大厦实实在在盖起来的关键一步。六、第六步数据库运行与维护——开门营业持续养护大楼盖好、验收合格可以入住了但建造工程并未彻底结束。大楼在长年使用中需要持续的物业养护。数据库设计的最后一步数据库运行与维护干的正是这入住使用、持续养护的工作。网上书店数据库正式上线、开门营业之后便进入了长期的运行与维护阶段数据库管理员要承担起诸多养护职责。第一是备份与恢复。书店的订单和顾客数据极其宝贵一旦丢失损失巨大所以必须定期备份比如每天夜里自动把整个数据库备份一次万一某天服务器硬盘损坏就能用昨夜的备份迅速恢复把损失降到最低。第二是安全性与完整性维护。要管好权限比如普通店员只能查询订单不能修改图书价格而经理才有改价的权限防止数据被乱改同时保证数据始终满足约束比如库存不能为负数。第三是性能的监测与调优。随着这家书店生意越来越红火订单数据迅猛增长原先反应飞快的查询可能渐渐变慢。管理员就要持续监测发现瓶颈及时优化比如为新出现的高频查询补建索引或者把多年前的历史订单归档到别处给当前数据减负。第四是重组与重构。当书店业务发展比如新增了图书评价功能原有的表结构不够用了就需要适当扩充、调整数据库结构添加新的评价表等让数据库跟上业务发展的步伐。可见运行与维护是贯穿数据库整个生命周期的长期工作它保障了书店数据库安全、高效、稳定地长久运行正如大楼的物业养护是保障数据大厦历久弥新的最后一步也是永不停歇的一步。七、结语行文至此我们以建造大厦为喻并自始至终贯穿网上书店这一具体案例生动而完整地走过了数据库设计的六个基本步骤。我们从需求分析出发弄清了书店要管图书、顾客、订单要支持下单和查询接着进行概念结构设计画出了包含三个实体、一对多下单联系和多对多包含联系的E-R图这张蓝图然后通过逻辑结构设计把蓝图转化为图书、顾客、订单、订单明细四张规范的表再经物理结构设计为书名、顾客编号等高频查询列设计了索引进而通过数据库实施写出建表语句、录入数据、把书店数据库实实在在建了起来最后步入运行与维护对它持续地备份、保护、调优与扩充。六个步骤由抽象到具体、由设计到实现再到运维环环相扣层层推进。回顾这场以网上书店为线索的建造之旅我们能够深切体会到数据库设计绝非一蹴而就的简单活计而是一项需要通盘谋划、循序渐进的系统工程。每一步都有不可替代的作用需求分析定方向概念设计绘蓝图逻辑设计造详图物理设计选工艺实施阶段见真章运维阶段保长久。任何一步的草率都可能给最终的数据大厦留下难以弥补的缺陷。尤其那个多对多的购买关系正是因为在概念设计时就被准确识别、在逻辑设计时又被妥善地拆成了订单明细表整个书店数据库才得以结构清晰、毫无冗余。这恰恰印证了前期设计的步步用心会怎样实实在在地决定着最终系统的优劣。更可贵的是这套步骤所蕴含的是一种严谨求实、谋定后动的工程智慧。它告诉我们面对复杂的设计任务不能急于求成、贸然动手而要先想清楚、再做扎实把抽象的需求一步步具体化、把宏观的构思一层层落地化。当我们今天能够像一位经验丰富的建筑师那样对照着网上书店这样一个真实的案例从容地完成从需求到运维的全过程时我们便真正掌握了构建数据世界的核心方法论。希望大家不仅记住这六个步骤更能借由这个案例领会其中由虚到实、环环相扣的设计精髓并在今后的实践中亲手为自己的项目走上这样一遭。唯有如此我们才能真正建造出一座座结构合理、坚固耐用的数据大厦在数据驱动的时代里行稳致远。