版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
根据领域模型分析数据模型MappingfromtheClassModeltotheRelationalModel从类模型映射到关系模型Havingdescribedthetwodomainsofinterestandthenotationtobeused,wecannowturnourattentionastohowtomaportranslatefromonedomaintotheother.Thestrategyandsequencepresentedbelowismeanttobesuggestiveratherthanproscriptive-adaptthestepsandprocedurestoyourpersonalrequirementsandenvironment.在需要对两个领域建模时,现在我们可以关注如何从一个领域映射或转换映射到另一个领域。以下的策略和方法,就是要启发,而不是强制的步骤和程序应用到您的个人需求和环境。ModelClassesFirstlywewillassumeweareengineeringanewrelationaldatabaseschemafromaclassmodelwehavecreated.Thisisobviouslytheeasiestdirectionasthemodelsremainunderourcontrolandwecanoptimisetherelationaldatamodeltotheclassmodel.Intherealworlditmaybethatyouneedtolayeraclassmodelontopofalegacydatamodel-amoredifficultsituationandonethatpresentsitsownchallenges.Forthecurrentdiscussionwillfocusonthefirstsituation.Ataminimum,yourclassmodelshouldcaptureassociations,inheritanceandaggregationbetweenelements.1.类建模首先,我们将假设从已创建的类模型生成一个新的关系数据库模型。这显然是最容易的,可控制的,可以通过关系数据库模型反向优化类模型。在现实世界中可能你需要将类模型作为数据模型的上层,这是更困难的情况,也对自己提出了一个挑战。对于目前的讨论将集中在第一种情况。至少,你的类模型应捕元素之间的联系、继承和聚集关系。IdentifypersistentobjectsHavingbuiltourclassmodelweneedtoseparateitintothoseelementsthatrequirepersistenceandthosethatdonot.Forexample,ifwehavedesignedourapplicationusingtheModel-View-Controllerdesignpattern,thenonlyclassesinthemodelsectionwouldrequirepersistentstate.确认持久对象已建成的类模型,我们需要区分这些元素,那些需要持久化和那些不是。例如,如果我们设计我们的应用程序使用Model-View-Controller设计模式,那么只有MODEL模型部分需要持久化状态。
AssumeeachpersistentclassmapstoonerelationaltableAfairlybigassumption,butonethatworksinmostcases(leavingtheinheritanceissueasideforthemoment).Inthesimplestmodelaclassfromthelogicalmodelmapstoarelationaltable,eitherinwholeorinpart.Thelogicalextensionofthisisthatasingleobject(orinstanceofaclass)mapstoasingletablerow.假设一个持久化类映射一个关系表大多数情况下,这都是一个合理的假设,除去继承问题以外(暂且不考虑)。在最简单的模型中,逻辑模型中的一个类映射一个关系表的全部或一部分。这种逻辑的延伸是一个单一的对象(或类的实例)映射关系表中的一行数据。选择一个继承策略从面向对象模型转化成关系模型的过程中,继承可能是最有问题的关系和逻辑结构。关系空间本质上是平面结构,每一个实体自我实现,而对象模型通常为多层次扩展的类结构。多层级类模型可能有多层次继承的属性和行为,最终结果,运行时功能齐全的对象。有三种基本方式对继承关系转换成关系模型:Eachclasshierarchyhasasinglecorrespondingtablethatcontainsalltheinheritedattributesforallelements-thistableisthereforetheunionofeveryclassinthehierarchy.Forexample,Person,Parent,ChildandGrandchildmayallformasingleclasshierarchy,andelementsfromeachwillappearinthesamerelationaltable;类层次结构有只有一个相应的表,包含所有元素的所有继承的属性。因此这个表是类层次结构中所有类的联合。例如,人,父母,子女和孙子都可能形成一个单一的类层次结构,单所有元素将出现在同一个关系表中;Eachclassinthehierarchyhasacorrespondingtableofonlytheattributesaccessiblebythatclass(includinginheritedattributes).Forexample,ifChildisinheritedfromPersononly,thenthetablewillcontainelementsofPersonandChildonly;层次结构中每个类都有一个相应的表。表中包含类所要访问的所有属性(包括继承的属性)。例如,如果孩子继承人,则该表将包含个人与儿童所有的元素;Eachgenerationintheclasshierarchyhasatablecontainingonlythatgeneration'sactualattributes.Forexample,ChildwillmaptoasingletablewithChildattributesonly在类结构中,每一层有一个表,包含这一层的实际属性。例如,Child将映射大偶一个简单表,只包含汉字的属性。Therearecasestobemadeforeachapproach,butIwouldsuggestthesimplest,easiesttomaintainandlesserrorproneisthethirdoption.Thefirstoptionprovidesthebestperformanceatrun-timeandthesecondisacompromisebetweenthefirstandlast.Thefirstoptionflattensthehierarchyandlocatesallattributesinonetable-convenientforupdatesandretrievalsofanyclassinthehierarchy,butdifficulttoauthenticateandmaintain.Businessrulesassociatedwitharowarehardtoimplement,aseachrowmaybeinstantiatedasanyobjectinthehierarchy.Thedependenciesbetweencolumnscanbecomequitecomplicated.Inaddition,anupdatetoanyclassinthehierarchywillpotentiallyimpacteveryotherclassinthehierarchy,ascolumnsareadded,deletedormodifiedfromthetable.以上的方法都有成功的案例,但我认为最简单,最容易维护和减少出错是第三个选择。第一个选项提供在运行时的最佳性能,第二个是第一个和最后一个方法的妥协。第一个选项把层次结构变成了平面结构,定义所有属性在一个表中-便于更新和检索层次结构中任何类,但难以验证和维护。与行相关的业务规则难以实现,因为每行可以作为层次结构中任何对象实例化。列间的依赖关系可能会变得非常复杂。此外,在更新层次结构中的任何类将有可能影响层次结构中的所有其他类,例如对表进行添加,删除或修改列。Thesecondoptionisacompromisethatprovidesbetterencapsulationandeliminatesemptycolumns.However,achangetoaparentclassmayneedtobereplicatedinmanychildtables.Evenworse,theparentaldataintwoormorechildclassesmayberedundantlystoredinmanytables;ifaparent'sattributesaremodified,thereisconsiderableeffortinlocatingdependentchildrenandupdatingtheaffectedrows.第二种选择是一个妥协方案,提供更好的封装和消除空列。但是,对父类的改变可能需要重复对多个子表的进行修改。更糟的是,在两个或更多孩子的父类数据可能冗余存储在多个表中,如果一个父类的属性被修改,那么定位产生影响的行数据的子表,并进行修改,将需要非常大的工作。Thethirdoptionmoreaccuratelyreflectstheobjectmodel,witheachclassinthehierarchymappedtoitsownindependenttable.Updatestoparentsorchildrenarelocalisedinthecorrectspace.Maintenanceisalsorelativelyeasier,asanymodificationofanentityisrestrictedtoasinglerelationaltablealso.Thedownsideistheneedtore-constructthehierarchyatrun-timetoaccuratelyre-createachildclass'sstate.AChildobjectmayrequireaPersonmembervariabletorepresenttheirmodelparentage.Asbothrequireloading,twodatabasecallsarerequiredtoinitialiseoneobject.Asthehierarchydeepens,withmoregenerations,thenumberofdatabasecallsrequiredtoinitialiseorupdateasingleobjectincreases.第三个方案更准确地反映了对象模型,在层次结构中每个类映射到它自己独立的表中。父类和子类的更新定位于正确的空间。维护也相对容易,任何一个实体的改变也能限制到一个单一的关系表中。不利的一面是,在运行时需要重新构造层次结构,以准确的重建子类的状态。子对象可能需要一个角色成员变量来表示他们的父子模型关系。初始化一个对象时需要两个表同时加载,两次数据库调用。对于多层结构,初始化或更新一个简单对象时,数据库调用的数量增加。Itisimportanttounderstandtheissuesthatarisewhenyoumapinheritanceontoarelationalmodel,soyoucandecidewhichsolutionisrightforyou.重要的是要了解把继承关系映射到关系模型可能出现的问题,以便决定哪个解决方案最适合您。ForeachclassaddauniqueobjectidentifierInboththerelationalandtheobjectworld,thereistheneedtouniquelyidentifyanobjectorentity.Intheobjectmodel,non-persistentobjectsatrun-timearetypicallyidentifiedbydirectreferenceorbyapointertotheobject.Onceanobjectiscreated,wecanrefertoitbyitsrun-timeidentity.However,ifwewriteoutanobjecttostorage,theproblemishowtoretrievetheexactsameinstanceondemand.ThemostconvenientmethodistodefineanOID(objectidentifier)thatisguaranteedtobeuniqueinthenamespaceofinterest.Thismaybeattheclass,packageorsystemlevel,dependingonactualrequirements.为每个类添加唯一对象标识E3在关系和对象世界中,都需要唯一标识一个对象或实体。在对象模型中,在运行时,非持久性对象通常由直接引用或者指针进行标识。一旦对象被创建,我们能够参考它通过它的运行时标识。但是,如果我们把对象输出到存储介质中,问题是当需要时,如何准确的重新获取相同的实例。最简便的方法是定义一个OID(对象标识符),是保证在关注的命名空间唯一性。也可能是在类,包或系统级中根据实际要求进行定义。AnexampleofasystemlevelOIDmightbeaGUID(globallyuniqueidentifier)createdwithMicrosoft's'guidgen'tool;eg.{A1A68E8E-CD92-420b-BDA7-118F847B71EB}.AclasslevelOIDmightbeimplementedusingasimplenumeric(eg.32bitcounter).Ifanobjectholdsreferencestootherobjects,itmaydosousingtheirOID.Acompleterun-timescenariocanthenbeloadedfromstoragereasonablyefficiently.AnimportantpointabouttheOIDvaluesaboveisthattheyhavenoinherentmeaningbeyondsimpleidentity.Theyareonlylogicalpointersandnothingmore.Intherelationalmodel,thesituationisoftenquitedifferent.一个系统级的OID可能是一个微软的'guidgen'工具创建的GUID(全局唯一标识符);例如。{A1A68E8E-CD92-420b-BDA7-118F847B71EB}。类级别的OID可能是通过使用一个简单的数字(如32位计数器)。如果一个对象包含其他对象的引用,它可以使用他们的OID。在运行时,一个完整结构可以从存储介质中被合理有效载入。一个关于上述OID值重要的一点是,他们没有超越作为简单标识以外的含义。他们是唯一合乎逻辑的指针而已。在关系模型中,情况往往大不相同。Identityintherelationalmodelisnormallyimplementedwithaprimarykey.Aprimarykeyisasetofcolumnsinatablethattogetheruniquelyidentifyarow.Forexample,nameandaddressmayuniquelyidentifya'Customer'.Whereotherentities,suchasa'Salesperson',referencethe'Customer',theyimplementaforeignkeybasedonthe'Customer'primarykey.Theproblemwiththisapproachforourpurposesistheimpactofhavingbusinessinformation(suchascustomernameandaddress)embeddedintheidentifier.Imaginethreeorfourtablesallhaveforeignkeysbasedonthecustomerprimarykey,andasystemchangerequiresthecustomerprimarykeytochange(forexampletoinclude'customertype').Theworkrequiredtomodifyboththe'customer'tableandtheentitiesrelatedbyforeignkeyisquitelarge.在关系模型中的标识通常作为一个主键。主键是一个表中唯一标识一行的列集合。例如,姓名和地址可以唯一地标识一个'客户'。当其他实体,例如,一个'推销员',参考'客户'时,以'客户'的主键为基础,创建一个外键的。用这个方法的问题是有业务信息在标识中(如客户名称和地址),可能跟真实目的产生冲突。想象一下,三个或四个表中都有外键和基于客户表的主键,如果一个系统需要改变客户表的主键(例如包括'客户类型')。修改'客户'表和通过外键关联的实体的工作是相当大的。Ontheotherhand,ifanOIDwasimplementedastheprimarykeyandformedtheforeignkeyforothertables,thescopeofthechangeislimitedtotheprimarytableandtheimpactofthechangeisthereforemuchless.Also,inpractice,aprimarykeybasedonbusinessdatamaybesubjecttochange.Forexampleacustomermaychangeaddressorname.Inthiscasethechangesmustbepropagatedcorrectlytoallotherrelatedentities,nottomentionthedifficultyofchanginginformationthatispartoftheprimarykey.另一方面,如果OID作为主键,形成了对其他表的外键,更改范围仅限于主表,改变的影响要少得多。此外,在实践中,基于业务数据的主键可能会有所变动。例如,一个客户可能会变更地址或名称。在这种情况下,更改必须正确地传播到所有其他相关的实体,改变主键的一部分是更困难的。AnOIDalwaysreferstothesameentity-nomatterwhatotherinformationchanges.Intheaboveexample,acustomermaychangenameoraddressandtherelatedtablesrequirenochange.Whenmappingobjectmodelsintorelationaltables,itisoftenmoreconvenienttoimplementabsoluteidentityusingOID'sratherthanbusinessrelatedprimarykeys.TheOIDasprimaryandforeignkeyapproachwillusuallygivebetterloadandupdatetimesforobjectsandminimisemaintenanceeffort.Inpractice,abusinessrelatedprimarykeymightbereplacedwith:Auniquenessconstraintorindexonthecolumnsconcerned;Businessrulesembeddedintheclassbehaviour;Acombinationof1and2.Again,thedecisiontousemeaningfulkeysorOID'swilldependontheexactrequirementsofthesystembeingdeveloped.一个OID通常指的是同一个实体-无论什么其他信息发生变化。在上述例子中,客户可能会改变名称或地址以及相关的表不需要改变。当映射对象模型到关系表中,用OID作为绝对标识比使用业务相关主键实现往往更方便。OID作为主键和外键通常会更好的提供加载和更新对象的方法,减少维护工作量。在实践中,业务相关的主键可能被替换为:•在相关列上建立唯一性约束和索引•业务规则嵌入到类行为中;•建立1和2的联系.同样,决定使用有意义的钥匙或OID的依赖于对系统发展的真实需求。MapattributestocolumnsIngeneralwewillmapthesimpledataattributesofaclasstocolumnsintherelationaltable.Forexampleatextandnumberfieldmayrepresentaperson'snameandagerespectively.Thissortofdirectmappingshouldposenoproblem-simplyselecttheappropriatedatatypeinthevendor'srelationalmodeltohostyourclassattribute.Forcomplexattributes(ie.attributesthatareotherobjects)usetheapproachdetailedbelowforhandlingassociationsandaggregation.属性映射到列字段中。一般我们会把类中简单数据属性映射到关系表中的列字段中。例如,一个人的名字和年龄可以分别表示成文本和数字类型。这种直接映射应不成问题-只需在关系模型中选择适当的数据类型来承载类的属性。对于复杂属性(即其他对象的属性集合)的使用方法在下面处理关联和聚合关系的部分进行详细说明。MapassociationstoforeignkeysMorecomplexclassattributes(ie.thosewhichrepresentotherclasses),areusuallymodelledasassociations.Anassociationisastructuralrelationshipbetweenobjects.Forexample,aPersonmayliveatanAddress.WhilethiscouldbemodelledasaPersonhasCity,StreetandZipattributes,inboththeobjectandtherelationalworldweareinclinedtostructurethisinformationasaseparateentity,anAddress.Intheobjectdomainanaddressrepresentsauniquephysicalobject,possiblywithauniqueOID.Intherelational,anaddressmaybearowinanAddresstable,withotherentitieshavingaforeignkeytotheAddressprimarykey.Inbothmodelsthen,thereisthetendencytomovetheaddressinformationintoaseparateentity.Thishelpstoavoidredundantdataandimprovesmaintainability.Soforeachassociationintheclassmodel,considercreatingaforeignkeyfromthechildtotheparenttable.更复杂的类属性(即表示其他类集合),通常建模为关联关系。关联关系是对象之间的结构关系。例如,一个人可能在一个地址上居住。虽然这可以建模成一个人包含城市,街道和邮编属性,无论在对象和关系世界,我们倾向于地址信息结构作为一个单独的实体。在对象领域,一个地址表示一个唯一的的物理对象,可能拥有一个唯一的OID。在关系领域中,一个地址可能是一个地址表中的一行,其他实体通过外键关联到地址的主键上。在这两种模型,有一个趋势,地址信息作为一个单独的实体。这有助于避免冗余数据,提高可维护性。因此,在类模型中的每个关联关系,将考虑创建从子表到主表的外键关系。&MapAggregationandCompositionAggregationandcompositionrelationshipsaresimilartotheassociationrelationshipandmaptotablesrelatedbyprimary-foreignkeypairs.Therearehowever,somepointstobearinmind.Ordinaryaggregation(theweakform)modelsrelationshipssuchasaPersonresidesatoneormoreAddresses.Inthisinstance,morethanonepersoncouldliveatthesameaddress,andifthePersonceasedtoexist,theAddressesassociatedwiththemwouldstillexist.Thisexampleparallelsthemany-to-manyrelationshipinrelationalterminology,andisusuallyimplementedasaseparatetablecontainingamappingofprimarykeysfromonetabletotheprimarykeysofanother.8.关联映射到主键上聚集和组成关系和关联关系相似,也是通过一对主外建关系映射到关系表中。然而,一些要点需要注意。普通聚合模型关系(弱形式),比如一个人居住在一个或多个地址。在这种情况下,不止一个人可以生活在同一个地址,如果人不再存在,与之相关的地址依然存在。这个例子中类似于关系模型中的多对多关系,通常是作为一个单独表来实现,包含从一个表的主键映射到另一个表的主键的关系。Asecondexampleoftheweakformofaggregationiswhereanentityhasuseorexclusiveownershipofanother.Forexample,aPersonentityaggregatesasetofshares.ThisimpliesaPersonmaybeassociatedwithzeroormoresharesfromaSharetable,buteachSharemaybeassociatedwithzerooronePerson.IfthePersonceasestoexist,theSharesbecomeun-ownedorarepassedtoanotherPerson.Intherelationalworld,thiscouldbeimplementedaseachSharehavingan'owner'columnwhichstoredaPersonID(orOID).第二个作为弱形式聚集的例子就是一个实体和它使用或者专属的事物。例如,一个人书体聚合了他的股票的集合。这意味着一个人可能拥有零或者更多来自股票表的股票,但每个股份可能属于零或者一人。如果这个人不再存在,其股份就成为没有拥有者或者分给另一个人。在这种关系世界,这可以被实现为每个股票有一个存储人的ID(或者OID)的‘拥有者'列。Thestrongformofaggregation,however,hasimportantintegrityconstraintsassociatedwithit.Composition,impliesthatanentityiscomposedofparts,andthosepartshaveadependentrelationshiptothewhole.Forexample,aPersonmayhaveidentifyingdocumentssuchasaPassport,BirthCertificate,Driver'sLicense&etc.APersonentitymaybecomposedofthesetofsuchidentifyingdocuments.IfthePersonisdeletedfromthesystem,thentheidentifyingdocumentsmustbedeletedalso,astheyaremappedtoauniqueindividual.较强的聚合形式,和它相关的约束具有重要的完整性。组合关系,意味着一个实体整体由部分组成,这些部分有需要扶养的与整体的关系。例如,唯一标识一个人实体的证明可以是护照,出生证明,驾驶执照等,人的实体可以由以上的人的身份证明组成。如果此人从系统中被删除,则身份证明也必须同时删除,因为它们映射到一个唯一的个体。IfweignoretheOIDissueforthemoment,aweakaggregationcouldbeimplementedusingeitheranintermediatetable(forthemany-to-manycase)orwithaforeignkeyintheaggregatedclass/table(one-to-manycase).Inthecaseofthemany-to-manyrelationship,iftheparentisdeleted,theentriesintheintermediatetableforthatentitymustalsobedeletedalso.Inthecaseoftheone-to-manyrelationship,iftheparentisdeleted,theforeignkeyentry(ie.'owner')mustbecleared.如果我们暂时忽略的OID的问题,一个弱的聚合关系可以用一个中间表(多对多的情况)或者在聚合类/表中建立外键(一对多的情况)来实现。在多对多关系时,如果父对象被删除,在中间表中该实体相关的数据也必须被删除。在一对多关系时,如果父对象被删除,外键对应的实体(即'拥有者')必须被清除。Inthecaseofcomposition,theuseofaforeignkeyismandatory,withtheaddedconstraintthatondeletionoftheparentthepartmustbedeletedalso.Logicallythereisalsotheimplicationwithcompositionthattheprimarykeyofthepartformspartoftheprimarykeyofthewhole-forexample,aPerson'sprimarykeymaycomposedoftheiridentifyingdocumentsID's.Inpracticethiswouldbecumbersome,butthelogicalrelationshipholdstrue.在组合的情况下,被强制使用外键,增加父数据被删除部分数据也必须被删除的约束。在逻辑上组合关系也存在部分的主键构成整体的主键的一部分-例如,人实体的主键由他的唯一识别证明组成。在实践中,这将是十分麻烦的,但逻辑关系是成立的。DefinerelationshiprolesForeachassociationtyperelationship,eachendoftherelationshipmaybefurtherspecifiedwithroleinformation.Typically,youwillincludethePrimaryKeyconstraintnameandtheForeignKeyConstraintname.Figure6illustratesthisconcept.Thislogicallydefinestherelationshipbetweenthetwoclasses.Inaddition,youmayspecifyadditionalconstraints(eg.{NotNULL})ontheroleandcardinalityconstraints(eg.0..n).9.定义关系角色对于每一个关联关系类型,每个关系的结束需要进一步指定角色信息。通常,您将包括主键约束的名称和外键约束的名称。下图说明了这一概念。这在逻辑上定义了两个类之间的关系。此外,您可以指定其他的限制(如不为空)在角色和基数的限制(如0..n)的。ModelbehaviourWenowcometoanotherdifficultissue:whethertomapsomeorallclassbehaviourtothefunctionalcapabilitiesprovidedbydatabasevendorsintheformoftriggers,storedprocedures,uniquenessanddataconstraints,andrelationalintegrity.Anon-persistentobjectmodelwouldtypicallyimplementallthebehaviourrequiredinoneormoreprogramminglanguages(eg.JavaorC++).Eachclasswillbegivenitsrequiredbehaviourandresponsibilitiesintheformofpublic,protectedandprivatemethods.10.行为模型现在我们讨论另一个棘手的问题:是否需要通过数据库厂商提供的触发器,存储过程,唯一性约束,数据完整性的形式,对部分或全部行为映射到类的功能上。非持久性对象模型通常会实现通过一种或多种程序语言(如Java或C++)实现以上所有行为所需的行为。每个类为它的行为和责任设定公共,受保护和私有方法。RelationaldatabasesfromdifferentvendorstypicallyincludesomeformofprogrammableSQLbasedscriptinglanguagetoimplementdatamanipulation.Thetwocommonexamplesaretriggersandstoredprocedures.Whenwemixtheobjectandrelationalmodels,thedecisionisusuallywhethertoimplementallthebusinesslogicintheclassmodel,ortomovesometotheoftenmoreefficienttriggersandstoredproceduresimplementedintherelationalDBMS.Fromapurelyobject-orientedpointofview,theanswerisobviouslytoavoidtriggersandstoredproceduresandplaceallbehaviourintheclasses.Thislocalisesbehaviour,providesforacleanerdesign,GmplifiesmaintenanceandprovidesgoodportabilitybetweenDBMSvendors.来自不同厂商的关系型数据库通常包含一些可编程基于SQL的脚本语言的形式来实现数据操作。有两个常见的例子是触发器和存储过程。当我们混合使用对象和关系模型,通常需要决定所有的业务逻辑是在类模型中实现,还是移到关系数据库DBMS中效率高的触发器和存储过程中实现。从一个纯粹的面向对象角度来看,答案显然是要避免触发器和存储过程,并将所有行为放置在类中。这种本地化的行为,提供了一个更简洁的设计,便于维护和在DBMS供应商之间提供良好的可移植性。Intherealworld,thebottomlinemaybescalingto100'sor1000'softransactionspersecond,somethingstoredproceduresandtriggersarepurposedesignedfor.Ifpurityofdesign,portability,maintenanceandflexibilityarethemaindrivers,localiseallbehaviourintheobjectmethods.在现实世界中,底线可能会控制在每秒100次1000次的处理范围之内,会使用一些存储过程和触发器来进行设计的。如果纯设计,便携性,维护性和灵活性为主要驱动力,将把所有行为本地化到对象方法中。Ifperformanceisanover-ridingconcern,considerdelegatingsomebehaviourtothemoreefficientDBMSscriptinglanguages.Beawarethoughthattheextratimetakentointegratetheobjectmodelwiththestoredproceduresinasafeway,includingissueswithremoteeffectsanddebugging,maycostmoreindevelopmenttimethansimplydeployingtomorecapablehardware.如果关注性能是压倒一切的,可以考虑一些行为使用更有效的DBMS脚本语言。
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 教科版科学五下《改变生态瓶》课件
- 上海科教版品社五上《主题5 农民、牧民、渔民》课件1
- 外研版(三起)三上Module 9《Unit 2 Hes a tor》课件3
- 《庖丁解牛》一等奖课件
- 教科版科学六上《电磁铁的磁力(一)》课件1
- 人教版语文五下儿童诗两首《我想》《童年的水墨画》课件2
- 氧气瓶安全操作规程
- 养老机构网络工程施工方案
- 学校教学楼施工组织设计编制规范
- 暖通空调工程施工组织设计编制规范
- 2027北京协和医院应届毕业生招聘(护理类)考试参考题库及答案解析
- 长征胜利 90 周年 长征精神与新时代青年责任担当课件
- 2026中国内河码头建设政策环境与区域发展机遇研究报告
- 2026 版特殊作业监护人员安全手册
- 麻醉科麻醉复苏查房课件
- 2026年西藏自治区中考化学试题(含解析)
- 2026年江西高中水平测试题语文
- 手术室护理实践指南2025版
- 2026年广东省行政执法专业科目考试真题分析与备考指南
- 2026-2030中国orc低温余热发电系统行业供需形势与营销策略研究报告
- 项目部管理人员安全教育培训
评论
0/150
提交评论