本文共 8647 字,大约阅读时间需要 28 分钟。
本篇目录
对于SQL Server基础,我们已经学习了SQL Server的相关概念和基本操作,包括创建库、创建表、添加约束和创建安全账户等。
掌握了对数据的增加(insert)、删除(delete)、修改(update)、查询(select)等SQL语句,主要知识点如下:
本系列教程,我们将深入学习SQL Server的高级应用,课程内容如下:
您也许会问,在第一阶段,根据业务需求,我们直接建库、建表,插入测试数据,然后再查询数据,为什么现在需要强调先设计再建库、建表呢?
原因非常简单,正如我们修造建筑物一样,如果您是盖一间茅屋或一间简易平房,您会花钱请人设计房屋图纸嘛?毫无疑问,没人请。
但是,如果是房地产开发商开发一个楼盘,修建多栋楼房的居住小区,他会情人设计施工图纸嘛?答案是肯定的。
不但开发商会考虑设计施工图纸,甚至恨专业的购房者也会在看房时要求开发商出示设计图纸。
同样道理,在实际的项目开发中,如果徐彤的数据存储量较大,设计的表也比较多,表和表之间的关系比较复杂,我们就需要过滤规范的数据库设计,然后再进行具体的建库、建表工作。
不管是创建动态网站,还是创建桌面窗口应用程序,数据库设计的重要性都不言而喻。
如果设计不当,查询起来就非常吃力,程序的性能也会受到影响。
无论您是用的是SQL Server还是Oracle数据库,通过进行规范化的数据库设计,都可以使您的程序代码更具有可读性,更容易扩展,从而也会提升项目的应用性能。
数据库设计就是规范和结构化数据库中的数据对象以及这些数据对象之间关系的过程。
如图是一个KTV数据库的结构,示例该数据库包含歌手、歌手类型、歌曲、歌曲分类的信息,图中还显示了各个对象之间的关系。
数据库中创建的数据结构的种类,以及在数据对象之间建立的复杂关系是数据库系统效率的重要决定因素。
糟糕的数据库设计表现为以下几点:
良好的数据库设计表现为以下几点:
经过了SQL Server基础的学习,我们对项目的开发有了一个整体的感性认识,项目开发需要经过需求分析、概要设计、详细设计、代码编写、运行测试和打包发布几个阶段。
重点讨论在各个阶段,数据库的设计过程:
现在,我们共同讨论:在需求分析阶段,后台数据库的设计步骤。
无论数据库的大小和复杂程度如何,再进行数据库的系统分析时,都可以参考下列几本步骤:
创建数据库之前,必须充分理解数据库需要完成的任务和功能。
简单的说,我们需要了解数据库需要存储哪些信息(数据),实现哪些功能。
以BBS论坛系统为例,我们需要了解BBS论坛的具体功能,与后台数据库的关系:
在收集需求信息后,必须标识数据库要管理的关键对象或实体。
我们曾在Java中学习过对象的概念,对象可以是有形的事务,如人或产品。也可以是无形的事务,如商业交易、公司部门或发薪周期。
在系统中标识这些对象以后,与他们相关的对象就会理清楚。
以BBS论坛系统为例,我们需要标识出系统中的主要对象(实体),注意:对象一般是名词,一个对象只描述一件事情,不能重复出现含义相同的对象:
数据库中的每个不同的对象都拥有一个与其相对应的表,也就是说,在我们的数据库中,会对应至少三张表,分别是用户表、帖子表和板块表。
将数据库中的主要对象标识为表的候选对象以后,下一步就是标识每个对象存储的详细信息,也称为该对象的属性,这些属性将组成表中的列。
简单的说,就是需要细分出每个对象包含的子成员信息。
以BBS论坛系统为例,我们逐步分解每个对象的子成员信息,在分解时又发现发帖合回帖不同,所以把帖子细分为发帖合回帖两个对象(实体)。
注意:
分解时,含义相同的成员信息不能重复出现,例如联系方式和电话等,每个对象对应一张表,对象中的每个子成员对应表中的每一列。
例如,从上述的关系就可以看出用户表应该包含列:用户名、密码和电子邮件等
关系型数据库有一项非常强大的功能,它能够关联数据库中各个项目的相关信息。
不同类型的信息可以单独存储,但是如果需要,数据库引擎可以根据需求将数据组合起来。
在设计过程中,要标识对象之间的关系,需要分析这些表,确定这些表在逻辑上是如何相关联的。
以及添加关系列建立起表之间的连接。
以BBS论坛系统为例:
在需求分析阶段解决了客户的业务合数据处理需求后,就进入了我们的概要设计阶段,我们需要合项目团队的其他成员以及我们的客户沟通,讨论数据库的设计是否满足客户的业务合数据处理需求。
和机械行业需要机械制图,建筑行业需要施工图一样,我们的数据库设计也需要图形化的表达方式——E-R(Entity-Relationship)实体关系图,它也包括一些具有特定含义的图形符号。
下面将介绍相关理论和具体的图形符号。
4.1.1 实体
所谓实体就是指现实世界中具有区分其它事物的特征或属性并与其它实体有联系的对象。
例如BBS论坛系统中的用户、帖子、板块等,实体一般是名词,它对应我们表中的一行数据,例如张三用户这个实体,将对应“用户表”中,张三用户所在的一行数据,包括他的密码、出生日期、电子邮件等信息。
严格的说,实体指表中一行一行的特定数据,但我们在开发时,也常常把整个表也称为一个实体。
4.1.2 属性
属性可以理解为实体的特征。
例如:“用户”这个实体的属性有昵称、出生日期和电子邮件等。
属性对应表中的列。
4.1.3 关系
关系是两个货多个实体之间的联系。
如图是用户实体和板块实体之间的关系,实体使用方块表示,实体一般是名词,属性使用椭圆表示,一般也是名词。
关系使用菱形表示,一般是动词。
4.1.4 映射基数
映射基数表示可以通过关系与该实体关联的其它实体的个数。
对于实体集X和Y之间的二元关系,映射基数必须为下列基数之一:
E-R图以徒刑的方式将数据库的这个那个逻辑结构表示出来,E-R图的组成包括:
在本教程中,直线可以是有方向的(在末端有一个箭头),用来表示关系集的映射基数。
如图显示了一些示例,这些示例表示了可以通过关系与一个实体相关联的其它实体的个数,箭头的定位很简单,可以将其视为指向引用的实体。
绘制E-R图后,我们还需要与客户反复进行沟通,让客户提出修改意见,以确认系统中数据处理需求是否表示的正确和完整。
该要设计解决了客户的需求捕获,并绘制了E-R图,在后续的详细设计阶段,我们需要把E-R图转换为多张表,并标识各表的主外键。
下面将介绍如何将介绍如何将E-R图转换为表哥,如何审核各表的结构是否规范将在本篇最后进行介绍。
根据上述E-R图转换的表如图:
标识各表键的关系后如图:
有人开玩笑说,在该要设计阶段,同一个项目,10个设计人员将设计出10种不同的E-R图。
不错,不同的人从不同的角度,标识出不同的实体,实体又饱含不同的属性,自然就设计出不同的E-R图。
那么怎样审核这些设计图呢?怎么评审出最优秀的设计方案呢?
所以,我们的下一步工作就是规范化E-R图了。
为了讨论方便,下面直接以账户表(Account)为例,该表存储有关银行客户账户的信息和交易细节:
帐号 | 客户姓名 | 地址 | 开户日期 | 账户类型 | 交易号 | 交易金额 | 交易日期 |
85001 | Smith | 1,Main | 1/4/03 | Savings | 1 | 1000 | 2/4/03 |
85002 | James | 2,Main | 3/4/03 | Current | 2 | 200 | 4/4/03 |
85003 | Ritcha | 3,Main | 4/4/03 | Savings | 3 | 100 | 5/4/04 |
86003 | Ritcha | 3,Main | 4/4/03 | Savings | 4 | 400 | 6/4/03 |
从用户的角度而言,将所有信息放在一个表中很方便,因为这样查询数据库可能会比较容易,但是上述表具有下列问题:
如何重新规范设计上述表呢?如何避免上述诸多异常呢?
在数据库的设计时,有一些专门的规则,成为数据库的设计范式,遵守这些规则,您将创建设计良好的数据库,下面将注意讲解数据库设计中著名的三大范式理论。
1. 第一范式(1NF,Normal Formate)
第一范式的目标时确保每列的原子性:如果每列(或者每个属性值)都是不可再分的最小数据单元(也称为最小的原子但愿),则满足第一范式(1NF)。
例如:
顾客表(顾客编号、地址、...),其中地址列还可以细分为国家、省、市、区等,更多的程序甚至把姓名也拆分为姓和名等。
2. 第二范式(2NF)
第二范式在第一范式的基础上,更进一层,其目标是确保表中的每列都和主键相关,如果一个关系满足1NF,并且出了主键以外的其它列,都依赖于该主键,则满足第二范式(2NF)。
例如:
订单表(订单编号、产品编号、订购日期、价格、...)
该表主要用来描述订单,所以订单编号设为主键,“订购日期”、“价格”两列都和“订单编号”主键相关,但“产品编号”列和“订单编号”列没有直接关系,即“产品编号”列不依赖于“订单编号”主键列,该列应从该表中删除,放入产品表中。
这样,该表就只描述一件事情:订单信息。
3. 第三范式(3NF)
第三范式在第二范式的基础上,更进一层,第三范式的目标是确保每列都和主键列直接相关,而不是间接相关:如果一个关系满足2NF,并且出了主键以外的其它列都不依赖于主键列,则满足第三范式(3NF)。
为了理解第三范式,需要根据Armstrong公理之一定义传递依赖:假设A、B和C是关系R的3个属性,如果A->B且B->C,则从这些函数依赖(FD)中,可以得出A->C,如上所述,依赖A->C是传递依赖。
例如:
订单表(订单编号、订购日期、顾客编号、顾客姓名、...)
初看该表没有问题,满足2NF,每列都和主键列“订单编号”相关,再细看您会发现“顾客姓名”列和“顾客编号”相关,“顾客编号”列和“订单编号”又相关,最后经过传递依赖,“顾客姓名”也和“订单编号”相关。
为了满足3NF我们应该去掉“顾客姓名”列,将此列放入客户表中。
了解了用于规范化数据库设计的三大范式之后,咱们回头看一下上面那个Account帐号表。
1.是否满足第一范式
第一范式要求每列必须是最小的原子单元,即不能再细分。
前面我们提及过,地址需要氛围省、市、区等,方便查询。但我们没有这方面的查询需求,所以本例中没必要拆分“地址”列。
所以,该表满足第一范式。
2.是否满足第二范式
第二范式要求每列必须和主键相关,不想管的列放入别的表中,即要求一个表只描述一件事情。
实用的技巧是,我们可以直接查看该表描述了哪几件事情,然后一件事情创建一张表。经过分析,该表描述了三件事情:
1) 账号信息
2) 交易信息
3) 账户类型信息
即我们需要创建三张表,对各列进行筛选,拆分后结果表如下:
类型编号 | 账户类型 |
1 | Savings |
2 | Current |
交易号 | 交易金额 | 交易日期 | 帐号 |
1 | 1000 | 2/4/03 | 85001 |
2 | 200 | 4/4/03 | 85002 |
3 | 100 | 5/4/03 | 85003 |
4 | 400 | 6/4/03 | 86003 |
帐号 | 客户信息 | 地址 | 开户日期 | 账户类型 |
85001 | Smith | 1,Main | 1/4/03 | 1 |
85002 | James | 2,Main | 3/4/03 | 2 |
85003 | Ritcha | 3,Main | 4/4/03 | 1 |
86003 | Ritcha | 4,Main | 4/4/03 | 1 |
3.是否满足第三范式
第三范式要求该表中各列必须和主键直接相关,不能间接相关,浏览每个表,已经满足了。
需要提醒的是,对于项目的最终用户来说,客户最关系的是方便、清晰的数据结果。
您如果让客户选择,毫无疑问,客户会认为最初的表设计最适合需求,虽然他根本就不满足三大方式,并且存在大量的数据冗余。
所以说,我们在设计数据库时,设计人员和客户对数据库的设计有一定的矛盾。
通过三大范式分解的三张表,为了满足客户的需求,最终我们需要通过三张表之间的连接查询,恢复为客户需要的数据结果。
插入数据同样如此,对客户输入的数据,我们需要分开插入在三张不同的表中。
由此可以看出,为了满足三大范式,我们的苏剧操作性可能会收到相应的影响。
所以,在时机的数据库设计中,既要考虑三大范式,避免数据的冗余和各种数据操作异常,还要考虑数据访问性能。
有时,为了减少表间链接,提高数据库的访问性能,适当允许少量数据的冗余列,才是最合适的数据库设计方案。
在需求分析阶段,设计数据库的一般步骤如下:
在概要设计阶段和相惜设计阶段,设计数据库的一般步骤为如下:
从关系型数据库中除去冗余数据的过程称为规范化。如果使用得当,规范化是用于获得高效关系型数据库中表的逻辑结构的最好和最容易的方法。
规范化数据时,执行下列操作:
【来自:张董'Blogs:,转载请注明出处。】
亲们。码字不容易,觉得不错的话记得点赞哦。。