??xml version="1.0" encoding="utf-8" standalone="yes"?> 实现q个目的的方法是你的参CZ个XML字符串来传递,q剖析XML来取回你所需要的数据Q然后l实C所需要集成的功能。你不仅可以通过XML来获取一些参敎ͼ你还可以对XML所创徏的DOM文档q行查询Q以此来装多个存储q程。我会提供一些例子,告诉你如果实现这个目的,q简要地描述每个例子?/p>
在本例里Qؓ了更C个Customer表格里的姓名字段Q我会传递几个参数。ؓ了获?i>customeridQn份列Q和新的姓名字段QXML会被剖析。我传递给q程的XML字串像下面的这P
<root><Customer><customerid>3</customerid><name>Acme 要被创徏的存储字D就像下面的q样Q?/p>
q个q程首先声明我们将要用到的变量会保存相关信息。在此之后,DOM文档被打开Q一个“句柄(handleQ”会被返回到sp_xml_preparedocument调用的第一参数里?/p>
q个调用的第二个参数是用于新DOM文档的XML源文件。这个“句柄”是在进行OPENXML调用的时候用来从DOM里查询信息的。OPENXML调用的第二个参数是父节点的一个Xpath映射Q这些父节点包含有要被执行的数据?/p>
W三个参敎ͼ2Q指明,以元素ؓ中心的映会被用。WITH子句剖析的数据提供了数据列集QrowsetQ格式,sp_xml_removedocument调用会删掉DOM文档的源文g?/p>
在下面这个例子里Q我会传递一pd用户IDQ用以删除多个数据列。下面就是XML字符串的内容Q?/p>
相应的存储过E看h像下面q样Q?br />. . . 有了q个存储q程׃再需要创Z个冗长的SQL查询字符Ԍ用以在ADO里传递或者多ơ调用一个存储过E了。这也会消除多次调用对网l流量所造成的媄响?/p>
正如你能够看到的Q微软的SQL 2000让整个过E稍E简单了一炏V要CQ这一Ҏ的不之处在于:在SQL 2000q行XMLd的时候,XML作ؓ一个参数发送会被限制到8,000字符。和以往一P不要忽视了精心策划的好处?/p>
讉KMSDN库能够获得更多关?a target="_blank">OPENXML?a target="_blank">sp_xml_preparedocument以及sp_xml_removedocument的信息?/p>
在过dq中Q我们将敏捷Ҏ应用于数据库设计中。我们ȝZ些技巧,使得当应用程序发展时Q数据库也能够进化,q是敏捷Ҏ的一个重要属性。我们的Ҏ是通过持箋集成以及自动重构Q通过数据库管理h员(DBAQ和应用开发h员的紧密合作。这些技巧在应用开发的各个时期都有效?br /> q年来,出现了一U新的Y件开发方法学—敏h法学。这l数据库设计提出了一些新的、巨大的需求。这些需求的一个中心就是进化设计。在一个敏捷项目中Q需要假定我们ƈ不能事先定pȝ的需求。因此在目的初期有一个详l设计阶D늚x是不现实的。系l的设计必须随着软g的变化而进化。敏h法,其是极限编E(XPQ,通过一些实践ɘq种q化设计成ؓ可能。在数据库设计采用敏h法,反复q代。?br />
8. 正确认识数据冗余
4. 不要附加不必要的功能
Inc.</name></Customer></root>
CREATE PROCEDURE update_Customer (@xmldatavarchar(8000)) AS
DECLARE @customeridint
DECLARE @customernamevarchar(50)
DECLARE @xmldata_idint
EXEC sp_xml_preparedocument @xmldata_id OUTPUT, @xmldata, ''
SELECT @customerid = customerid, @customername = [name] FROM
OPENXML(@xmldata_id, '//Customer', 2) WITH (customeridint, [name]
varchar(50))
EXEC sp_xml_removedocument @xmldata_id
UPDATE Customer SET Customer.[name] = ISNULL(@customername, Customer.[name])
WHERE Customer.tblID = @customerid
<root><Customer><customerid>1</customerid></Customer><Customer><customerid>
2</customerid></Customer><Customer><customerid>3</customerid></Customer>
</root>
EXEC sp_xml_preparedocument @xml_id OUTPUT, @xmldata, ''
DELETE FROM Customer WHERE Customer.tblID IN (SELECT customerid FROM
OPENXML(@xmldata_id, '//Customer', 2) WITH (customeridint))
. . .
]]>
1敏捷Ҏ?/b>
许多Z怀疑敏h法能否用于有大型数据库组件的pȝ。但我们的确使用了许多敏捷和XP技巧,用于解决Z大型数据库的目中的q化与P代问题?br />
本文介l一些在数据库设计采用敏h法的实践。当Ӟqƈ不是说我们已l完全解决了数据库进化的问题Q但是我们想提供一些行之有效的Ҏ?br />
2 U极应对变化
敏捷~程的一个显著特点就是它面对变化的态度。对软gq程的一般解释是早理解需求,停止需求的变动Q将q些需求作计的基础Q停止设计的变动Q然后开始构{体pR这是瀑布Ҏ--Z计划的生命周期?br />
q种Ҏ通过大量的前期工作来减少变化。一旦前期工作完成,需求变化会引v很大的问题。因此当需求变化时Q这LҎ׃有很大的问题Q因此需求变动是q种q程的一个很大的问题?br />
而敏LE却以另外一U方式来面对变化。拥抱变化,甚至允许在项目开发的后期发生变化。尽变化会被控Ӟ但是q种态度会允许尽可能多的变化。变化部分来自于目需求的不稳定,部分来自于要支持变化的商业环境来面对竞争压力?br />
Z做到q样Q必采取不同的设计态度。设计不仅仅是一个阶D?在开始徏{之前就大部分完成的一个阶D;设计是一个持l的q程Q与~码、测试甚臛_布相兟뀂这是计划设计与q化设计的不同之处。敏h法的一个重要A献是提出了在可控制方式下的进化设计。因此不是由于设计没有预先计划好Q生了混ؕ。敏h法提供了控制q化设计和其可行的技巧?br />
敏捷Ҏ的一个重要特点就是P代式开发,x个项目生命周期中q行多个完整的Y件生命周期@环。敏捯E在每次q代中都会度q一个完整的生命周期。P代可以完成最l品的需求子集中~码、测试以及集成代码。敏h法P代时间较短,通常是一周到两个月之_而且我们更們于更短的q代周期?br />
当用敏h法时Q最大的问题是数据库如何进行进化设计。许多h认ؓ数据库设计是前期计划的工作,而在后期改变数据库设计计划会引v应用软g的崩溃;在配|以后改变数据库设计计划会导致数据迁U问题?br />
在过Mq我们参加了一个大型的目Q其中用C切实可行的进化设计的Ҏ。该目包括100人的目l, 200多张表格Q数据库在一q半的最初开发中一直在q化Q甚臛_为多用户分发的过E中也在q化。一开始我们一个月q代一ơ,q了几个月之后变?周P代一ơ?br />
随着我们这些经验推q到目中越来越多的部分Q从来多的案例中获得l验。同Ӟ我们也从其他敏捷目中吸收了一些经验?br />
2.1限制条g
在讲q实跉|法之前,必须指出我们q没有解x有的数据库进化设计问题,特别是:
* 我们是ؓ单独的应用设计一个应用数据库Q而不是试N成多个数据库Q?br />
* 我们没有做到24*7的数据库更新?br />
虽然很多为我们无法解册个问题,但其实这些问题是可以解决的。当然这需要进一步的工作Q光说是不能解决问题的?br />
3 实践
我们有关于数据库q化设计的方法依赖于一些重要的实践?br />
3.1数据库管理h员与开发h员紧密合?br />敏捷Ҏ的一个重要原则就是拥有不同技能和背景的h能够紧密合作。正式的会议和文档不能达C效果,因此他们需要一直一起工作,亲密合作。所有的目l成员都需要紧密合作:pȝ分析人员Q项目经理,行业专家Q开发h员以及数据库理人员QDBAQ?br />
开发h员的每项工作可能都需要DBA的帮助。开发h员和DBA需要考虑是否需要对数据库计划做很大的改变。开发h员向DBA咨询如何应对变化Q开发h员知道需要什么新的功能,而DBA对应用中的数据有全局的观c?br />
Z辑ֈ亲密合作的效果,DBA必须使自己易于接q。DBA需要留出几分钟的时_让开发h员来提问。必ȝ保DBA和开发h员坐在一Pq样他们很Ҏ沟通。同时必ȝ保应用设计会议是公开的,q样DBA可以随时加入q来。在很多情况下我们发Ch们在DBA和应用开发h员之间徏立屏障,q些屏障必须去除Q这栯化数据库设计才有可能?br />
3.2每个目l成员都有自q数据库实?br />q化设计认ؓZ通过试来进行学习。在~程期间开发h员在如何实施某个特征Q应用某个首选的Ҏ之前做一些试验。数据库设计也是如此。因此,每个开发h员都有自q来试验的实例Q而不必媄响其它hQ这一点很重要。这h个h都可以根据自q需要进行试验?br />
许多DBA专家认ؓ多个数据库是一U麻烦,不易于实际应用,但我们发现操作一百个左右的数据库是很Ҏ的。当然其中很重要的是拥有便利的工P使你像操作文件一h作数据库?br />
3.3开发h员数据库l常集成到共享主数据?br />管开发h员可以在他们自己的空间频J试验,但是不同的工作定期汇合也是很重要的。应用开发需要一个共享主数据库,所有的工作都汇集于此。当开发h员开始工作时他们从主数据库获取拷贝到自己的工作空_q行操作和修改,然后变化反馈进入主数据库。我们的规定是每个开发h员要每天提交汇合一ơ?br />
假设开发h员上?0点开始一开发Q务,q项d的一部分是改变数据库计划。如果这U改变很单,如增加一个字D,他就可以自己军_。通过数据字典的帮助,开发h员还必须保他想增加的字D|据库中没有。但是如果他与DBA讨论q种可能的变化,那么工作p单的多?br />
当他准备开始时Q先从主数据库中获取一份拷贝,q样可以自由地改变数据库计划和代码。因Z使用的是自己的数据库实例Q所以不会媄响别人。在某个时候,如下?点,他很清楚需要什么样的数据库变化Q甚x时他q没有完全做完他的编码工作。这时他扑ֈDBAQ告诉他惌的变化。这时DBA可以提出开发h员没有考虑到的问题。当然大多数时候都很好QDBA同意q种变化Q通过一个或多个数据库重构)。DBA使变化马上发生(除非他们是破坏性的变化Q,q样开发h员可以l他的工作,在Q何时候提交代码,因ؓDBA已经这些变化发送给L据库?br />
可以这个原则看作类g持箋集成Q持l集成常用于源码理。实际上q就是将数据库看作是另一U源代码。因为配|管理系l象控制源代码一h制主数据库。只要我们构建成功,数据库和源代码一赯送入配置理pȝQ这h们就有两者完整和同步的版本历双Ӏ?br />
对于源代码来_集成中的问题被源代码控制pȝ处理。对于数据库来说Q要做的工作E微多一些。所有数据库的变化都需要妥善处理,如自动化数据库重构。此外DBA需要审视Q何数据库变化Q保证其W合整个数据库的计划。ؓ了ɘq项工作做的比较q稳Q在集成的过E中不应该出现大的变?-因此需要DBA与开发h员紧密合作?br />
我们l常性的集成,因ؓ它比非经常性的大集成容易得多。集成的复杂度会随着集成的规模呈几何U度增加。因此做许多的变化在实践中更易于实玎ͼ当然q看上去与直觉相抵触?br />
3.4数据库包含计划和试数据
当提到数据库的时候,我们q不仅仅指数据库计划Q而且q包括相当规模的数据。这些数据包括应用所需的标准数据,如全国所有的省䆾名,以及一些样本客Lh数据?br />
数据的作用:
1?易于试
使用大量的自动化试可以帮助E_应用的发展。这L试在敏h法里是常用的Ҏ。ؓ了ɘq些试有效q行Q很理智的方法是在一个有h试数据的基上工作,q样所有的试可以在程序正式进行之前完成?br />
2、测试数据库的迁U?br />
除了试代码之外Q样本测试数据允许我们测试数据库的迁U,当改变了数据库的计划后,我们q必M证所有的计划变更也能够处理样本数据?br />
在大多数目中这些样本数据是虚构的。然而在某些目中h们用实际数据作Z子。在q些情况下,数据从先前由自动化数据迁UM码的pȝ中提取出来。很明显不能马上q移所有的数据Q因为在早期q代中数据库只有部分徏立v来。但是我们希望当应用和数据库发展Ӟ改变q移代码。这样不仅能够尽早解册U问题,也行业专家易于处理q个正在开发的pȝ。因为有他们熟悉的数据,所以他们会指出可能l数据库和应用设计带来问题的地方。因此我们徏议在目的早期P代中引入实际数据?br />
3.5所有的变化应该数据库重?br />重构技术就是应用所有可控技术来改变现有的代码基。与此类似我们定义了数据库重构也l数据库的改变提供了cM的控制?br />
数据库重构的不同之处在于它必d三种不同的变化同时完成:
* 改变数据库计?br />
* q行数据q移
* 改变数据库存取代?br />
于是当描q数据库重构Ӟ我们必须描述变化的三个方面,q确保在应用另一个重构之前完成了q三U变化?br />
我们必须文档化不同的数据库重构,因此我们q不能详l描qC们。然而这里有几点需要指出:像代码重构一P数据库重构非常微。概念链一pd微小的变化,数据库和代码很相伹{变化的三个属性保持的变化更加重要?br />
许多数据库重构,如增加一个字D,可以不必更新所有存取系l的代码来完成。但是如果在使用新计划之前ƈ不了解它Q该字段会无用Q因为新计划不知道其变化之处。许多变化,没有考虑整个pȝ计划Q我们称之ؓ破坏性变化,如将一个已l存在的I值列讄为非I。破坏性变化需要多加留心,留心的程度依赖于包含破坏性的E度。一个小破坏性的例子是将一个已l存在的I值列讄为非I,在这U情况下你可以蒙着头做?br />
而重构将考虑数据库中I值数据。开发h员将更新数据库映代码,因此更新不会破坏其它人的代码Q如果偶然会破坏Q开发h员将在徏立和使用试时发现问题?br />
一个经怋用的表分成两个是一U更复杂的破坏。在q种情况中提前让所有h知道变化到来很重要,q样他们可以有所准备。此外应该在一个更安全的时L实施变化?br />
q里面很重要的一Ҏ选择适用于你做出的变化的q程?br />
3.6自动重构
在代码世界中许多语言能够实现自动重构。在计划变化和数据迁U过E中Q这U自动化对于数据库也非常重要。因此每个数据库重构都可以通过~写SQL DDLQ对于计划变化)和DMLQ对于数据迁U)来完成。这些变化不是通过手工实现Q而是通过一些SQL语句来自动实现变化?br />
一旦完成代码,我们保存q些代码文g来生数据库变化的完整的变化记录Q作为数据库重构的结果。我们于是可以更CQ何实例到最新的L据库Q通过q行在我们拷贝主数据库来产生更早的数据库实例的变化记录?br />
自动化变化的序列化是对于持箋集成和迁UM品数据库的一个基本功能?br />
Z最后品数据库我们q不在常规P代周期中实施变化。我们在每一个发布之间徏立完整的数据库重构变化日志。毫无疑问,q是一个巨大的变化Q我们必ȝU实施该变化。在实际应用之前先测试迁U计划绝Ҏ明智之D。迄今ؓ止,q项技术相当管用。通过大变化分解为小的简单的变化Q我们可以对产品数据q行大的变化Q同时又不会l我们太多的ȝ。套用兵法中的一句话Q就是“化整ؓ零”?br />
除了自动化向前的变化Q我们也要考虑重构时向后的变化。如果能够做到这样就可以回到以前的数据库状态。在我们的项目中q没有这样做Q因为没有这个需求,但这同样是很重要的基本原则?br />
3.7自动地更新所有开发h员的数据?br />Z变化和更C数据库,但是如何发现L据库已经发生变化Q在传统的持l集成有源代码的环境中,开发h员在提交变化之前先更C数据库。这样他们就可以在提交变化给׃nL据库之前Q解决他们自q机器上的问题?br />
每次L据库发生改变Ӟ我们都要更新开发h员的数据库。当L据库发生变化Ӟ我们自动化更新所有项目成员的数据库。相同的重构代码更新L据库上的同时Q自动更新成员数据库。也许有为在开发h员不知情的情况下Q更新开发h员数据库会生很多问题,但在实践中我们没发现什么问题。当Ӟq只在h们联|时用。所以当开发h员离U时Q必d快与L据库重新保持同步。?br />
3.8清晰地分L有的数据库获取代?br />Z理解数据库重构的l果Q了解应用程序如何用数据库也非帔R要。如果SQL语句分布在代码基周围Q则很难q样d。因此一个清晰的数据库获取层很重要,它用来显C数据库如何被用,在哪里被使用?br />
清晰的数据库层有很多好处。它减少了开发h员操U|据库旉要用SQL知识的地方,q样使对SQL语句不太熟悉的开发h员更易开发。对于DBA来说Q给他提供了清晰的代码,可以清楚C解数据库如何用。这也帮助准备烦引、数据库优化Q优化SQL语句QDBA更好地理解数据库如何被用?br />
4 变化法则
如同M实践一Pq些原则必须Ҏ你特D的环境变化。没有一成不变的目Q我们必要应对变化?br />
4.1保持多个数据库在一个系l中
单项目也许只需要一个主数据库。但是复杂项目需要有多个数据库,x据库pR如果在投入生之前数据库必d支,那么我们可以创徏新的数据库系。数据库pȝg代码的分支,需要不同测试数据集来进行测试?br />
当开发h员从L据库中获取了一份拷贝,必须注册他们在修改哪个数据库pR当DBA更新L据库某个数据库系Ӟ同时更新了所有注册这个数据库pȝ开发h员的数据库?br />
4.2不需要专职的DBA
所有这些听上去好像需要大量的工作Q但它ƈ不需要大量的人力资源。在最大的目中,我们?0个开发h员,目l规?00人(包括质量评h、分析h员和理人员Q,我们大概?00多个不同pd的品分布在各工作站上。但所有这些工作只需要一个专职DBAQ只有两个编Eh员业余帮忙?br />
在小目中甚至不需要专职DBA。当我们这些技巧用于更的目--12人左右的项目时Q发现该目不需要一个专职的DBA。与此相反,我们依靠两个Ҏ据库感兴的开发h员业余处理DBAd?br />
q是自动化的功劳。如果对每项dq行自动化处理,可以用更少的h来完成更多的工作?br />
5辅助工具
数据库进化需要大量的重复性工作,我们可以开发一些简单工h帮助我们解决大量的重复性工作?br />
自动化的最有h值的地方是有一个通用数据库Q务简单代码集。自动化的Q务包括:
* 用户资料与现在管理员的资料一?br />
* 创徏新用?br />
* 复制数据库计划ƈ协同修改
* Udq合成数据库
* 删除用户
* 导出用户Q这样项目组成员可以分发ȝ数据库备份?br />
* 导入用户Q这样项目组成员可以拥有数据库备份,导入数据库,创徏新计划?br />
* 导出基线Q将L据库q行备䆾Q这是导出用L一个特例。?br />
* 创徏不同计划的报告,以便比较?br />
* 计划与主计划作比较Q这样开发h员就可以他们本地拷贝与L据库作比?br />
* 列出所有的用户
分析人员和质量评价h员常怼ȝ试数据Qƈ且需要改变他们。因此我们用VBA语句开发一个Excel应用E序Q从数据库里面提取数据到Excel文g中,允许用户修改q个文gQ修改后又返回到数据库中厅R当Ӟ也可以用其他工h览和编辑数据库的内容,但是我们使用excelQ因为很多h熟悉它?br />
目l的所有成员应该很Ҏ获取数据库设计的详细内容Q从而发C么表格可以获得,以及如何使用q些表格。我们徏立了ZHTML的工P使用servlets来查询数据库元数据。因此开发h员在d字段之前Q可以先通过搜烦表和字段的元数据来看一看数据库中有没有q个字段。我们用Erwin建模Q将数据从Erwin提取到我们的元数据表中?br />
6 l束?br />
当然Q这q不是敏h法在数据库设计中的全部应用,也不是数据库q化设计的全部,q有集成数据库和24*7时实施以及其他一些没有解决的问题Q数据库q化设计q需要进行进一步的研究工作?br />
]]>
可以是一对一、一对多、多对多的关pR在一般情况下Q它们是一对一的关p:即一张原始单据对应且只对应一个实体。在Ҏ情况下,它们可能是一对多或多对一的关p,即一张原始单据对应多个实体,或多张原始单据对应一个实体。这里的实体可以理解为基本表。明这U对应关pdQ对我们设计录入界面大有好处?
〖例1〗:一份员工历资料,在h力资源信息系l中Q就对应三个基本表:员工基本情况表、社会关p表、工作简历表。这是“一张原始单据对应多个实体”的典型例子?
2. 主键与外?/b>
一般而言Q一个实体不能既无主键又无外键。在EQR 图中, 处于叶子部位的实? 可以定义主键Q也可以不定义主?因ؓ它无子孙), 但必要有外?因ؓ它有父亲)?
主键与外键的设计Q在全局数据库的设计中,占有重要C。当全局数据库的设计完成以后Q有个美国数据库设计专家_“键Q到处都是键Q除了键之外Q什么也没有”,q就是他的数据库设计l验之谈Q也反映了他对信息系l核?数据模型)的高度抽象思想。因为:主键是实体的高度抽象Q主键与外键的配对,表示实体之间的连接?
3. 基本表的性质
基本表与中间表、时表不同Q因为它h如下四个Ҏ:
(1) 原子性。基本表中的字段是不可再分解的?
(2) 原始性。基本表中的记录是原始数据(基础数据Q的记录?
(3) 演绎性。由基本表与代码表中的数据,可以z出所有的输出数据?
(4) E_性。基本表的结构是相对E_的,表中的记录是要长期保存的?
理解基本表的性质后,在设计数据库Ӟp基本表与中间表、时表区分开来?
4. 范式标准
基本表及其字D之间的关系, 应尽量满第三范式。但是,满W三范式的数据库设计Q往往不是最好的设计。ؓ了提高数据库的运行效率,常常需要降低范式标准:适当增加冗余Q达CI间换时间的目的?
〖例2〗:有一张存攑֕品的基本表,如表1所C。“金额”这个字D늚存在Q表明该表的设计不满第三范式,因ؓ“金额”可以由“单价”乘以“数量”得刎ͼ说明“金额”是冗余字段。但是,增加“金额”这个冗余字D,可以提高查询l计的速度Q这是以空间换旉的作法?
在Rose 2002中,规定列有两种cdQ数据列和计列。“金额”这L列被UCؓ“计列”,而“单价”和“数量”这L列被UCؓ“数据列”?
? 商品表的表结?
商品名称 商品型号 单h 数量 金额
电视?29?2,500 40 100,000
5. 通俗地理解三个范?/b>
通俗地理解三个范式,对于数据库设计大有好处。在数据库设计中Qؓ了更好地应用三个范式Q就必须通俗地理解三个范?通俗地理解是够用的理解,q不是最U学最准确的理?Q?
W一范式Q?NF是对属性的原子性约束,要求属性具有原子性,不可再分解;
W二范式Q?NF是对记录的惟一性约束,要求记录有惟一标识Q即实体的惟一性;
W三范式Q?NF是对字段冗余性的U束Q即M字段不能由其他字D|生出来,它要求字D|有冗余?
没有冗余的数据库设计可以做到。但是,没有冗余的数据库未必是最好的数据库,有时Z提高q行效率Q就必须降低范式标准Q适当保留冗余数据。具体做法是Q在概念数据模型设计旉守第三范式,降低范式标准的工作放到物理数据模型设计时考虑。降低范式就是增加字D,允许冗余?
6. 要善于识别与正确处理多对多的关系
若两个实体之间存在多对多的关p,则应消除q种关系。消除的办法是,在两者之间增加第三个实体。这P原来一个多对多的关p,现在变ؓ两个一对多的关pR要原来两个实体的属性合理地分配C个实体中厅R这里的W三个实体,实质上是一个较复杂的关p,它对应一张基本表。一般来Ԍ数据库设计工具不能识别多对多的关p,但能处理多对多的关系?
〖例3〗:在“图书馆信息pȝ”中Q“图书”是一个实体,“读者”也是一个实体。这两个实体之间的关p,是一个典型的多对多关p:一本图书在不同旉可以被多个读者借阅Q一个读者又可以借多本图书。ؓ此,要在二者之间增加第三个实体Q该实体取名为“借还书”,它的属性ؓQ借还旉、借还标志(0表示借书Q?表示q书)Q另外,它还应该有两个外?“图书”的主键Q“读者”的主键)Q它能与“图书”和“读者”连接?
7. 主键PK的取值方?/b>
PK是供E序员用的表间q接工具Q可以是一无物理意义的数字? q序自动加1来实现。也可以是有物理意义的字D名或字D名的组合。不q前者比后者好。当PK是字D名的组合时Q徏议字D늚个数不要太多Q多了不但烦引占用空间大Q而且速度也慢?/p>
主键与外键在多表中的重复出现, 不属于数据冗余,q个概念必须清楚Q事实上有许多hq不清楚。非键字D늚重复出现, 才是数据冗余Q而且是一U低U冗余,即重复性的冗余。高U冗余不是字D늚重复出现Q而是字段的派生出现?
〖例4〗:商品中的“单仗数量、金额”三个字D,“金额”就是由“单价”乘以“数量”派生出来的Q它是冗余Q而且是一U高U冗余。冗余的目的是ؓ了提高处理速度。只有低U冗余才会增加数据的不一致性,因ؓ同一数据Q可能从不同旉、地炏V角色上多次录入。因此,我们提倡高U冗?z性冗?Q反对低U冗?重复性冗??
9. EQR图没有标准答?/b>
信息pȝ的EQR图没有标准答案,因ؓ它的设计与画法不是惟一的,只要它覆盖了pȝ需求的业务范围和功能内容,是可行的。反之要修改EQR图。尽它没有惟一的标准答案,q不意味着可以随意设计。好的EQ图的标准是Q结构清晰、关联简z、实体个数适中、属性分配合理、没有低U冗余?
10. 视图技术在数据库设计中很有?/b>
与基本表、代码表、中间表不同Q视图是一U虚表,它依赖数据源的实表而存在。视图是供程序员使用数据库的一个窗口,是基表数据综合的一UŞ? 是数据处理的一U方法,是用h据保密的一U手Dcؓ了进行复杂处理、提高运速度和节省存储空? 视图的定义深度一般不得超q三层?若三层视图仍不够? 则应在视图上定义临时? 在时表上再定义视图。这样反复交q定? 视图的深度就不受限制了?
对于某些与国家政沅R经、技术、军事和安全利益有关的信息系l,视图的作用更加重要。这些系l的基本表完成物理设计之后,立即在基本表上徏立第一层视图,q层视图的个数和l构Q与基本表的个数和结构是完全相同。ƈ且规定,所有的E序员,一律只准在视图上操作。只有数据库理员,带着多个人员共同掌握的“安全钥匙”,才能直接在基本表上操作。请读者想惻Iq是Z么?
11. 中间表、报表和临时?/b>
中间表是存放l计数据的表Q它是ؓ数据仓库、输出报表或查询l果而设计的Q有时它没有主键与外?数据仓库除外)。时表是程序员个h设计的,存放临时记录Qؓ个h所用。基表和中间表由DBAl护Q时表q序员自己用程序自动维护?
12. 完整性约束表现在三个斚w
域的完整性:用Check来实现约束,在数据库设计工具中,对字D늚取D围进行定义时Q有一个Check按钮Q通过它定义字D늚值城?
参照完整性:用PK、FK、表U触发器来实现?
用户定义完整性:它是一些业务规则,用存储过E和触发器来实现?
13. 防止数据库设计打补丁的方法是“三原则?/b>
(1) 一个数据库中表的个数越越好。只有表的个数少了,才能说明pȝ的EQR囑ְ而精Q去掉了重复的多余的实体QŞ成了对客观世界的高度抽象Q进行了pȝ的数据集成,防止了打补丁式的设计Q?
(2) 一个表中组合主键的字段个数少好。因Z键的作用Q一是徏主键索引Q二是做为子表的外键Q所以组合主键的字段个数了Q不仅节省了q行旉Q而且节省了烦引存储空_
(3) 一个表中的字段个数少好。只有字D늚个数了Q才能说明在pȝ中不存在数据重复Q且很少有数据冗余,更重要的是督促读者学会“列变行”,q样防止了子表中的字D|入到主表中去Q在主表中留下许多空余的字段。所谓“列变行”,是主表中的一部分内容拉出去,另外单独Z个子表。这个方法很单,有的人就是不习惯、不采纳、不执行?
数据库设计的实用原则是:在数据冗余和处理速度之间扑ֈ合适的q炏V“三”是一个整体概念,l合观点Q不能孤立某一个原则。该原则是相对的Q不是绝对的。“三多”原则肯定是错误的。试惻I若覆盖系l同L功能Q一百个实体(׃千个属? 的EQR图,肯定比二百个实体(׃千个属?的EQR图,要好得多?
提倡“三”原则,是叫读者学会利用数据库设计技术进行系l的数据集成。数据集成的步骤是将文gpȝ集成为应用数据库Q将应用数据库集成ؓ主题数据库,主题数据库集成为全局l合数据库。集成的E度高Q数据共享性就强Q信息孤岛现象就少Q整个企业信息系l的全局E—R图中实体的个数、主键的个数、属性的个数׃少?
提倡“三”原则的目的Q是防止读者利用打补丁技术,不断地对数据库进行增删改Q企业数据库变成了随意设计数据库表的“垃圑֠”,或数据库表的“大杂院”,最后造成数据库中的基本表、代码表、中间表、时表杂ؕ无章Q不计其敎ͼD企事业单位的信息pȝ无法l护而瘫痪?
“三多”原则Q何h都可以做刎ͼ该原则是“打补丁Ҏ”设计数据库的歪理学说。“三”原则是而精的原则,它要求有较高的数据库设计技巧与艺术Q不是Q何h都能做到的,因ؓ该原则是杜绝用“打补丁Ҏ”设计数据库的理Z据?
14. 提高数据库运行效率的办法
在给定的pȝg和系lY件条件下Q提高数据库pȝ的运行效率的办法是:
(1) 在数据库物理设计Ӟ降低范式Q增加冗? 用触发? 多用存储q程?
(2) 当计非常复杂、而且记录条数非常巨大?例如一千万?Q复杂计要先在数据库外面,以文件系l方式用C++语言计算处理完成之后Q最后才入库q加到表中去。这是电信计费系l设计的l验?
(3) 发现某个表的记录太多Q例如超q一千万条,则要对该表进行水q_剌Ӏ水q_割的做法是,以该表主键PK的某个gؓ界线Q将该表的记录水q_割ؓ两个表。若发现某个表的字段太多Q例如超q八十个Q则垂直分割该表Q将原来的一个表分解Z个表?
(4) Ҏ据库理pȝDBMSq行pȝ优化Q即优化各种pȝ参数Q如~冲Z数?
(5) 在用面向数据的SQL语言q行E序设计Ӟ量采取优化法?
MQ要提高数据库的q行效率Q必M数据库系l优化、数据库设计U优化、程序实现优化Q这三个层次上同时下功夫?
上述十四个技巧,是许多h在大量的数据库分析与设计实践中,逐步ȝ出来的。对于这些经验的q用Q读者不能生帮硬套,死记背Q而要消化理解Q实事求是,灉|掌握。ƈ逐步做到Q在应用中发展,在发展中应用?/p>
]]>
一?概念的区分?br /> 有些人把面向对象的数据库设计Q即数据库模式)思想与面向对象数据库理pȝ(OODBMS) 理论混ؓ一谈。其实前者是数据库用户定义数据库模式的思\Q后者是数据库管理程序的思\。用户用面向对象方法学可以定义M一UDBMS数据库,即网l型、层ơ型、关pd、面向对象型均可Q甚x件系l设计也照样可以遵@面向对象的思\。?br />
面向对象的思\或称规范可以用于pȝ分析、系l设计、程序设计,也可以用于数据结构设计、数据库设计。OOSE自上至下、自始至l地贯彻面向对象思\Q是一个一气呵成的l一体。面向对象的数据库设计只?OOSE 的一个环节。?br />
二?数据库设计的重要性?br /> 一般数据库设计Ҏ有两U,卛_性主导型和实体主导型。属性主导型从归Ux据库应用的属性出发,在归q属性集?实体)时维持属性间的函C赖关pR实体主导型则先从寻扑֯数据库应用有意义的实体入手,然后通过定义属性来定义实体。一般现实世界的实体数在属性数 1/10 以下Ӟ宜用实体主导型设计Ҏ。面向对象的数据库设计是从对象模型出发的Q属于实体主导型设计。?br />
一般数据库应用pȝ都遵循以下相兛_发步骤:1设计应用pȝl构Q? 选择便于应用程序与 DBMS l合的DBMS体系l构Q如RDBMSQ? Ҏ应用E序使用的环境^収ͼ选择适宜的DBMS(如Oracle)和开发工?如PB)Q? 设计数据库,~写定义数据库模式的SQLE序Q? ~写保数据正确录入数据库的用户接口应用E序Q? 录入数据库数据;7 q行各种与数据库相关的应用程序,以确认和修正数据库的内容。?br />
对以上各步骤Q有几点需要说明:
(1)q不是瀑布模型Q每一步都可以有反馈。?br />
在公路局pȝ中,以上各步不仅有反馈、有反复Q还有ƈ行处理。比如一些库表在数据录入Ӟ另一些库表设计还在修攏V这与我们的递增式开发方法有养I也与面向对象的特征有兟뀂?br />
(2)上述序不是l对的,大多数场合是从第三步开始的。?br />
(3)对大多数数据库应用系l来_上述各步中最重要、最困难的不是应用系l设计而是数据库设计。?br />
三?DBMS的支持和数据库设计?br /> 很多数据库应用系l开发者不重视数据库设计的原因是:他们太迷信DBMSQ认入一个功能强大的 DBMS后数据库设计׃困难、不重要了。一些国内外的数据库教材常常是在为DBMS的开发厂商做宣传Q而很站在数据库用户角度Q从数据库应用系l出发介l数据库设计Ҏ。结果往往使读者搞不清书中介绍的是数据库管理程序的设计思想Q还是应用这U?DBMS q行数据库设计的思想。?br />
其实QDBMS只是l用户ؓ已采用的数据库提供一个舞収ͼ而是否用这个舞C的道具以及唱什么戏Q则完全取决于用L戏剧脚本和导?开发?的安排。例如,公\局pȝ所使用的数据库理pȝQ是以二l表为基本管理单元、支持所有关pM数操作、支持实体完整性与实体间参照完整性的全关pd RDBMSQ而我们要在这个舞C利用上述“道具”设计一个面向对象的关系数据库。?br />
四?应用对象模型与RDBMS模型的映?br /> 数据库设?模式)是否支持应用pȝ的对象模型,q是判断是否是面向对象数据库pȝ的基本出发点。由于应用系l设计在前,数据库设计随后,所以应用系l对象模型向数据库模式的映射是面向对象数据库设计的关键。?br />
1.三层数据库模式面向对象模型的扩展
一般数据库设计多参照ANSL/SPARC关于数据库模式的3层标准结构提案。最接近物理数据库的内部模式?DBMS 提供的SQL来描q。概忉|式可以由若干个内部模式聚集而成Q它是由数据库用戯范的一些表的集合。例如,公\局计划处数据库模式、机务处数据库模式等Q它们是逻辑数据库,常常通过库表 ID来界定库边界。一般的概念模式是数据库物理模式作用域的边界Q它能实现数据库的物理意义、特定DBMS 的特D操作对外部应用E序的信息隐蔽。外部模式是从特定用户应用角度看待的数据库模式,从不同的应用出发对同一概念模式可以l出多种不同的外部模式。例如:公\l化情况查询应用看到的数据库是公路上的树木种cR数量、分布比率等Q桥梁隧道状冉|询应用看到的是公路上的桥梁、隧道长度、个数、\D늭Q但是它们可能访问的是同一个库表的不同子集。?br />
当外部应用系l以对象模型q行抽象Ӟ从各个应用出发抽象出的对象模型可以映到外部模型上,Ҏ我们不妨UC为外部对象模型。但是,外部模型只是概念模型的子集,所以面向对象的数据库设计核心在于系l对象模?不妨UC为概念对象模? 向数据库概念模型的映?参见?) 。?br />
2.对象模型向数据库表的映射规则
׃ RDBMS 是以二维表ؓ基本理单元的,所以对象模型最l是׃l表及表间关pL描述的。换a之,对象模型向数据库概念模型的映就是向数据库表的变换过E。有关的变换规则单归U_下:
Q?Q一个对象类可以映射Z个以上的库表Q当c间有一对多的关pLQ一个表也可以对应多个类。?br />
? 三层数据库模式面向对象模型的扩展
Q?Q关p?一对一、一对多、多对多以及三项关系)的映可能有多种情况Q但一般映ؓ一个表Q也可以在对象类表间定义相应的外键。对于条件关pȝ映射Q一个表臛_应有3个属性。?br />
Q?Q单一l承的泛化关pd以对类、子cd别映表Q也可以不定义父c表而让子类表拥有父cd性;反之Q也可以不定义子c表而让父类表拥有全部子cd性。?br />
Q?Q对多重l承的超cd子类分别映射表,对多ơ多重承的泛化关系也映一个表。?br />
Q?Q对映射后的库表q行冗余控制调整Q其达到合理的关系范式。?br />
3.数据库模式要面向应用pȝ
我们选择面向对象的系l设计也好,面向对象的数据库设计也好Q根本目的是服务于应用系l的需要。?br />
以公路局计划处子pȝZ。计划处的最大工作量是处理成堆的报表,因此如何有效地存取这些报表是计划处数据库设计的关键。考虑到每月上交的报表是同构的Q我们可以创Z张库表去存储同一U报表,例如公\工程月报表。但是又产生另一个问题,当用h查询某个月的公\工程月报表时Q如何从库表中取出数据呢?按照数据库的思想应该有一个主键来标识q张报表。在公\局的报表里Q区别月报表靠上报时间和上报单位Q但如果为每条记录都加上q两个字D,无疑会加大库表冗余,增加查询旉Q降低效率。更何况每张报表都有单位负责人、填表h的属性,那么怎样解决q个问题呢?我们设计了超cd?X3 表和水可。X3 表和水可的表l构如下。?br />
? X3表和水可的表l构Q?br />
它们加入由应用对象模型映射出的数据库概忉|型后Q得到图2所C的l构。?br />
每一个应用模块对象对应徏立一张流水号表,同一cȝ报表属同一水可Q由水可l一理。流水号表对各分局、处室提交和建立的每一张报表分配一个流水号Q该水号在整个数据库中是唯一的,因此在库中存放Q何一张报表都是明的。流水号的数据类型ؓ Char(10)Q前4位ؓ表号Q后6位ؓ序列P其中序列号取?X3表中最大序列号。也是_水号就是对象标识符Q报表是一个对象,一个对象标识符唯一军_一个对象。流水号一旦被分配出去后,在这张报表的生存期内具有了怹不变性。无论报表的内容及结构怎么变化Q它都不变,直到报表被删除,水h会消失。流水号表是父类Q报表是子类Q流水号表之间的联系只能通过 X3 表?个应用模块对象完全映到数据库概忉|型中QŞ成应用对象与数据库对象的一一对应Q保持了5个应用对象在目标pȝ设计中原有的独立性,h很好的封装性和信息隐蔽性。尽流水号表会有一些冗余,但它是值得的。?br />
? 类对象间关pȝ意图
五?面向对象关系数据库设计效果?br /> 在公路局pȝ设计中,从某U意义上Ԍ是数据库设计的面向对象特征最l奠定了整个pȝ的面向对象性,才面向对象Ҏ在程序开发阶D全面开花。其效果归纳如下Q?br />
1.数据库结构清晎ͼ便于实现OOP
׃实现了应用模块对象对数据库对象的完全映射Q数据库逻辑模型可以自然且直接地模拟现实世界的实体关pR公路局用户所处的当前物理世界、系l开发者所抽象的系l外部功能,与支持系l功能的内部数据?(数据l构)一一对应Q所以用戗开发者和数据库维护h员可以用一致的语言q行沟通?特别是对多数不了解公路局业务的程序开发h员来_q种应用对象与相应的数据对象封装在对象l一体中的设计方法,大大减轻了程序实现的隑ֺQ他们只要知道加工的数据及所需的操作即可,而且应用E序大多雷同Q可以多处承由设计人员抽象出来的、预先开发好的各U物理类。?br />
2.数据库对象具有独立性,便于l护
除了数据库表对象与应用模块对象一一对应外,在逻辑对象模型中我们没有设计多重承的泛化关系Q所以这样得到的数据库结构基本上是由父表cd子表cL成的树型层次l构Q表c间很少有承以外的复杂关系Q是一个符合局部化原则的结构,从而数据库表数据破坏的媄响控制在局部范围且便于修复Q给公\局pȝ开通后的数据库日常l护工作带来便利。?br />
3.需求变更时E序与数据库重用率高Q修改少
在映应用对象时Q除关系映射规范化后可能出现一对多的表映射外,大多数应用对象与表对象是一一对应的。我们可以把规范化处理后的、由一个应用对象映出来的多个表看成一个数据库对象。因此当部分应用需求变更时Q首先,pȝ修改可以不涉及需求不变更的部分。其ơ,变更部分的修改可以基本上只限于追加或删除E序模块或追加新库表Q而基本上不必修改原有E序代码或原有库表定义,从而大大减了工作量,降低了工作难度。?br />
六?最单的是最好的
客观世界是错l复杂的Q计机U学理论的发展也来高深、复杂。然而,人类探烦理论和技术的最l目的是Q让客观世界的复杂变单,最单的是最好的。ؓ此我们给Z下几点忠告:
1. 慎用外键
RDBMS 支持复杂关系的能力很强,无论用户怎么在逻辑上设定外键,它基本上都能从物理上帮用户实现。但是外键把许多独立的实体牵q在一P不仅?RDBMS l持数据一致性负担沉重,也数据库应用复杂化Q加重了E序开发负担。这L数据库很隄解,很难实现信息隐蔽性设计,往往把简单问题复杂化。?br />
2. 适当冗余
减少数据库冗余的设计思\产生?0q代Q它是促?DBMS q步的重要动力之一。然而,犹如Z节省2个字节的存储I间而酿成了如今全球Z头痛?000q问题一P它是计算机硬件主导时代的产物。以今天国内计算机市Zhgؓ例,6G服务器硬盘的h不过2000元,而上L价局 1996 q颁发的一个h月Y件开发的指导L8000元,即一个h月的软gh可以购?0G左右的硬盘。即使有5万行数据的库表,每个记录压羃40字符的冗余,单纯计算合计也不?MQ即节省0.6元钱的磁盘空间。?br />
今天的世界已q入软gd的计机时代。因此,最Ҏ理解、应用开发工作量最、维护最单的数据库结构才是最好的。只要数据完整性、一致性不受威胁,有些冗余Q不ؓ虑。换a之,最节省软g成本 (而不是硬件成? 的是最好的。?br />
3. 信息隐蔽
q是软g工程最重要的基本原则之一。简a之即信息的作用域小好Q数据库的透明度越大越好,因ؓ应用E序需要知道得多p复杂。数据库黑盒化 (透明度高) 的方法很多,除了设计上的局部化处理外,q可以利?DBMS 的触发器、存储过E、函数等Q把数据库中无法化的复杂表关pd装到黑盒子里Q隐藏v来,特别是放到服务器端,其优性更是多斚w的?
]]>
数据仓库和我们常见的RDBMSpȝ有些亲缘关系Q但它又有所不同。如果你没有实施q数据仓库,那么从设定目标到l出设计Q从创徏数据l构到编写数据分析程序,再到面对挑剔的用L评估Q整个过E都会带l你一U与以往的项目完全不同的体验。一句话Q如果你试图以旧有的方式创徏数据仓库Q那你所面对的不是预超支就是所建立的数据仓库无法良好运作。?br />
在处理一个数据仓库项目时需要注意的问题很多Q但同时也有很多有徏设性的参考可以帮助你更顺利的完成d。开放思维Q不断尝试新的途径Q对于找CU可行的数据仓库实现Ҏ来说也是必需的。?br />
1. 配备一个全职的目l理或你自己全面负责目理
在通常情况下,目l理都会同时负责多个目的实施。这么做完全是出于资金和IT资源斚w的考虑。但是对于数据仓库项目的理Q绝对不能出Cn兼数个项目的情况。由于你所处的领域是你和你的团队之前没有进入过的领域,有关数据仓库的一切-数据分析、设计、编E、测试、修攏V维护-全都是崭新的Q因此你或者你指派的项目经理如果能全心投入Q对于项目的成功会有很大帮助。?br />
2. 项目管理职责推l别的项目经?/font>
׃数据仓库实现q程实在是太困难了,Z避免自虐Q你可以在当前阶D늚目完成后就项目管理职责推l别的项目经理。当Ӟq个新的目l理一定要复合W一条所说的h全职性。ؓ什么要q么做呢Q首先,从项目经理的角度看,数据仓库实施q程的Q何一个阶D都以让hw心疲惫。从物理存储讑֤的开发到Extract-Transform-Load的实玎ͼ从设计开发模型到OLAPQ所有阶D都明显的比以前接触的项目更加困难。每个阶D不但需要新的处理方法、新的管理方法,q需要创新性的观点。所以将理职责推给别的目l理不但不会寚w目有损害Q还可以起到帮助作用?br />
3.与用戯行沟?/font>
q里所讲的内容q比一文章本w要重要的多。你必须明白Q在数据仓库的设计阶D,那些潜在用户自己也不清楚他们到底需要数据仓库ؓ他们做什么。他们在不断的探索和发现自己的需求,而你的开发团队也在和客户的接触中做着同样的事情。更加频J的与客h触,多做记录Qƈ让你的团队更x于项目需求讨论的l果而不是讨论的q程本n?br />
既然你和客户的交是Z了解存储的数据是何种cd以及如何有效存储数据Q你也许需要(和你的用户一P采用一U新的方法观察数据,而不是直接处理数据。你可以试从中扑և隐藏的信息,比如在一D|期内的数字涨落等。不要试图追寻项目需求的{案Q而是要让{案找上门来?br />
4. 以技?信息库作为领?/font>
׃数据仓库实施的各个阶D都有很大不同,因此你需要有起到l持整个目的连l进行的作用Q不q这个职责ƈ不需要那U全职性。项目实施有三个重要斚wQ架构、技术和业务。将架构作ؓ重点可以保证在整个项目中Q数据仓库的架构从物理层往上,都会受到良好的维护。而我们应该将技术作为重点,因ؓ开发团队和关键用户都在使用他们以前从未用过的工P必须有h监督开发过E以及工具用的一致性?br />
最后,在数据仓库的应用q程中Q现出来的业务需求必被详细分析和记录,以促机开发过E持l下厅R如果用户不能很好的开发h员以及其它用h通,那么数据分析和度量方面的开发进E就会g期,所以必L人关注业务方面的开发,推动开发进入更高别?br />
5. 跛_反复修改E序的陷?/font>
W一ơ实现的数据仓库肯定不会是最l交付的版本。ؓ什么呢Q实际上在真正见C品前Q你无法定的知道自q目标是什么。或者说Q最l用户只有在使用数据仓库产品一D|间后Q才能明告诉你q个产品是不是他所希望的。与你以往处理的项目不同,业务q处于发展的初期Q每个公司对业务都有不同的解释,因此你的目决不会一ơ成功?br />
Z以正的格式获得数据Q你需要在不断变化的状况中摸烦前进。BIh很强的个性,不同的环境、不同的市场以及不同的企业都有不同的BI。这又代表什么呢Q这表示你需要把数据库管理员攑֜一个消息相对封闭的环境中,不要让他知道数据仓库的数据结构以及ETLE序在不断的改变。对此没有别的办法。这样可以减M和DBA所承受的压力?br />
6. 对大量的前端资源q行数据源分?/font>
在数据仓库实现过E中Q你不得不在旧有的数据中艰难跋涉Q这些数据来自老的数据库、老的带Z及远E的数据。它们中的大部分都凌׃堪,q且难以获取。你要对q些数据q行大量处理Qƈ且还要设计ETLE序来寻扑օ中的有用信息。如果你希望整个目做v来比较顺利,q且扑ֈ一U方法能够一ơ成功,那就需要你的开发h员必花费够的旉来充分研I这些旧有数据,凌q数据规则化,q尽力设计和实现强壮的数据采集和转换q程。数据仓库的ETL部分会占用整个项目资源的癑ֈ之八十,所以一定要定你的资源都用在刀刃上了?br />
7. h际关pd理放在首?/font>
在数据仓库实现过E中真正的地׃是来自技术或者开发方面,而是来自你周围的人。你也许会遇C个对目q不乐观而又没时间听你陈q的领导。你也许会遇C些开发h员将q度拖g太长旉q抱怨ؓ什么不能用老方法实施。你也许q会遇到一些抱有不切实际的qL的用P他们希望ȝ鼠标p实现惌中的功能Q但却不愿在他们那边多做些智力投资,更好的培训他们自q员工。而你也已l疲惫不堪,鼓励投资Q以及在开发团队和用户Q甚臌板Q中推广新的开发技巧?br />
M你要保持微笑。当一切搞定,你的烦恼也就一扫而空了,W到最后才W得最L?br />
数据仓库开发过E中的七个禁忌?/b>
q去我们一直用的OLTP技术也讔R藏着许多严重的缺陗数据仓库的实现q不是一个简单的dQ你会发C前积累下来的丰富l验Qƈ不适合处理每个数据仓库的独牚w求。?br />
下面列出的条ƾ是你在实现数据仓库q程中一定会面对的问题,其中一些看hq没有想象中那么严重Q但是你q是应该量避免出现cM问题。数据仓库ƈ不是一个事务处理系l,它没有一定的标准也不会实现某个特定的应用Q但它本质上是非常有l织性的。MQ每个公司所建立的数据仓库都是唯一的,q且每一ơ数据仓库的实现Ҏ都不是一成不变的。在实现数据仓库旉要注意的不单?应该如何?Q更要注?不该如何?。下面就是我们ȝ的七?不该如何?。?br />
1.不要~写自己无法快速修改的代码
你所要编写的E序主要用于数据分析Q而不是处理事务。而你的用户也q不真正知道他们自己真正惌一个什么样的程序。因此你不得不反复修改代码好几次Q才会明白用户到底需要一个什么样的程序。如果你~写的程序具有良好的l构和灵zL,q需要修改也不会太浪费力气。反之,你会被自q歅R?br />
2. 不要使用无法修改的数据库讉KAPI
在过去,你的数据库可以ؓ大量的客h供稳定的数据查询服务。而如今,你的E序必须能够应付更多的数据查询。这使得重新改写E序以得每个查询请求能得到最大的数据量成为势在必行的工作Q而一般来说这U代码修攚w不会一ơ成功,所以只有选择合适的可以修改的APIQ才能ɽE序快适应新的需求。?br />
3. 不要设计M无法扩展的东?/font>
在联机处理过E(OLTPQ应用中Q数据分析ƈ不是一个真正的应用E序。实际上Q数据分析的关键是获取大量旧的数据,从中提取数据模型Qƈ以此模型推断出新的信息。而你所~写的访问潜在信息的代码应该h可扩展性,可以附加新的数据。千万别在支持数据分析的代码中假定数据都是固定格式的。?/p>
一个仓库要做的是恰到好处的服务Q用戯q仓库,从货架上取得自己所需得信息,仅此而已。由于业务智能、分析以及规律性的问题都有各自的处理程序,因此你的客户唯一的需要就是获取信息。他们需要一U应用环境,可以让他们快速的从数据仓库中取得分析q程所需的数据,而不个数据是什么样子的。也怽惛_助他们精g下获得的数据Q但最好不要这么做。一定要CQ不要给客户的数据分析程序添加Q何会影响数据讉K性能的功能?br />
5. 不要化数据清除和数据源分析的步骤
在实现数据仓库过E中最应该注意的地方就是ؓExtract-Transform-Load机制分析数据源,以及Z化负载而清除数据。安全的做法是假N目经理在q个阶段会需要整个项目资源的一半以上。相反,如果你在q方面进行了化,E后肯定会后悔。所以就系l工作缓慢,也不要简化清理旧的数据的q程?br />
6. 不要避免颗粒度和分区问题
在数据仓库设计过E中有两个最大的数据存储问题Q第一是如何给转换数据定位一个恰当的颗粒度等U,W二是如何将数据l对的分区。ؓ什么这两点问题如此重要呢?因ؓ整个数据仓库的响应能力受颗粒度媄响,q且数据讉K的效率直接与数据分区性能有关。因此这是具有关键性的工作Q不要试N免面对这些问题?br />
7. 不要在没考虑业务问题前就使用OLAP
用户在亲D到程序前通常都不知道自己到底惌个什么样的程序。因此他们的观点有不错误,比如他们希望分析l果会忠实反应性能度量Q或者希望程序会使他们部门或公司的业务工作有所不同。而你必须跛_自己的职责范_从IT理者的角度考虑用户部门直至整个企业的运行方式,才能在开发过E中避免q类问题。在通常的OLTP开发中Q你可以比较方便的理解业务流E。而在联机分析处理QOLAPQ领域,M事情都需要亲自考察Q而在你周围工作的Z许ƈ不会发现你对业务斚w存在的误解。因此,不要自以为已l了解了_的信息。不断的询问才能使你真正了解"业务"中的"业务"到底是什么样子的
利开发数据仓库的七种思\
对于大多数ITN来说Q实C个数据仓库的隑ֺ比以前做q的M目隑ֺ都要大。考虑C同的数据l构、用途以及应用程序开发方法,以前所U篏的经验和技巧大部分都无用武之地了。但是只要在你的前进道\上稍加修正,你就会发现实C个数据仓库ƈ不是难事Q就你是第一ơ实现数据仓库也没问题。?br />
下面列出了数据仓库实施过E需要考虑的步骤,有一些你可能从来没有意识刎ͼ而另一些可能已l在实施q程中用到了,但是重新思考一番也怽会有更多的领悟。开放思维Q不断尝试新的途径Q找CU可行的数据仓库实现Ҏ。?br />
1. 再三考虑应用E序的实现方?/font>
数据仓库q不涉及事务处理Qƈ且在报表斚w也仅占一部分。而数据仓库应用程序的本质是分析,其是针对业务智能的分析。BIq不是通常所说的数据Q它是一U从旧有数据?模型化得到的新的数据。那么如何才能从旧有数据中挖些新数据呢?事实上,q个工作不是让你来完成的Q而是你的客户所要完成的。从目ȝ的角度看Q应该有一个经验丰富的数据表格设计师与你合作,q而决定如何将各类E序融合在一赗其中所遇到的最主要的挑战将是如何用新的Ҏ观察数据Q这也是你的客户正在试图使用的方法。?br />
2. 创徏抽象的、良好部|的数据库访问组?/font>
在过M接触q的数据库项目和现在的数据仓库之_有一点绝对不同,那就是:在Online Transaction Processing QOLTPQ环境中Q用h量非常大Q但使用到的数据却比较少Q而在Online Analytical Processing QOLAPQ环境中情况却正好相反,量的用户在使用大量的数据。而你的工作就是编写一个应用程序来优化q种不同。这里有一个线索:在你所有的分析E序中,都要能抓取连l的数据,q样在以后徏立和讉K的数据结构中才能存放与原数据物理l构cM的数据。具体如何实现呢Q首先不要规格化数据。第二将其放入数l中最化dh数。按照这U方法,DBA会很乐意与你合作?br />
3. 保持松散
现在回头看看W一步,你应该可以理解定义一个分析程序不是g单事了,而且一般情况下Q很隑֜W一ơ就实现W合要求的最l品。而在你将要进行分析的数据l构上同样存在这U问题。一句话Q实现过E会有很多变敎ͼ你需要不断的改动你的E序。通常我们都希望将改动ơ数降到最低。在一个数据仓库实现过E中Q本质是要分析过E毫无差错,q也需要DBA的参与。不要死抓住你的E序设计、代码、框图,或你建立的其它什么东西不放手Q要Ҏq种变化而不断进行调整?br />
4. 管理放在首?/font>
在分析数据源斚w你做的如何呢Q你是否认ؓ清理垃圾数据的工作非常困难?q不是只有你一个hq样惻I做过cM工作的h都有q种看法。在一个一般规模的机构中,作ؓ数据仓库实现q程的一部分Q会有大量的旧有数据必须q行一致性处理。所以分析数据源q花Ҏ个小时编写{换程序将旧有数据导入数据仓库是整个数据仓库实现过E中最艰难的一部分。ƈ且这也是整个目中最重要的一环,可以占到整个目周期和预的四分之三。所以一定要心对待?br />
5. 从字里行间发现问?/font>
与用户交是个很ȝ的事情,Z么这么说呢?因ؓ很多用户在见到最l品前都不知道自己惌什么样的品。定义数据仓库应用程序是一个探索的q程Q而且q个q程要反复进行。记住所谓的"业务"是用戯己定义的Q他们按照自q理解来处理业务流E。因此这些用户就是连接数据和业务处理q程间的桥梁。他们所要的q不是数据本w,而是隐藏在数据后面的性。你可以让他们讨论、思考ƈl出性的意见。但千万不要让他们解x让他们Q意想象和发表那些"有可?的观炏V最后,一定要随时留意用户得出的结论?br />
6. 保持领先
数据仓库看v来没有传l的OLTP模式Ҏ蒂固Q事实如此。虽然很多h投n数据仓库的开发中Q但׃其框架与以前的系l大相径庭,因此在开始的一D|间数据仓库的实现看上ȝ当乱。但是坚持下L很重要的。它h两方面重要的作用?br />
W一Q技术的领先性。它可以跟踪目中Q何阶D늚软g工具的部|和正确使用Q以及开发过E。如果这复合你的背景Q你可以Ҏ多加留意?br />
W二Q体pȝ构的领先性。它使得目在各个阶D{换时Q数据仓库和它所支持的系l的物理以及逻辑架构都具有持l性,不会发生改变。这也是你能提供的?br />
7. 发出警告
最后你要记住,你ƈ不是唯一M新大陆的人。你周围的每一个h都会有下面一Ҏ几点问题Q不现实的期望、对技术的误解、旧习惯或坏习惯、竞争行为,或缺乏对目的信d。虽然交沟通等d应该是项目经理负责的Q但实际上你也要担负L同的责Q。那么作为技术ȝ你该怎么作呢Q首先当然是要真诚的对待周围的hQ但一定要竖立威信Q适当的发告。当你发现项目进度缓慢、资源流失,或者员工失ȝ标,p直言不讳的说出来。快速明的l予警告在大部分情况下都是明Z举。匆忙上马的数据仓库目也许会出轨,但不要让p|的项目把你拉下马?/p>
在这里,我不打算介绍使用SQL Server的窍门,也不能提供一个包ȝ病的ҎQ我所做的是ȝ一些经?---关于如何形成一个好的设计。这些经验来自我q去几年中经受的教训Q一直来Q我看到许多同样的设计错误被一ơ又一ơ的重复?/p>
你了解你的工具吗Q?/font>
不要轻视q一点,q是我在q篇文章中讲q的最关键的一条。也怽也看到有很多的SQL ServerE序员没有掌握全部的T-SQL命o和SQL Server提供的那些有用的工具?/p>
“什么?我要费一?font size="2">?/font>的时间来学习那些我永q也不会用到的SQL命oQ?Q”,你也怼q样说。对的,你不需要这样做。但是你应该用一个周末浏览所有的T-SQL命o。在q里Q你的Q务是了解Q将来,当你设计一个查询时Q你会记hQ“对了,q里有一个命令可以完全实现我需要的功能”,于是Q到MSDN查看q个命o的确切语法?/p>
不要使用游标
让我再重复一遍:不要使用游标。如果你想破坏整个系l的性能的话Q它们倒是你最有效的首选办法。大多数的初学者都使用游标Q而没有意识到它们Ҏ能造成的媄响。它们占用内存,q用它们那些不可思议的方式锁定表Q另外,它们直就像蜗牛。而最p糕的是Q它们可以你的DBA所能做的一切性能优化{于没做。不知你是否知道每执行一ơFETCHq于执行一ơSELECT命oQ这意味着如果你的游标?0000条记录,它将执行10000ơSELECTQ如果你使用一lSELECT、UPDATE或者DELETE来完成相应的工作Q那有效率的多?/p>
初学者一般认Z用游标是一U比较熟悉和舒适的~程方式Q可很不q,q会Dp糕的性能。显ӞSQL的M目的是你要实C么,而不是怎样实现?/p>
我曾l用T-SQL重写了一个基于游标的存储q程Q那个表只有100,000条记录,原来的存储过E用?0分钟才执行完毕,而新的存储过E只用了10U钟。在q里Q我想你应该可以看到一个不U职的程序员I竟在干了什么!Q!
我们可以写一个小E序来取得和处理数据q且更新数据库,q样做有时会更有效。记住:对于循环QT-SQL无能为力?/p>
我再重新提醒一下:使用游标没有好处。除了DBA的工作外Q我从来没有看到q用游标可以有效的完成M工作?/p>
规范化你的数据表
Z么不规范化数据库Q大概有两个借口Q出于性能的考虑和纯_因为懒惰。至于第二点Q你q早得ؓ此付Z仗而关于性能的问题,你不需要优化根本就不慢的东ѝ我l常看到一些程序员“反规范化”数据库Q他们的理由是“原来的设计太慢了”,可结果却常常是他们让pȝ更慢了。DBMS被设计用来处理规范数据库的,因此Q记住:按照规范化的要求设计数据库?/p>
不要使用SELECT *
q点不太Ҏ做到Q我太了解了Q因为我自己q常这样干。可是,如果在SELECT中指定你所需要的列,那将会带来以下的好处Q?/p>
1 减少内存耗费和网l的带宽
2 你可以得到更安全的设?/p>
3 l查询优化器Z从烦引读取所有需要的?/p>
了解你将要对数据q行的操?/font>
Z的数据库创徏一个健壮的索引Q那可是功d一件。可要做到这一点简直就是一门艺术。每当你Z个表d一个烦引,SELECT会更快了Q可INSERT和DELETE却大大的变慢了,因ؓ创徏了维护烦引需要许多额外的工作。显Ӟq里问题的关键是Q你要对q张表进行什么样的操作。这个问题不太好把握Q特别是涉及DELETE和UPDATEӞ因ؓq些语句l常在WHERE部分包含SELECT命o?/p>
不要l“性别”列创徏索引
首先Q我们必M解烦引是如何加速对表的讉K的。你可以烦引理解ؓZ一定的标准上对表进行划分的一U方式。如果你l类g“性别”这L列创Z一个烦引,你仅仅是表划分Z部分Q男和女。你在处理一个有1,000,000条记录的表,q样的划分有什么意义?CQ维护烦引是比较Ҏ的。当你设计烦引时Q请遵@q样的规则:Ҏ列可能包含不同内容的数目从多到少排列Q比如:姓名+省䆾+性别?/p>
使用事务
请用事务,特别是当查询比较耗时。如果系l出现问题,q样做会救你一命的。一般有些经验的E序员都有体?----你经怼到一些不可预料的情况会导致存储过E崩溃?/p>
心死锁
按照一定的ơ序来访问你的表。如果你先锁住表AQ再锁住表BQ那么在所有的存储q程中都要按照这个顺序来锁定它们。如果你Q不l意的)某个存储q程中先锁定表BQ再锁定表AQ这可能׃D一个死锁。如果锁定顺序没有被预先详细的设计好Q死锁是不太Ҏ被发现的?/p>
不要打开大的数据?/font>
在CSDN技术论坛中 :Q,一个经常被提出的问题是Q我怎样才能q速的?00000条记录添加到ComboBox中?q是不对的,你不能也不需要这样做。很单,你的用户要浏?00000条记录才能找到需要的记录Q他一定会诅咒你的。在q里Q你需要的是一个更好的UIQ你需要ؓ你的用户昄不超q?00?00条记录?/p>
不要使用服务器端游标
与服务器端游标比hQ客L游标可以减少服务器和|络的系l开销Qƈ且还减少锁定旉?/p>
使用参数查询
有时Q我在CSDN技术论坛看到类DL问题Q“SELECT * FROM a WHERE a.id='A'BQ因为单引号查询发生异常Q我该怎么办?”,而普遍的回答是:用两个单引号代替单引受这是错误的。这h标不LQ因Zq会在其他一些字W上遇到q样的问题,更何况这样会D严重的bugQ除此以外,q样做还会SQL Server的缓冲系l无法发挥应有的作用。用参数查询, 釜底抽薪Q这些问题统l不存在了?/p>
在程序编码时使用大数据量的数据库
E序员在开发中使用的测试数据库一般数据量都不大,可经常的是最l用L数据量都很大。我们通常的做法是不对的,原因很简单:现在盘不是很贵Q可Z么性能问题却要{到已经无可挽回的时候才被注意呢Q?/p>
不要使用INSERT导入大批的数?/font>
请不要这样做Q除非那是必ȝ。用UTS或者BCPQ这样你可以一举而兼得灵zL和速度?/p>
注意时问题
查询数据库时Q一般数据库的缺省都比较,比如15U或?0U。而有些查询运行时间要比这长,特别是当数据库的数据量不断变大时?/p>
不要忽略同时修改同一记录的问?/font>
有时候,两个用户会同时修改同一记录Q这P后一个修改者修改了前一个修改者的操作Q某些更新就会丢失。处理这U情况不是很难:创徏一个timestamp字段Q在写入前检查它Q如果允许,合q修改,如果存在冲突Q提C用戗?/p>
在细节表中插入纪录时Q不要在主表执行SELECT MAX(ID)
q是一个普遍的错误Q当两个用户在同一旉插入数据Ӟq会D错误。你可以使用SCOPE_IDENTITYQ?code>IDENT_CURRENT?code>@@IDENTITY。如果可能,不要使用@@IDENTITYQ因为在有触发器的情况下Q它会引起一些问题(详见q里?a >讨论Q?/font>
避免列设ؓNULLable
如果可能的话Q你应该避免列设ؓNULLable。系l会为NULLable列的每一行分配一个额外的字节Q查询时会带来更多的pȝ开销。另外,列设ؓNULLable使编码变得复杂,因ؓ每一ơ访问这些列旉必须先进行检查?/font>
我ƈ不是说NULLS是麻烦的ҎQ尽有些hq样认ؓ。我认ؓ如果你的业务规则中允许“空数据”,那么Q将列设为NULLable有时会发挥很好的作用Q但是,如果在类g面的情况中用NULLableQ那直就是自讨苦吃?/font>
CustomerName1
CustomerAddress1
CustomerEmail1
CustomerName2
CustomerAddress2
CustomerEmail3
CustomerName1
CustomerAddress2
CustomerEmail3
如果出现q种情况Q你需要规范化你的表了?/code>
量不要使用TEXT数据cd
除非你用TEXT处理一个很大的数据Q否则不要用它。因为它不易于查询,速度慢,用的不好q会费大量的空间。一般的QVARCHAR可以量不要使用临时?/font>
量不要使用临时表,除非你必这样做。一般用子查询可以代替临时表。用时表会带来系l开销Q如果你是用COM+q行~程Q它q会l你带来很大的麻烦,因ؓCOM+使用数据库连接池而时表却自始至l都存在。SQL Server提供了一些替代方案,比如Table数据cd?/code>
学会分析查询
SQL Server查询分析器是你的好伙_通过它你可以了解查询和烦引是如何影响性能的?/code>
使用参照完整?/font>
定义d、唯一性约束和外键Q这样做可以节约大量的时间?/code>
当你向决{者们陈述自己对于数据仓库的实施计划时Q不要将投资回报作ؓ争取投资的筹码。因Z没有定q数据仓库会对生产效率或者市Z解度的增长vC么作用,因此你无法提供一个投资回报计划。由于没有Q何数据仓库的l验Q因此你也就无法量化其带来的好处。事实上Q实施数据仓库的首要原因是要开发企业的业务能力Q它会教l你如何明确的测量市Z解度的增ѝ也是_你在甌旉和经Ҏ开发一个可以测定自wh值的工具。?br />
q你已l开发出了具有数据分析和性能监测能力的品,也还是无法说明你最l要量的是什么。ؓ什么这么说呢?因ؓ高别的业务性能度量是基于更详细的更低的度量的Q而这些是你将要在部门U培ȝ数据分析所负责的领域。而在产品成Ş前他们自׃不知道所要做的是什么?br />
q一切听h是那么神U,但是q些秘的数字确实有用。下面这几点内容你可以大胆的说出来,q且我会告诉你如何说。虽然没有附带具体数据,但其逻辑性很强,不容反驳?br />
数据仓库的优?/b>
1.多的趋势分析。你的胦务h员、销售h员以及市Zh员将有能力对市场势q行多等U的定义和分析,所包括的范围大到整个市场,到一个地区的市场或Q意定义的范围。而且他们可以控制预测的精度,因ؓ数据来源的品质和量_ֺ都是可以控制的?br />
2.企业范围的性能监测。同{别的分析能力可以应用于部门、业务单元Q以及整个企业范围。你可以开发,q且不断的改q,度量整个企业的性能?br />
3.用户定义的,用户控制的报表。这一点尤光要强调,因ؓ它听h有种紧随世界势的意思。实际上我们一点也没有夸大它的能力Q而且q也正是你需要的能力?br />
你的案例
现在考虑一下你的报告系l。以订货量ؓ例,pȝ会将大量的报表发送到不同部门的不同h员手中。这里出现的状况是没有h能够处理包括订单、来自订单历史记录的数据Q以及来自不同数据库的数据(如客戯格等Q,因此无法汇L需的信息。问题出在哪里呢Q首先,׃报表很大E度上是静态的Qƈ且所需信息多来自不同的数据库,需要多ơ请求才能得刎ͼ操作h开销很大?br />
现在你可以让决策者选择逐一的投资实现单独的功能或者一ơ投资实现所有功能。你必须让他们清楚的知道Q数据仓库实施的最l目的是l你的用L一个唯一的应用程序,而它可以代替以往的数个程序。在一个大E序上的投资_投资实现一个数据仓库了Q而它所带来的功能将更强大。这才是企业所q求的效益?br />
数据仓库的另一个好处是它可以实C个叫做ȝ理信息系l(EISQ的pȝ。EIS是一个应用程序,它可以按照分cdŞ式提供经理在决策报告中所需的Q何信息。由于一般情况下l理不会面对其它用户所遇到的分析数据的问题Q他们不会处理四五个数据源的数据汇d作。他们只是需要用最单的Ҏ获得最_的信息。对于这cȝh_数据仓库可以令他们梦x真?br />
谁是受益者?
如果你无法明的说明q一点,决策者们是不会ؓ你掏腰包的。数据仓库是一个强大的战略性工P它可以大大加Z业的竞争力。如果你无法提出具体的投资数目,那么可以说一个很保守的数?0万美元,而最高投资肯定不会到七位数?br />
那么你需要购C么设备呢Q如果你目前使用的是某种ERPq_QSAP R/3, Oracle, PeopleSoftQ,你可以购买相应的开发工具包Q其中的工具可以帮助你实现数据提取和载入E序Q以及开发数据挖掘和分析E序。如果目前还没有ERPq_Q你需要购买存储设备、用于将数据导入数据仓库的extract-transform-load QETLQYӞ以及用于数据挖掘和分析的软gQOnline Analytical Processing, or OLAPQ。除此之外,你还需要对员工q行业务培训Q他们能够胜Q数据分析工作Q还要帮助员工{变事务处理思想模式Q他们能顺利进行报表开发工作(后箋的文章会Ҏ做更深入的讨论)?br />
最后你需要ȝ一下,q也是各位决{者需要听到的Q通过数据仓库Q你的用户团队可以实现少花钱多办事的目的?br />
一、与构架有关的几个基本概念:
1、模块(moduleQ:一l完成指定功能的语句Q包括:输入、输出、逻辑处理功能、内部信息、运行环境(与功能对应但不是一对一关系Q?br />2、组ӞcomponentQ:pȝ中相当重要的、几乎是独立的可替换部分Q它在明定义的构架环境中实现确切的功能?br />3、模式(patternQ:指经q验证,臛_适用于一U实用环境(更多时候是好几U环境)的解x案模板(用于l构和行为。在 UML 中:模式由参数化的协作来表示Q但 UML 不直接对模式的其他方面(如用结果列表、用示例等Q它们可由文本来表示Q进行徏模。存在各U范围和抽象E度的模式,例如Q构架模式、分析模式、设计模式和代码模式或实施模式。模式将可以帮助我们抓住重点。构架也是存在模式的。比如,对于pȝl构设计Q我们用层模式Q对于分布式pȝQ我们用代理模式(通过使用代理来替代实际的对象QɽE序能够控制对该对象的访问)Q对于交互系l,我们使用MVCQM模型(对象)QV视图(输出理)QC控制?输入处理)Q模式。模式是针对特定问题的解Q因此,我们也可以针寚w求的特点采用相应的模式来设计构架?br />4、构架模式(architectural patternQ:表示软gpȝ的基本结构组l方案。它提供了一l预定义的子pȝ、指定它们的职责Qƈ且包括用于组l其间关pȝ规则和指对{?br />5、层QlayerQ:Ҏ型中同一抽象层次上的包进行分l的一U特定方式。通过分层Q从逻辑上将子系l划分成许多集合Q而层间关pȝ形成要遵循一定的规则。通过分层Q可以限制子pȝ间的依赖关系Qɾpȝ以更松散的方式耦合Q从而更易于l护。(层是Ҏ架的横向划分Q分区是Ҏ架的U向划分Q?br />6、系l分层的几种常用ҎQ?br />1Q?常用三层服务Q用户层、业务逻辑层、数据层Q?br />2Q?多层l构的技术组成模型:表现层、屑zxԎ莶悖?br> 3Q?|络pȝ常用三层l构Q核心层、汇聚层和接入层Q?br />4Q?RUP典型分层ҎQ应用层、专业业务层、中间g层、系lY件层Q?br />5Q?ZJava的B/S模式pȝl构Q浏览器端、服务器端、请求接收层、请求处理层Q?br />6Q?某六层结构:功能层(用户界面Q、模块层、组装层QY件ȝQ、服务层Q数据处理)、数据层、核心层Q?br />7、构ӞArchitectureQ愿意ؓ建筑学设计和建筑物徏造的艺术与科学): 在RUP中的定义QY件系l的构架Q在某一l定点)是指pȝ重要构g的组l或l构Q这些重要构仉过接口与不断减的构g与接口所l成的构件进行交互;《Y件构架实c中的定义:某个软g或者计系l的软g构架即组成该pȝ的一个或者多个结构,他们l成软g的各个部分,形成q些lg的外部可见属性及怺间的联系QIEEE 1471-2000中的定义Qthe fundamental organization of a system emboided in its components,their relationships to each other,and to the enviroment and the principles guiding its design and evolutionQ构架是pȝ在其所处环境中的最高层ơ的概念。Y件系l的构架是通过接口交互的重要构Ӟ在特定时间点Q的l织或结构,q些构g又由一些更的构g和接口组成。(“构架”可以作为名词,也可作ؓ动词Q作为动词的“构架”相当于“构架设计”)
8、构架的描述方式Q?Q?”视图(用例视图、设计视图、实现视图、过E视图、配|视图)是一个被qؓ使用的构架描q的模型QRUPq程的构架描q模板在?Q?”视囄基础上增加了可选的数据视图Q从怹性数据存储方面来对系l进行说明)QHP公司的Y件描q模板也是基于?Q?”视图?br />9、结构:软g构架是多U结构的体现Q结构是pȝ构架从不同角度观察所产生的视图。就像徏{物的结构会随着观察动机和出发点的不同而有多种含义一P软g构架也表Cؓ多种l构。常见的软gl构有:模块l构、逻辑或概늻构、进E或协调l构、物理结构、用结构、调用结构、数据流、控制流、类l构{等?
二、构架设计应考虑的因素概揽:
模块构架设计可以从程序的q行时结构和源代码的l织l构斚w考虑?br />1、程序的q行时结构方面的考虑Q?br />1Q?需求的W合性:正确性、完整性;功能性需求、非功能性需求;
2Q?M性能Q内存管理、数据库l织和内宏V非数据库信息、Q务ƈ行性、网l多人操作、关键算法、与|络、硬件和其他pȝ接口Ҏ能的媄响)Q?br />3Q?q行可管理性:便于控制pȝq行、监视系l状态、错误处理;模块间通信的简单性;与可l护性不同;
4Q?与其他系l接口兼Ҏ;
5Q?与网l、硬件接口兼Ҏ及性能Q?br />6Q?pȝ安全性;
7Q?pȝ可靠性;
8Q?业务程的可调整性;
9Q?业务信息的可调整?br />10Q?使用方便?br />11Q?构架样式的一致?br />注:q行时负载均衡可以从pȝ性能、系l可靠性方面考虑?br />2、源代码的组l结构方面的考虑Q?br />1Q?开发可理性:便于人员分工Q模块独立性、开发工作的负蝲均衡、进度安排优化、预防h员流动对开发的影响Q、利于配|管理、大的合理性与适度复杂性;
2Q?可维护性:与运行可理性不同;
3Q?可扩充性:pȝҎ的升U、扩宏V扩充性能Q?br />4Q?可移植性:不同客户端、应用服务器、数据库理pȝQ?br />5Q?需求的W合性(源代码的l织l构斚w的考虑Q。?br />
三、程序的q行时结构方面的考虑Q?br />1?需求的W合性:正确性、完整性;功能性需求、非功能性需?br />软g目最主要的目标是满客户需求。在q行构架设计的时候,大家考虑更多的是使用哪个q行q_、编成语a、开发环境、数据库理pȝ{问题,对于和客户需求相关的问题考虑不、不够系l。如果无论怎么好的构架都无法满_h的某个功能性需求或非功能性需求,应该与客户协调在项目范围和需求规D明书中删除这一需求。否则,架构设计应以满客户所有明需求ؓ最基本目标Q尽量满_隐含的需求。(客户的非功能性需求可能包括接口、系l安全性、可靠性、移植性、扩展性等{,在其他小节中l述Q?br />一般来_功能需求决定业务构架、非功能需求决定技术构Ӟ变化案例军_构架的范围。需求方面的知识告诉我们Q功能需求定义了软g能够做些什么。我们需要根据业务上的需求来设计业务构架Q以使得未来的Y件能够满_L需要。非功能需求定义了一些性能、效率上的一些约束、规则。而我们的技术构架要能够满q些U束和规则。变化案例是Ҏ来可能发生的变化的一个估计,l合功能需求和非功能需求,我们可以确定一个需求的范围Q进而确定一个构架的范围。(此段From林星Q?br />q里讲一个前几年因客h些需求错误造成构架设计问题而引Ll性能和可靠性问题的小的例子:此系l的需求本w是比较单的Q就是将某城市的某业务的全部历史档案卡片扫描存储hQ以便可以按照姓名进行查询。需求阶D客戯卡片大约?0万张Q需求调研者出于对客户的信L有对数据的总量q行查证。由于是中小型数据量Qƈ且今后数据不会增加,l过计算20万张卡片M定w之后Q决定用一U可以单Z用也可以联网的中型数据库管理系l。等到系l完成开始录入数据时Q才发现数据臛_?0万,q样使用那种中小型数据库理pȝ不但会造成pȝ性能的问题,而且其可靠性是非常脆弱的,不得不对pȝq行重新设计。从q个小的教训可以看出,需求阶D不仅对客户的功能需求要调查清楚Q对于一些隐含非功能需求的一些数据也应当调查清楚Qƈ作ؓ构架设计的依据?br />对于功能需求的正确性,在构架设计文档中可能不好验证Q需要h工、费力)。对于功能需求完整性,应当用需求功能与对应模块对照表来跟踪q溯。对于非功能需求正性和完整性,可以使用需求非功能与对应设计策略对照表来跟t追溯评估?br />“Y件设计工作只有基于用户需求,立于可行的技术才有可能成功。?br />2?M性能
性能其实也是客户需求的一部分Q当然可能是明确的,也有很多是隐含的Q这里把它单独列出来在说明一ơ。性能是设计方案的重要标准Q性能应考虑的不是单台客L的性能Q而是应该考虑pȝȝl合性能Q?br />性能设计应从以下几个斚w考虑Q内存管理、数据库l织和内宏V非数据库信息、Q务ƈ行性、网l多人操作、关键算法、与|络、硬件和其他pȝ接口Ҏ能的媄响;
几点提示Q算法优化及负蝲均衡是性能优化的方向。经常要调用的模块要特别注意优化。占用内存较多的变量在不用时要及时清理掉。需要下载的|页主题文gq大时应当分解ؓ若干部分Q让用户先把主要部分昄出来?br />3?q行可管理?br />pȝ的构架设计应当ؓ了ɾpȝ可以预测pȝ故障Q防患于未然。现在的pȝ正逐步向复杂化、大型化发展Q单靠一个h或几个h来管理已昑־力不从心Q况且对于某些突发事件的响应Qh的反应明显不够。因此通过合理的系l构架规划系l运行资源,便于控制pȝq行、监视系l状态、进行有效的错误处理Qؓ了实Cq目标,模块间通信应当可能简单,同时建立合理详尽的系l运行日志,pȝ通过自动审计q行日志Q了解系l运行状态、进行有效的错误处理Q(q行可管理性与可维护性不同)
4?与其他系l接口兼Ҏ(解释略)
5?与网l、硬件接口兼Ҏ及性能Q解释略Q?br />6?pȝ安全?br />随着计算机应用的不断深入和扩大,涉及的部门和信息也越来越多,其中有大量保密信息在|络上传输,所以对pȝ安全性的考虑已经成ؓpȝ设计的关键,需要从各个斚w和角度加以考虑Q来保证数据资料的绝对安全?br />7?pȝ可靠?br />pȝ的可靠性是C信息pȝ应具有的重要特征Q由于h们日常的工作对系l依赖程度越来越多,因此pȝ的必d靠。系l构架设计可考虑pȝ的冗余度Q尽可能地避免单Ҏ障。系l可靠性是pȝ在给定的旉间隔及给定的环境条g下,按设计要求,成功地运行程序的概率。成功地q行不仅要保证系l能正确地运行,满功能需求,q要求当pȝ出现意外故障时能够尽快恢复正常运行,数据不受破坏?br />8?业务程的可调整?br />应当考虑客户业务程可能出现的变化,所以在pȝ构架设计时要量排除业务程的制U,x程中的各项业务l点工作作ؓ独立的对象,设计成独立的模块或组Ӟ充分考虑他们与其他各U业务对象模块或lg的接口,在流E之间通过业务对象模块的相互调用实现各U业务,q样Q在业务程发生有限的变化时Q每个业务模块本w的业务逻辑没有变的情况下)Q就能够比较方便C改系l程序模块或lg间的调用关系而实现新的需求。如果这U调用关p被设计成存储在配置库的数据字典里,则连E序代码都不用修改,只需修改数据字典里的模块或组件调用规则即可?br />9?业务信息的可调整?br />应当考虑客户业务信息可能出现的变化,所以在pȝ构架设计时必d可能减少因ؓ业务信息的调整对于代码模块的影响范围?br />10?使用方便?br />使用方便性是不须提及的必然的需求,而用方便性与pȝ构架是密切相关的。WinCEQ?.0Q的p|和后来改q版本的成功p明了q个问题。WinCEQ?.0Q有太多层次的视H和菜单Q而用户则更喜Ƣ简单的界面和快L操作。失败了应当及时U正Q但最好不要等到失败了再来U正Q这样会费巨大的胦力物力,所以在pȝ构架阶段最好能需要考虑的因素都考虑到。当然用方便性必Mpȝ安全性协调^衡统一Q用方便性也必须与业务流E的可调整性和业务信息的可调整性协调^衡统一。“满用L需求,便于用户使用Q同时又使得操作程可能简单。这是设计之本。?br />11、构架样式的一致?br />软gpȝ的构架样式有些类g建筑样式Q如中国式、哥特式、希腊复古式Q。Y件构架样式可分ؓ数据构架样式、调用返回构架样式、独立组件构架样式、以数据Z心的构架样式和虚拟机构架样式Q每一U样式还可以分ؓ若干子样式。构架样式的一致性ƈ不是要求一个Y件系l只能采用一U样式,像建筑样式可以是中西结合的QY件系l也可以有异质构架样式(分ؓ局部异质、层ơ异质、ƈ行异质)Q即多种样式的综合,但这Ll合应该考虑其某些方面的一致性和协调性。每一U样式都有其使用的时机,应当Ҏpȝ最的质量属性来选择。?
四、源代码的组l结构方面的考虑Q?br />1?开发可理?br />便于人员分工Q模块独立性、开发工作的负蝲均衡、进度安排优化、预防h员流动对开发的影响Q一个好的构架同时应有助于减项目组的压力和紧张Q提高Y件开发效率)、利于配|管理、大的合理性、适度复杂性;
1Q便于h员分工-模块独立性、层ơ?br />模块独立性、层ơ性是Z保证目开发成员工作之间的相对独立性,模块联结方式应该是纵向而不是横? 模块之间应该是树状结构而不是网状结构或交叉l构Q这样就可以把开发h员之间的通信、模块开发制U关pd到最。同时模块独立性也比较利于配置理工作的进行。现在有来多的的软g开发是在异地进行,一个开发组的成员可能在不同城市甚至在不同国Ӟ因此便于异地开发的人员分工与配|管理的源代码组l结构是非常必要的?br />2Q便于h员分工-开发工作的负蝲均衡
不仅仅是开发出来的软gpȝ需要负载均衡,在开发过E中开发小l各成员之间工作d的负载均衡也是非重要的。所谓工作Q务的负蝲均衡是通过合理的Q务划分按照开发h员特点进行分配Q务,量让项目组中的每个人每D|间都有用武之地。这需要在构架设计时应当充分考虑目l手头的人力资源Q在实现客户需求的基础上实现开发工作的负蝲均衡Q以提高整体开发效率?br />3Q便于h员分工-q度安排优化Q?br />q度安排优化的前提是模块独立性ƈ搞清楚模块开发的先后制约关系。利用工作分解结构对所有程序编码工作进行分解,得到每一工作的输入、输出、所需资源、持l时间、前期应完成的工作、完成后可以q行的工作。然后预估各模块需要时_分析各模块的q行与串行(序制约Q,l制出网l图Q找出媄响整体进度的关键模块Q算出关键\径,最后对|络图进行调_以ɘq度安排最优化?br />有个家喻h的智力题叫烤肉片{略Q约逊家户外有一个可以同时烤两块肉片的烤肉架Q烤每块肉片的每一面需?0分钟Q现要烤三块肉片l饥肠辘辘急不可耐的一家三口。问题是怎样才能在最短的旉内烤完三片肉。一般的做法?0分钟先烤完前两片Q再?0分钟烤完W三片。有一U更好的Ҏ可以节省10分钟Q大家想惟?br />4Q便于h员分工-预防员工人员动对开发的影响
人员动在Y件行业是司空见惯的事情,已经是一个常见的风险。作为对q一风险的有效的防范对策之一Q可以在构架设计中考虑到ƈ预防员工人员动对开发的影响。主要的思\q是在模块的独立性上Q追求高内聚低耦合Q,lg化是目前行的趋ѝ?br />5Q利于配|管理(独立性、层ơ性)
利于配置理与利于h员分工有一定的联系。除了逻辑上的模块lg要利于h员分工外Q物理上的源代码层次l构、目录结构、各模块所处源代码文g的部|也应当利于人员分工和配|管理。(管现在配置理工具有较强大的功能,但一个清楚的源码分割和模块分割是非常有好处的Q?br />6Q大的合理性与适度复杂?br />大小的合理性与适度复杂性可以开发工作的负蝲均衡Q便于进度的安排Q也可以使系l在q行时减不必要的内存资源浪贏V对于代码的可阅L和pȝ的可l护性也有一定的好处。另外,q大的模块常常是pȝ分解不充分,而过的模块有可能降低模块的独立性,造成pȝ接口的复杂?br />2?可维护?br />便于在系l出现故障时及时方便地找C生故障的原因和源代码位置Qƈ能方便地q行局部修攏V切ԌQ可l护性与q行可管理性不同)
3?可扩充性:pȝҎ的升U、扩宏V扩充性能
pȝ在徏成后会有一D很长的q行周期Q在该周期内Q应用在不断增加Q应用的层次在不断升U,因此采用的构架设计等Ҏ因充分考虑升、扩宏V扩充的可行性和便利
4?可移植?br />不同客户端、应用服务器、数据库理pȝQ如果潜在的客户使用的客L可能使用不同的操作系l或览器,其可UL性必考虑客户端程序的可移植性,或尽量不使业务逻辑攑֜客户端;数据处理的业务逻辑攑֜数据库管理系l中会有较好的性能Q但如果客户中不能定使用的是同一U数据库理pȝQ则业务逻辑׃能数据库理pȝ中;
辑ֈ可移植性一定要注重标准化和开放性:只有q泛采用遵@国际标准Q开发出开放性强的品,才可以保证各U类型的pȝ的充分互联,从而产品更具有市场竞争力Q也为未来的pȝUL和升U扩展提供了基础?br />5?需求的W合?br />从源代码的组l结构看需求的W合型主要考虑针对用户需求可能的变化的Y件代码及构架的最冗余(同时又要使得pȝh一定的可扩展性)?
五、写pȝ构架设计文档应考虑的问?br />构架工作应该在需求开发完成约80Q的时候开始进行,不必{到需求开发全部完成,需要项目经理以具体的判断来评估此时是否以开始构Y件构架?br />l出一致的轮廓Q系l概q。一个系l构枉要现有概括的描述Q开发h员才能从上千个细节甚x十个模块或对象类中徏立一致的轮廓?br />构架的目标应该能够清楚说明系l概念,构架应尽可能化,最好的构架文g应该单、简短,清晰而不杂ؕQ解x案自然?br />构架应单先定义上层的主要子系l,应该描述各子pȝ的Q务,q提供每个子pȝ中各模块或对象类的的初步列表?br />构架应该描述不同子系l间怺通信的方式,而一个良好的构架应该子pȝ间的通信关系降到最低?br />成功构架的一个重要特Ԍ在于标明最可能变更的领域,应当列出E序中最可能变更的部分,说明构架的其他部分如何应变?br />复用分析、外购:~短软g开发周期、降低成本的有效Ҏ未必是自行开发YӞ可以对现有Y件进行复用或q行外购。应考虑其对构架的媄响?br />除了pȝl织的问题,构架应重点考虑对于l节全面影响的设计决{,深入q些决策领域Q外部Y件接口(兼容性、通信方式、传递数据结构)、用h口(用户接口和系l层ơ划分)、数据库l织和内宏V非数据库信息、关键算法、内存管理(配置{略Q、ƈ行性、安全性、可UL性、网l多人操作、错误处理?br />要保证需求的可追t性,即保证每个需求功能都有相应模块去实现?br />构架不能只依据静态的pȝ目标来设计,也应当考虑动态的开发过E,如h力资源的情况Q进度要求的情况Q开发环境的满情况。构架必L持阶D|规划,应该能够提供阶段性规划中如何开发与完成的方式。不应该依赖无法独立q行的子pȝ构架。将pȝ各部分的、依赖关pL出来QŞ成一套开发计划?
六、结?br />pȝ构架设计和千差万别的具体的开发^台密切相养I因此在此无法l出通用的解x案,主要是ؓ了说明哪些因素是需要考虑的。对于每个因素的设计{略和本文未提到的因素需要Y件构架设计师在具体开发实践中灉|把握。不同因素之间有时是矛盾的,构架设计旉要根据具体情况进行^衡?
参考文?br />《Y件构架实cSEI软g工程译丛Q林·巴斯?br />《微软项目:求生法则》Steve McConnell著,余孟学译
《实用Y件工E》第二版Q郑人杰、殷人昆、陶气R{著
《Y件工E:实践者的研究Ҏ》(W?版)Roger S.Pressman?br />《Y件开发的U学与艺术》陈宏刚{著
本文作者邮:luls@dragonsoft.com.cn或lulsnet@21cn.com
后来QRational Edge发表了我和Y件测试方面的其他专家的一些访谈。有些读者却质疑我的选择Q他们会问:“这和我现在做的主要工作有什么关p??br />因此Q在本文中,我想把所有这些课题放在一Pq对自己关于未来试领域的发展的前瞻q行阐述。我可以断言的是Q测试h员、开发h员、项目管理h员、公司管理h员和最l用户们都期待着看到在这10q里软g试实践斚w要发生的大变革。其原因很简单,--软g质量的低下已lɾ国l济蒙受巨大损失QNIST估计[?]Q每q损q600亿美元,而Standishl织的数据则?000亿美元。所以改qY件质量已成ؓ取得高投资回报率QROIQ的直接途径Q只有那些把握了软g质量的企业才会赢得胜利,其余的则被Z所遗忘?br />q些实践和工具又是什么呢Q我认ؓ随着旉的发展,以下五种势会得到发展和应用?br />1. 试驱动型的软g开发。在软g生命周期的各个阶D中Q这些阶D包括测试、需求分析、用Ş象化W号q行的规D明,以及ZUML和其它新标准的实践;
2. 探烦性学习和发现Q这成P代开发过E的一个组成部分;
3. lg试和易试性设计,q将成ؓ软g开发不可分割的l成部分Q?br />4. 更加重视适当的技能的应用Q减预先写好的文档Q这成ZU软gq程的基本原则之一Q?br />5. 使用自动化测试来取代目前严重影响试效率的冗余繁复的人工q程?br />下面让我来对q些势q行说明?/p>
试驱动型开?/b>
q一实践在RUPq程中又UCؓ“测试第一的设计(test-first designQ”,而在很多XP( eXtreme Programming)文章中则UC为“测试第一的开发(test-first programmingQ”。这一设想的提今已有近十年了,但是直到最q才得以在开发这一层次上取得很大的支持Q这要在很大E度上感谢敏h法组l。他们的核心思想是,在你写一行代码之前,你要先写一行对其失效所q行的测试。在该测试的描述中应包含一个程序代码实际运行的实例。Martin Fowler这L试UCؓ“带实例的规D明(specification by exampleQ”?br />Brain Marick和其他一些敏h试的支持者已l提出徏议,要把试驱动开发的概念扩展到所有的层次Q包括系l测试和产品U测试[?]。Marick很清晰地表述了他的观点:“我q不惛_Z套用于捕捉用h望的需求,取而代之的是,我要写出一套测试,一旦这些测试能够通过Q品就能Ҏ意。所以我攑ּ需求编写的步骤Q而直接把需求分析加入到试的创E中厅R”[?]q些试脚本p是可执行的规D明,当程序代码通过了测试,那么q些E序代码也将和规D明保持一致?br />如果你的代码是用JavaQ而且你的试也在Java中测试,那么试很可能会ZJUnitQ你可能要么是一个hQ要么是~写的两人组中的一个,不管是哪一U情况,都很Ҏ看到Q这时Marick的方法是可行的。Marick怿q是可~的Q可以适合于小团体Q或者在有一个用户在场的条g下进行“交谈式试的创建(conversational test creationQ”的实践。但是,如果有h要了解需求,q些需求却是在试设计中被捕捉的,而你q不在场Q无法直接ؓ他们q行解释Q这样就存在明显的问题。在q种前提下,我ƈ不认为测试一定要在程序语a中体现。即使对需求有了“精”的表达Q也不以解军_理解性的问题。对于这一问题QLeffingwell和Widrig有很好的描述[?]Q下囑֍是基于他们的观点?/p>
?Q可理解性问题(ZLeffingwell和Widrig的观点)
实际上,Leffingwell和Widrigq没有真正地考虑到测试的问题。他们的主要目的是想让需求具备很高的可理解性,以便于让用户和投资者能够充分理解。他们没有解册L问题Q即如何把规D明提交给其他投资者和生命周期的其它阶Dc作ZU争议,他们认ؓ有必要保留一部分不明性。而实际上Q不明确的需求显然会让测试h员发疯?br />Marick提出的测试驱动型开发方法则走向另一个极端:试代表了需求,试的表现Ş式是一些可~译、可执行的代码。但是,如果试Q需求)的唯一表现形式是代码的话,你就很难和商务h?投资?客户q行有效沟通,甚至也很隑֒其他试人员及开发h员进行沟通。所有这些h都认为测试的形式本该是数据和程Q所以如果要以那U方式来做的话,你的试必须变得非常Ҏq行交流?br />一些公司正致力于ؓq种隔阂提供解决之道。Rational正积极参与一个OMG团体关于UML试预定义项目,该项目可以把试表示为数据和可视化的程Q例如顺序图和活动图。我们正在开发一些工h对待以下三种表示ҎQ代码,数据和流E,q取代类似的试视图?br />在过去,我们制作了这些“实例化规格说明”,按照RUP的命名方法,可称之ؓ“用例实现”。“实例化规格说明”和“用例实现”的怼性可以通过援引最q的一个用AgileҎ的工作团体的报告来说明:
[一个参与者]提到Q和他一起工作的人都很喜Ƣ用“测试第一”的开发方式。当试框架被开发好以后Q特别是当用于组l运行的试脚本被定义好Ӟ他们的工作变得更为容易。而用例在l织h开发脚本时会有所帮助。他们的试可以捕捉到用L需要。h们之所以喜Ƣ这LҎQ其原因是它提供了他们工作所需的结构。在AgileҎ中,需求以“案?story)”的形式存在。于是,试脚本以接口已明定义好的Ş式把q些“案例”编l在一赗这意味着l对~程的h可以Ҏ他们需要的序怺试接口[?]?br />cM圎ͼOMG试预定义工作组发现Q将UML排列h也很Ҏ。你可以一个用例实现{成ؓ试Q这只需增加两g东西Q验证工作(例如Q“现在用试来检查这个Y件中的条件。”)以及裁决Q例如,通过、失败,或者暂不决定)。这L信息在规D明中随处可以捕捉刎ͼ所以UMLW号可以让我们测试h员有了表辄手段?br />于是Q只需要额外做一点点努力Q就可以使测试对客户来说变得很容易理解:数据表和可视化流E。然后,当有软g需要测试的时候,试已准备就l。这一实践使测试驱动型开发在pȝU测试上也具有实用的价|因ؓ在设计工件和试设计工g之间实没有什么区别。仅仅只要增加验证的注解以及q行裁决可以了。在比较Ҏ理解的可视化程和数据的帮助下,你不再需要把pȝ设计从测试设计中分离出来。而且׃q些程h一个可执行的Ş式(生成的代码)Q因此可以把每一ơ创Z为测试来执行。这使整个团队得C解放Qƈ成ؓKent Beck和Erich Gamma所说的"受媄响的试Qtest infectedQ?:
?..q是一U测试的cdQ只要用非常小的投入即可你成Z个更快的、更多的、更具预见性的、压力更的开发者。?br />-Kent Beck和Erich Gamma《Test Infected: Programmers Love Writing Tests》[?]
探烦性学?/b>
q第二种势认识Cq样的现实,x们通常很难把问题描q得十分正确Q需求在演变Q我们需要简化(扁^化)或者把著名的“错?代h”曲UK倒过来。这里的核心思想是:我所说的每一,不管是在产品、测试或者跟t排错的W一步,都在q行软g旉过探烦性发玎ͼ才得可视化-可执?设计-试的整个过E和l果变得更ؓ真实?br />实时分析工具Q例如Rational PurifyPlus带有制作精良的非常明确的实例,例如发现内存错误和性能上的瓉。你q可以用它们来支持更q泛的探索,其是在由各U不同组件所构成的系l中?0%的企业行ؓ都是Ҏ些组件的重新l装Q包括对遗留下来的成分进行更新或补充{等Q而不是从头开始设计?br />在Y件运行时你会发现很多新的信息Q至和设计时一样多。这也是RUP要把可运行的软g作ؓ每一ơP代的l成部分的缘故。你发现的每一样东襉K应该是可视的Qƈ且放在你用于设计的同L工g中。对q行着的系l的跟踪是一UUML的P代,l过验证和裁冻I可以转化ZU可复用的测试。数据也值得q行概括Qƈ形成新的{hcȝ基础Q等{?br />当前Q大多数探烦性测试的提倡者,其是Kaner和BachQ都把这作ؓ使用后即可放弃的行ؓ[?]。但我认为,我们一旦把所探烦到的内容无缝地加入到设计中去后,׃发现Q这是高度可重用的。事实上Q这是实时分析的一个新的应用:通过探烦而发现的有h值的东西的捕获和利用?/p>
lg试和易试性设?/b>
W三U趋势是关于理解试人员和开发h员的相对角色Qƈ为每U角色分配合适的工具。Rational把提供组件测试和易测试性设计作ZU最佛_践,q已有很长的历史。我认ؓ对这些做法的采纳源自于对质量的基本理解。当前,太多的测试h员的行ؓ都受限于规格说明的模式,其中有很多浪贏V其实开发h员才有责d保证所开发出来的软g和规D求相一_他们应该使用合适的工具和过E来辑ֈq样的目的?br />Boris Beizer描述?U不同角色的区别Q?br />独立试的目的是提供一U不同的观察点,由此产生了不同的试Qƈ且在比开发h员所采用的开发环境更丰富的环境中执行试。自我测试(self-testingQ的目的是消除那些bugQ这可以在相Ҏ单、更明确的单?lg环境Q或者低层次的系l测试中q行Qƈ且只需p较低的代仗[?]
试驱动型开发提供更大的能力。如果规D明就是可执行的测试,而测试进行没有生别的问题,那么可以认Y件和规格说明相符。其它的单元试q程也只是ؓ了保证同L事情Q就规格说明而言Q不它们是什么内容,代码L与之相符合的。如果不W合Q那么就是开发h员的问题。Kent Beck非常清楚试驱动型开发所带来的效果:
如果试驱动~码的缺陷密度达到够低的话Q那么专业测试的角色不可避免地发生改变。以前的是“成人监护”方式,而现在更cM于一U扩韛_Q它宣称试要更多地验证的是pȝ必须做什么。[?]
q需要整个团队接受这L一个前提,即保证Y件符合规D明是开发h员的职责。这使得试者可以有更多_֊用于发现和避免一些别的问题,从客h者用L角度来看Q这些问题的存在可能会软g所应有的h值有所降低。Brian Marick针对q些冗长烦琐做法的错误性写q一很著名的文章[?0]。那些文档通常已说明了一个系l中的多于一半的错误Q他声称Q因此你需要专门有一个过E来让你的测试h员用来发现这些问题?br />易测试性的设计在这里具有重要的意义。现在很多Y件已改用Z服务的构Ӟq种构架是基于组件的构架的一U扩展,随之而来的是新增加的复杂性,即组件可以在没有警告的情况下发生改变Q其可靠性的问题是极Z重的。大多数ITl理会接?9%的可靠性,我敢打赌Q他们会认ؓq一标准甚至已经高于他们所用的买来或构建的lg。但是,如果你构建的pȝ有超q?00个组Ӟ每个lgh99%的可靠性,那么整个pȝ的可靠性是0.99?00ơ方Q实际上仅有37%。顺便提一下,q也是ؓ什么那些有高可靠性要求的市场Q例如电信业Q会要求??”的可靠性,?9.999%。在q样的情况下Q你可以?00个组Ӟl合h仍有99.9%的可靠性?br />q一基本原理实际上要求Y件进行易试性的设计Q就?0q前市场形成时硬件所做的一栗?Bertrand Meyer是这一领域研究的领先者,他提Z按合U设计,其意思是把对cd调用该类的客L之间的关pȝ视作ZU正式的协议Q这表达了每个团体的权利和义务[?1]。Meyer的概念已被广泛接受,其标志之一是合约设计的规DaWSDL的诞生,该语a是Web Service标准的核心[?2]?br />我认Zh们正来多地接受易试性设计。易试性已成ؓ诸如Web Service{框架和标准的一个补充的l成部分。接口也正成为技术^台和操作pȝ的一部分。一个比较简单的例子是,J2EE?NET 中预定义开攑ּ接口和API映射Q可以允许工h查在q行时刻环境中发生了什么。另一个真实而有益的势是h们正使用象Rational XDETMq样的工P通过设计模式的方法来构徏应用--而易试性已被置入在设计模式中。模式所构造的lg包括外在的用于测试的接口 -- 即组件的一些适当的getter和setterҎ?br />易测试性设计的一个实用的法则是,你已在GUI和表C层的后面对业务逻辑或Y件的行ؓq行了访问。Bret PettichorddQ易试性设计应该是关于可见性和控制的设计[?3]。你通过较低层获得其外在接口Q从而得到所需要的可见性,在测试的时候,通过很多开攄接口来允怽直接看到软g中的声明。同样地Q你需要接口来让你能够控制应用Q由此你才可以避免用GUIQ而是通过自动化框架来驱动应用?/p>
重视技?/b>
W四U趋势是增进软g试专业技术知识的水准。在.com行的年代中有这L误解Q即使没有很q试技术知识、业务应用方面的领域知识以及充分的培训,你也能有效地q行试。但当你面对一个分布式的应?-例如Q一个特别的ZWeb的应用,׃发生问题。Hung Nguyen关于ZWeb应用的测试论著是q种观点最好的代表[?4]。Nguyen认ؓQ测试h员应该知道技术是如何对他们所看到的各U错误生媄响的。他们需要对技术问题有所理解Q例如配|的问题Q以及他们所查的技术本w内含的问题。各U细节上的理解,例如了解应用服务器中Bean和Container理的持l性之间的区别Q可以直接媄响到你发现特定缺L能力?br />所以,现在的测试h员除了测试本w的技术以外,q需要理解开发技术和领域知识。例如,假设你在览器中看到一个错误:?04 - Page not found”这L错误可能是错误的链接所引vQ也可能是因为某些服务失效而生。一个好的测试h员ƈ不会在出错页上就停下来,他会q一步诊断出错的原因。他不仅需要对该失效的服务具备_多的认识和理解,而且他要通过查看其它使用该服务的面来验证自q猜测。这是一UBug隔离的重要技能?br />另一U技能是成ؓ一个很好的探烦者。以前,试斚w的很多论q对计划和脚本有很多要求Q但现实情况下,一个好的测试h员就是一个好的探索者。他们喜Ƣ在试q程中发C些暗C,q知道怎么来进行跟t。这L暗示有时很简单,例如一个页面要很长旉才能加蝲。那么对于一个好的测试h员来_他可能会惻Iq其中发生了什么?然后l箋了解要通过什么\径可以进一步发现答案。James Bach所写的一些内容可能是在探索性测试方面最好的材料[?5]Q其中有该课题的最佳练习。我认ؓq显然也是一个重要的技能,每个团队都需要这L技能?br />我们在Rational学院的课E中已经非常重视如何d用基本的软g试技术。可以和Florida Tech的Cem Kaner一起开始那些专为测试h员提供的软g试基本原理的新评[?6]。该评q不专注于测试工P而是专注于如何成Z名很好的软g试人员Q尤其是当你正在应用q代开发过E的时候。最后,试人员的生产能力和开发h员的生能力是同样重要的Q只有富有经验的试人员才能使品让客户获得很高的投资回报率QROIQ。Rational已经发现Q一个更快、更l济、更高质量的开发过E的关键是q代式开发过E。P代式q程可以使测试在整个开发周期中得以提前Q从而可以更早地发现错误Q修攚w误也相对更加ҎQ其成本也相Ҏ低?br />但是Q我认ؓ现在的测试h员还没有得到很好的训l以胜Qq代开发过E中的测试工作要求,目l理也没有得到很好的训练以正地认识试在P代项目中所扮演的角Ԍ开发h员也没有得到很好的训l以得到他们需要了解的试相关技术,例如基础{hcd分。因此我们在RUP(Rational Unified Process)和Rational学院中增加了大量关于试的材料。而且我们q将l箋扩充q些材料以帮助测试h员、开发h员和目l理们在q代q程的协同工作中做得更好?/p>
自动化测?/b>
W五U趋势是关于试自动化方面。目前,Z实行试自动化,试人员和开发h员要p80%的精力来使(自动化)试成ؓ可能Q而只?0%被用于Q自动化Q测试变得更有意义。这一可怕的事实使很多h最l放弃了试自动化。同P目前的自动化软g质量(ASQ) 工具提供商正p80%的精力用于重复工作,他们必须重新创徏一个基q_来支持相应的试和排错工作,而仅?0%的精力来为测试和开发h员提供可见的有h值的功能?br />最q,Rational、IBM和其它一些公司开展了一个开发源码的目Q其目标是要把q两个百分数颠倒过来。该目被命名ؓHyadesQ取自Eddington用来校验爱因斯坦理论的星云的名字Qƈ由Eclipse.org负责。它的目标也包括加强实验性观察,试q程及Y件度量,最l实现更具实用性的试自动化?br />
对于使用Eclipse的开发h员和试人员来说QHyades既是一U集成测试及跟踪Q也是环境监控程序。Eclipse为整个测试过E提供了标准、工具和互操作性,以ɋ试能更早地UL到应用生命周期中厅R对ASQ提供商和集成商来_Hyades动化试、跟t、预定义、监控和资源理提供了一个可扩展的架构和q_。和目前的测试与跟踪工具所不同的是QHyades提供一个统一数据模型Q实CUML试预定义)Q这是一U标准的用户工作的流E,包括一套统一的API及相兛_P可以在排列的目标之间连l地工作?/p>
ȝQ测试实늚大变?/b>
Rational和一些竞争对手尽自׃提供商业试工具Qؓ什么还要加入到象Hyadesq样的开放源码项目中dQ?我的很多同事也问q这L问题。其核心理由是上面所说的80/20比例。所有h都很x变这个比例?br />80%的基q_对用h说是不可见的Q它难以分LQ也难以l护。每当测试所用Y件的环境条g更新的时候,(新的~译器,新的库文Ӟ新的操作pȝ补丁Q等{)Q测试工具就必须随之更新。如果你是一位富有经验的实时分析或自动化工具的用P你可能早已感受到q种脆弱。你也许已经不止一ơ在考虑要更换开发环境,因ؓ有些工具不支持一些新的版本。这一l护成本l工h供商带来了巨大的压力Q因此工具商们决定无偿地为新的引擎工作,q分享其成果Q进而满用L需要。Hyades目必将为我们的用户提供其h倹{?/p>
对Hyades来说Q它是由一pd分散的努力所l成。在我所归纳的五U趋势中QHyades是其中的一个组成部分,它将同时为测试h员和开发h员提供新的测试支持方式。这是一U技术,它可以在生命周期的一开始就推动试Q带来工h面更好的协同性,通过改进试Q新的效果会明显地加入到软g中去。它ؓq?0q里我能所能看到的在测试实践上的改革提供有力的支持。我怿q种技术,以及其它有类似目标和基础的技术,代表着我们产业的未来。我们这些已被卷入到Hyades目中的人都有一U命感Q我们不能辜负Hyadesq一名称Q?br />让我们描d金牛座的头部--Hyades星云中的恒星Q这Ҏ们来说意义重大,q将带给我们快乐Qƈ使我们能够测量整个宇宙!
--Anthony G. A. Brown, Universidad Nacional Autýnoma de Mýxico.
备注Q?/b>
1 http://www.nist.gov/director/prog-ofc/report02-3.pdf
2 Kent Beck作了一个限定,把Marick的想法改UCؓ"Application-Test-Driven Development"Q可参考Kent Beck《Test-Driven Development》, Addison- Wesley, 2002, W?99c?br />3 http://www.therationaledge.com/content/oct_02/f_testFirstDesign_sg.jsp
4 Dean Leffingwell和Don Widrig《Managing Software Requirements?Addison-Wesley, 2000,W?73c?br />5 http://fc-md.umd.edu/projects/Agile/3rd-eWorkshop/topic4.html
6 http://junit.sourceforge.net/doc/testinfected/testing.htm
7 他们的教E材料已在以下网址中公开Qhttp://www.testingeducation.org/
另外QBach的网站www.satisfice.com也是很有价值的资源?br />8 Boris Beizer 《Black-Box Testing》, Wiley, 1995, W?3c?br />9 Beck《Test-Driven Development》,Addison Wesley, 2002, W?6c?br />10 http://www.testing.com/writings/omissions.pdf
11 Meyer?Object-Oriented Software Construction》第2版,Prentice Hall, 1997, W?31?br />12 参见http://www.w3.org/2002/ws/ 和http://www.ws-i.org/
13 参见诸如http://www.therationaledge.com/content/nov_02/f_pettichordInterview_sg.jsp中的讨论
14 Hung Q. Nguyen《Testing Applications on the Web》, Wiley, 2001?br />15 http://www.satisfice.com/articles/what_is_et.htm 可以作ؓ一个很好的L?br />16 http://www.therationaledge.com/content/jul_02/f_interviewWithKaner_sg.jsp中可以找到很有h值的相关讨论?/p>
对照Q?/b>
以下是翻译时所做的部分词汇处理Q以资对照:
Test-driven development 试驱动型开?br />exploratory testing 探烦性测?br />Design for testability 易测试性的设计
Design by Contract 合约设计
artifact 工g
interaction q代
stackholder Q项目)投资?br />Profile 预定义,概况
目理有时也遇到过同样的现象?
目的管理出了问题,自然会去咨询专家Q可是在听过专家意见后,可能感到颇ؓ失望Q以Zh家讲授的东西q不深奥Q不怿目理是如此单?
D不知世界上的事情有时就是很单,我们不妨介绍几个关于“简单”的故事Q?
“简单”一Q如何练习角?/b>
c_的名字在中国球迷的口中叫得很响,但国安球员g更欣赏英国h霍顿Q觉得是霍顿让自己明白了该怎么t球?
以罚角球ZQ原先的教练一般只会说诸如“盯紧了Q别让他着Q拉住了……”等套话Q但是霍却能明告诉队员“谁应该在哪Q第一点在哪,W二点在哪。?
q些东西虽然单,但原先没有h告诉大家?
郝v东感叹到Q这才叫懂啊Q原先就知道去踢。其实这也不是什么高q事情Q但是原来没有h告诉我们?
“简单”二Q如何服从指?/b>
史_威担任过抗战时期中国战区的参谋长Q他上Q不久发C国军队的指挥pȝ存在严重问题?
Ƨ美军队对上U的命ol对服从Q不是谁,只要有指挥权p指挥Q中国则不然Q上下关系׃人恩惠决定,军官只听从某个h的命令,其它人即使有指挥权也指挥不动军队?
例如当远征军回国的退路被日军切断Ӟ其直接上司史q威命o部队撤往印度Q但蒋介矛_命o撤回国?
最高指挥部的不l一使远征军的军官们十分为难Q有两个师撤往印度Q其他的撤回云南。在退回云南途中Q远征军q回I越未至的原始森林,饥饿和疾病导致士兵大量死亡,Q0部队最后只剩下Q万人,倒是撤往印度的两个师后来成ؓ了中国最_N的部队?/p>
ҎƧ美国家的军法,军官不服从命令要受到严惩。史q威要求处分那些不听命的军Q要枪毙四个师长。但蒋介矛_息事宁hQ只第五军军长杜聿明调任,五十五师师长陈吾勉处分了事?
史_威对此非怸满,认ؓ必须对中国军队进行结构上的改造,他说Q“如果给予正的指导Q中国军队不逊于M国家的军队。?
“简单”三Q如何遵守程?/b>
看日本hq活是很烦琐的?
拿收拑ֺ铺来_在中国是很简单的事情Q连五星U宾馆都规定Q客人没有动q的被褥不用拆洗和重新叠。而在日本Q首先不客人用没有用过Q床单被|都要剥下来Q一一送到z衣房去Q而且是每个屋子送一ơ?
能不能把所有房间的床单被罩都剥下来Q一起送到z衣服房Q这样工作效率不是大大提高了吗?
日本样回{:作业书就是这样写的,我们按照作业书上做?
日本的管理体制要求工作不必带热情Q只能严格按照作业书的指C做Q即便出了错Q自׃不必担责仅R?
“简单”四Q如何划分权?/b>
目理首先要解决的是一些初U的东西?
比如你要目成员义务,你就要明地告诉他有什么权利,凡是力_保护法规定的权利都要告诉他,q项目提成奖金如何分配都要和他们讲清楚,q要让他们知道,“你们是国家的主人,但这个项目的Mh是我Q你们没有选D目l理的权利”?
“我现在购买了你的劳动力Q你必须负责。你不负责,你将失去你的权利。?
从项目管理的角度Ԍq就是效率,不把_֊费在与目无关的事情上?
|角球时如何占位是简单的事情Q指挥信可l一是简单的道理Q按照条例操作属于常识性的规矩Q员工责权利的界定是基本的前提,理是p些看似简单的东西构成?
目l制定项目管理战略当焉要,但更重要的是要把日常的管理细节做好?
战场上所有胜利的基础都是d有方Q带兵小到宿营时战士烫脚IQ鞋合不合脚Q绑腿扎得松紧程度等{,都关pd战斗力,而这些都是“简单”的事情Qƈ不高深?
世间事物无不普通而玄妙,玄妙而普通。许多事情看h很高深,实际很普通,理也是q样?/p>
如果你仍旧不能明白ؓ什么会有这么多被神U力量所“驱动着的开发”,那么你就q脆d房找个^底锅烧点热aQ然后敲下一个鸡蛋,很快Q你׃悟“以蛋黄驱动开发”的真谛了?br />
抛开实现的技术细节不论,在工E中Q“以什么驱动开发”其实是一个过E问题。而你应该明白Q过E的选择(或制?取决于你的工E需要,以及它在相关应用领域的适用性、过E工L充备性和q个q程理论的完善程度,而不是大公司们的鼓吹?br />
q程模型军_了工E的实施步骤和组l方式。但是Object Management Group (OMG) 管对MDA提出了一套完备的技术和Ҏ体系Q工E实施者却无法在这个体pM扑ֈ一个可以适用的Y件过E模型——MDA不讨E?br />
也就是说QMDA架构作ؓ一个新的Y件开发方法的架构Q即使在技术研I、底层协议和软g实现斚wl过了持l地完善而渐x熟,然而如果没有同h熟的软gq程理论支持Q那么它在工E中的实用hg有限?br />
仔细审视一下这个MDAQ如果你现在决定将下一个工E项目徏立在q个构架的基上,或者用MDD的方式来开发BIOSQ那么你ȝ病׃q了?br /> ①我d的的是U而不是点Q“关注点”只是一个概c如果你非要dC个“点”,那么你可以用几何的目光,x于弧U与直线的切炏V然而,q样的结果将是你d的忽视了“关注点”的本质含义?br /> ②我l常注意到的成本因素包括旉、h力、资金和客户成本。而大多数情况下,Z不会把客L数量以及耐心当做(客户)成本来计。而在我的目规划中,q是成本?/p>