Download presentation
Presentation is loading. Please wait.
1
第3章 数据库建模实践指南 北师大珠海分校软件工程系 赵池龙
2
本章导读 数据库设计既是信息系统建设必备的基础,又是软件工程实践的主要内容,所以计算机及软件专业方向的大学生、研究生和软件工程师,都要特别重视数据库设计。 数据库设计虽然是一个理论问题,但更主要的是一个实践问题。 本章的特点是,将数据库设计的理论与实践紧密相结合,并通过大量案例,来说明数据库设计中需要解决的各种问题。本章的具体内容,表面上没有包括数据库设计中的“正确处理多对多关系和合理进行列变行”的两大技巧,但是这两大技巧却蕴涵在许多实例之中。 学习本章的难度系数,比学习Rational Rose还要大得多。幸好本章的文字语句通俗易懂,图形表格全面细致,这就给读者带来了很大方便。
3
本章对读者的要求 要 求 具 体 内 容 了 解 1)为什么要建立规范化理论 2)第一范式、第二范式、第三范式 3)数据库规范化设计的优点 4)数据库规范化设计的缺点 理 解 1)关系数据库规范化设计理论的实质,就是在数据库设计中实现属性原子化、主键原子化、实体原子化 2)数据库设计评价 3)数据库建模经典案例分析 掌 握 1)数据库设计方法与技巧 2)对象-关系映射
4
数据库设计规范化理论及其反思 1972年,E.F.Codd博士提出了规范化理论来指导数据库的设计,从而开辟了数据库史上新的一页。规范化是通过一系列的测试,来检查设计的关系(二维表)是否符合某一范式的要求。 后来随着时间的发展,越来越多的范式被提出,如图3-1所示。这些范式是嵌套的,就是说,一个范式是在另一个范式之上再做进一步的约束而形成的。 但是,很少有人对这些范式及研究范式的人提出过疑问、进行过反思。
5
表3-2 图书出版社对应表:出现了冗余,冗余会带来插入删除更改异常
图书编号 书名 作者 出版社编号 出版社名称 出版社地址 出版社电话 B0001 实用软件工程 赵池龙 C900 电子工业出版社 北京市海淀区万寿路 B0002 计算机算法设计与分析 王晓东 B0003 程序设计语言编译原理 陈火旺 C901 国防工业出版社 北京市海淀区紫竹院南路 B0004 javascript到jsp范例程序设计 沈建男 C902 中国青年出版社 北京市东四十二条
6
范式 第一范式(First Normal Form,1NF):表的每个列包含且只包含一个值。任何符合关系定义的数据表都在第一范式中。实际上,第一范式就是要求表中的每一列必须是单值,数组和重复的组都不能作为列的值。 第二范式(Second Normal Form,2NF):一个第一范式的表中,每个非主键列都可以从主键列得到。 第三范式(Third Normal Form,3NF):一个第二范式表中的所有非主键列的值,能且只能从主键列中得到。 第三范式已经解决了大部分日常使用中会出现的操作异常,剩下的是那些不常出现的操作问题,要解决这些问题,需要更高的范式进行约束。
7
数据库规范化设计的优点 规范化设计为数据库提供了许多的好处,下面列举了一些主要的优点: l 大大改进数据库的整体组织 l 减少了数据冗余
规范化处理数据库设计,能减少从用户、开发人员到数据库管理员的工作量,使他们能把更多的精力投入到其他工作中。数据冗余的有效控制,能简化数据结构,节省数据的存储空间。由于重复数据的减少,数据的不一致性也大大改善,同时也减轻应用程序为了维护数据的一致性而所花费的代价。这样在进行业务扩充与改造时,数据库的修改也变得相对容易。
8
数据库规范化设计的缺点 对数据库设计进行一定程度的规范化,的确能优化数据库的操作,但不必要的规范化却会带来不必要的麻烦,降低性能,类似的例子还有很多,例如多表联合查询的查询速度要比单表查询慢,有时为了处理事务与数据查询,规范化的数据库比非规范化的数据库要占用更多的CPU,内存和I/O等等。 规范化的目的,只是为了提升数据库的性能。当发现规范化后反而造成了不必要的开销,从而降低了数据库的性能,此时,你应该退一步,相应降低范式的级别,才会看到海阔天空的世界。
9
关系数据库规范化设计理论的反思 反思1:应该让数据库规范化设计的理论,从数学家的书本中或课堂上解放出来,变成软件分析师或设计师的强大设计武器。这里的解放方法,就是要通俗理解各级范式。所谓通俗理解,就是从工程应用上去理解,从数据库设计上去理解,而不要从抽象的数学上(函数依赖、多值依赖、连接依赖等)去理解。 反思2:应该知道,数据库规范化设计理论的目标或实质,就是要在数据库设计中实现“三化”,即“属性原子化、主键原子化、实体原子化”,或者说是“列原子化、键原子化、表原子化”。在这“三化”中,最难的是“实体原子化”,第三范式以上的各级范式,实质上都是为了解决“实体原子化”的问题。试问:如果一开始就用这“三化”思想来指导数据库设计,那么不就完全符合了各级范式的标准了吗?是的,当然是这样。 反思3:要辩证地看待“三化”思想。在实际设计中,为了提高数据库的运行性能,有时要进行一定程度的反规范化设计,即适当增加冗余,达到以空间换时间的目的。这就叫做理论联系实际、实事求是。
10
【定理3-1】 关系数据库规范化设计理论的实质,就是在数据库设计中实现属性原子化、主键原子化、实体原子化。
理解了这三个反思,你就能将深奥的数据库规范化设计理论,变成通俗易懂的数据库设计实践指南。理解了这三个反思,你就能摇身一变,成为一个企业派的数据库分析与设计专家。 通过上述讨论,我们得出如下定理。 【定理3-1】 关系数据库规范化设计理论的实质,就是在数据库设计中实现属性原子化、主键原子化、实体原子化。 由此可见,从软件工程师的角度来看,关系数据库规范化设计的理论,归根到底就是一句话:“属性原子化、主键原子化、实体原子化,再加上适当的数据冗余”,即“三个原子化加上适当的冗余”。 只要记住这句话,软件工程师在关系数据库设计中就不会迷失方向。
11
数据库设计评价 (1)描述事务。 使用这一种方法,要求将每个事务的需求描述存档,检查模型是否提供了事务处理所需要的所有信息(实体,关系和其他属性)。例如我们仍以图书馆信息管理系统为例,现在要求查询读者当前所借阅图书的列表,这样,就要求数据库中存有读者信息,借阅信息并且这两个实体间要有联系才能完成这样一个操作。 (2) 使用事务路径 使用这一种方法,需要设计人员对业务相当的熟悉,熟悉整个业务的流程,包括一些细节的东西,然后在脑海中模拟程序的执行路径,预测得到在执行的过程中需要使用数据库中的哪些元素,这对设计人员有较高的要求。 2.性能评价。 性能评价主要涉及开销问题,包括查询开销、报表生成开销、事务更新开销、内外存占用的开销等等,性能评价与优化密不可分,要在性能上得到提升,需要对包括数据库管理系统、数据库表的设计等多方面进行优化。
12
数据库设计方法与技巧 数据库是信息系统的核心,数据库设计的优劣直接影响信息系统的成败,良好的数据库设计不仅能支撑信息系统顺利完成业务逻辑,同时也为程序员代码的编写提供了便利。 数据库设计不是一蹴而就的事情,而是需要进行设计、评价、再设计、再评价的过程,其中知识和经验的积累是必不可少的东西。 关于数据库设计的方法与技巧,除了《实用软件工程(第二版),赵池龙等人编著,电子工业出版社,2006》一书中介绍的“要善于识别与正确处理多对多关系”、“要学会列变行技巧”之外,还有以下一些数据库设计的知识和经验,希望能给读者一些启示。
13
方法与技巧1:客户是上帝 无论何时何地,客户的需求总是放在第一位的,我们设计数据库,也是为满足需求而做的。不要凭空想象,不要理所当然。 一切为了客户,客户就是上帝,这些观念不但在日常的商业消费行为中渗透,也应在数据库设计中灌输。
14
方法与技巧2:主键的选取 在一个关系数据库中,所有的数据都是存储在表里的,而现代的数据库设计要求每一个表都有一个主键,我们建议使用一个与实体无关的无任何实际意义的序列号来充当,这样的设计可以提高数据库的可移植性。 怎样实现系统自动生成序列号呢?下面给出两种实现方法: (1) 数据库生成机制。 有些关系数据库提供某种序列号生成机制,如Microsoft SQL Server提供的一个Identity的属性,允许每一个表内可以有一个Identity列。Oracle提供了Sequence对象,可以提供序列键值,这样一来实现非常方便。但其他一些数据库引擎则没有相应的机制,例如Sybase就没有类似的功能。甚者,有些商业化的系统(如Vignette Story Server)需要支持几种主要的数据库。那么,这样的系统就不能使用Microsoft SQL Server或Oracle那样的特有的机制,而是必须使用某种具有一般性的机制。因此,我们不推荐使用这种序列号生成机制,除非你能保证在系统的生命周期里始终远行在同一种数据库管理系统上。 (2) 程序生成机制。 可以使用一个表,在其内部设有两个列,一个列存放键名,一个列存放键值。程序使用SQL语句自动管理键值。
15
方法与技巧3:发现西瓜 在与本书配套的教材(参考文献〔1〕)中,专门有一章节介绍了数据库设计中的技巧与艺术,除了讲述了要善于识别与正确处理两个实体之间的多对多关系、要学会“列变行”的设计技巧之外,还重点论述了“西瓜理论与西瓜方法”。 所谓“西瓜理论与西瓜方法”,其实质就是要求设计人员能够分清主次,抓住主要矛盾,分清问题的主要方面与次要方面,以主要带动次要,从而设计出满足用户需求的数据库。那么,怎样才能发现主要矛盾与次要矛盾,分清问题的主要方面与次要方面,也即是找到大西瓜呢?在这种寻找中,知识和经验是最重要的,但在我们看来,还是有一些方法可以遵循。
16
方法与技巧4:树型结构 我们在开发系统的时候,都会遇到树型结构这一类的问题,例如一些明显的主从结构、各大网站上常见的细分类别、应用系统的组织结构、Web系统的菜单树等。 现在我们使用数据库对这些信息进行存储,以下给出两种数据库的设计方案。
17
(1)方案1:
18
(2)方案2:
19
方法与技巧5:权限管理设计 在开发管理信息系统的时候,很多时候都会涉及到用户的权限管理的问题,虽然目前许多大、中型的数据库管理系统已经帮助我们解决了多用户多权限的管理问题,但我们不能依赖数据库管理系统级别的权限设置,究其主要原因有两个: (1) 那些大、中型后台数据库系统软件所提供的多用户及其权限设置都是针对数据库的共有属性,并不一定能完全满足某些特例的需求。 (2) 不要过多的依赖后台数据库系统软件的某些特殊功能,多种大、中型后台数据库系统软件之间并不完全兼容。否则一旦日后需要转换数据库平台或后台数据库系统软件版本升级,之前的架构设计很可能无法重用。 因此,我们有必要自行设计一套能适应以后使用的权限管理的数据库设计方案。
20
图3-4 权限管理
21
方法与技巧6:单表模式 一些细心的人会发现,现实生活中往往需要填写一些通用的表格,这类表格是登记在一定特定的范围之内的信息,例如《中华人民共和国机动车行驶证》,这就不是针对某一种车型的来设计的。 如果对车辆有一定认识的人就会知道,行驶证中的“号牌号码、车辆类型、总质量、整备质量、外廓尺寸、检验记录”是各种类型的车辆的公共属性,“核定载质量、准牵引总质量、驾驶室共乘、货箱内部尺寸、后轴钢板弹簧片数”是货运车辆的专有属性,“核定载客”是客运车辆的专有属性。 那么,我们应该如何设计这一种表格的数据库表呢?有设计师提出了一个名叫“单表模式”的设计思路,所谓单表模式,就是把相关子类的属性统统集中在一个表里,通过“类别”字段来区分表内记录所属的子类以及该类的有效属性。设计如下图3-6所示。
22
图3-6 单表表格
23
方法与技巧7:属性拓展模式 如果说单表模式是针对拥有比较稳定属性的事物,那么属性拓展模式就是针对哪些需求不清楚、事物的属性不稳定的一种解决方案。 如果现在要开发一个网上购物系统,其中要有一个存放商品信息的地方,也许你会设计出以下的数据库表,如图3-7所示。
24
客户突然提出要在商品中添加图片,但不是所有的商品都有图片。此时,代码已经写了一部分了,没办法,客户就是上帝,只好修改数据库,也许你会选择直接在数据库中添加图片属性,但考虑到不是所有商品都有图片,使用image类型的字段会比较浪费空间,所以要么选择把图片属性的类型改为varchar(50)用以存放图片路径,要么新开一个表格,为了讲述属性拓展模式,我们使用新开表格的方式进行拓展,如图3-8所示。
25
又过了一段日子,客户又提出商品的属性还要添加长、宽、高,此时你的程序已经写完了,没办法,还是按照先前的设计思路,再开新表存储,如图3-9所示。
26
系统运行时,如需维护“商品其他属性”,可先从“属性模板”中选择一个属性名称,然后填写“属性值”保存,系统会将对应的产品ID、属性模板ID及刚刚填写的“属性值”一起保存在“商品其他属性”里,这样就完成了相关设置。无论产品的其他属性需求发生怎样的变化、怎样增删改属性,都可以在运行时实现,而不必修改数据库设计和程序代码。如图3-10所示。
27
系统运行时,如需维护“商品其他属性”,程序直接列出“属性名称”,然后填写“属性值”保存,系统会将对应的产品ID、属性名称及刚刚填写的“属性值”一起保存在“商品其他属性”里,这样就完成了相关设置。以后如果需求发生变更,则只需修改相应的程序代码即可,不必修改数据库设计。如图3-11所示。
28
对象--关系映射 现代大部分的商业系统都是使用面向对象的技术进行开发的,比如像Java或者C#之类的,特别是在信息管理系统(MIS/ERP)领域,面向对象的技术更是主流所在。 在使用面向对象的技术进行前台开发的同时,大部分开发人员都会选择关系数据库管理系统(RDBMS)对数据进行管理。但是,面向对象技术和关系数据库是建立在两个不同理论基础之上的,对象技术基于软件工程的一些原理,例如耦合、聚合和封装,而关系范例则基于数学原理,特别是集合论的原理。 两种不同的理论基础导致各自有不同的优缺点。在一个项目的开发过程中,通常会存在着面向对象技术与关系型技术之间的阻抗失配。不过这种阻抗失配很容易被克服,诀窍有两点: (1). 理解把对象映射到关系型数据库的过程。 (2). 如何去实现这些映射。
29
对象--关系映射 对象--关系映射,即ORM(Object Relational Mapping)。它的实质就是将关系数据(库)中的业务数据用对象的形式表示出来,并通过面向对象(Object-Oriented)的方式将这些对象组织起来,实现系统业务逻辑的过程。 在ORM过程中最重要的概念是映射(Mapping),通过这种映射可以使业务对象与数据库分离。 从面向对象来说,数据库不应该和业务逻辑绑定到一起,ORM则起到这样的分离作用,使数据库层透明,开发人员真正的面向对象。 图3-12简单说明了ORM在多层系统架构中的这个作用。
30
图3-12 ORM的多层系统架构
31
1. 属性的映射 类是属性和操作的集合。 一般来说,类的一个属性可以映射到关系型数据库表中0个或者多个字段当中去。
但是,并非所有的属性都需要映射,例如一些统计型的数据,比如一个应用程序记录学生的成绩,那么其中的平均分数一栏,就可以在需要时通过前台应用程序进行计算。 如果一个属性本身就是一个对象,像学生选课系统中的课程对象拥有学生对象一样,这也反映了两个类之间的关系,学生对象也需要映射,这本身就是一个递归的关系。 最简单的映射是把一个属性映射成一列,通常这种情况出现在双方都拥有一样的数据类型,譬如双方都是date型、或者属性是string而列是char型。这样的映射在power Designer中能轻松地完成。
32
2. 继承结构的映射 在面向对象的技术领域中,继承关系是其最重要的特征之一,我们需要把这种特征映射到数据库当中去。对象之间有继承关系,但表之间却没有。在把对象存入关系型数据库的时候,继承的概念会发生了稍许的变化。我们介绍三种常用的解决方法,将继承关系映射到关系数据库,以及由Scott Amber提出的第四种补充的方法。前三种方法在powerDesigner已经有所体现。这些方法如下所示: (1). 整个类层次结构使用一张表 (2). 每个具体类使用一张表 (3). 每个类使用一张表 (4). 所有类映射到一个通用的表结构 我们将使用这一类结构来讲述这四种方法。
33
“学生”类“教师”类“教授”类结构
34
1.整个类层次结构使用一张表 按照这种设计思路,我们可以把所有的类都存储在一张表当中,如图3-15所示。这种方法非常直观,可以一目了然整个类结构,我们建议表的名称最好用根类的类名来命名。 不过,这种整个类层次结构使用一个表,会有一些力不从心的事情发生。如果现在出现了一个新的结构,如图3-16所示,那么表的结构就要添加一个新的字段“津贴”,如果继承的层次不断增多,那么就要不断修改表的结构,这对于实际的开发工作来说非常不利。 还有一个问题,现在出现了一个新的类型,它既是学生又是教师。那么在“类型”一列中就要用一个新的代号来指明,例如学生助教之类的,如果后来又不断出现新的组合类型,那么代码就要不断进行修改,从而造成不断地反工。在这种情况下,可以考虑使用“布尔值代替类型码”的方法,如图3-17所示。
35
整个类层次结构使用一张表图示
36
2.每个具体类使用一张表 按照这种设计思路,每一张表既包含自身的属性又包含它所表示的类继承的属性。 图3-18描述了采取这个方法时的数据表结构。有与“学生”类对应的和与“教师”类对应的表,因为它们是具体类,但没有与“人”类对应的数据表,因为它是抽象类。每个数据实体都有自己的主键,即studentOID 和 teacherOID。 这种设计思路非常容易掌握,但其弊端也非常明显。数据库表会随着类结构的不断增多而日渐庞大,其中有些表显得多余,数据表的无限制的膨胀在数据库设计当中应当避免。
37
图3-18 每个具体类使用一张表
38
按照这种设计思路,为每个类创建一张表,不管其是具体类还是抽象类。 图3-19展示了这种设计思路。
3.每个类使用一张表 按照这种设计思路,为每个类创建一张表,不管其是具体类还是抽象类。 图3-19展示了这种设计思路。 请大家注意,这里是将根类(“人”类)的主键(personOID)作为三个数据表的主键。在“学生”表和“教师”表中,personOID既是主键又是外键,personOID既起到唯一标识一条记录的作用,又能维系表与表之间的关系。在早期的UML中不允许类似<pk,fk>这种复合元素的出现,但在UML的1.4版中已经取消了这种限制。
39
图3-19 每个类使用一张表
40
4.所有类映射到一个通用的表结构 采用这种设计思路,我们需要设计一张通用的表格来存储继承结构,图3-20展示了这种设计思路。这种方法不局限于继承结构,也支持所有形式的映射。该方法也称为元数据驱动。 这样的设计,不管以后类结构如何增加,都能保持表个数的稳定。只需添加记录,就能轻松实现类的类结构的增长。不过,缺点也显而易见,为了重组一个类结构,需要花费的时间相当长,这是由于联合查询所造成的。
41
图3-20 所有类映射到一个通用的表
42
关系的映射 在映射之前,我们需要清楚关系的类型。在数据表之间存在一对一关系,一对多,多对多。而在对象与对象之间,不仅拥有数据表之间的关系,还增加了聚合、关联等。如何能实现平稳的映射呢? 首先介绍处理像聚合、关联等的关系的映射方法。其实,在面向对象建模期间(OOA),最难回答的问题是,何时使用聚合,何时使用关联。性能和灵活性的权衡将会影响到这个问题的答案。 可以使用单表聚合(Single Table Aggregation),这是一种最自然的聚合映射方式。 也可以使用外键聚合(Foreign Key Aggregation),它常常用于处理1:n聚合的映射。 对于n:m的关系,可以使用关联表(Association Table)的策略来解决。
43
1. 单表聚合(Single Table Aggregation)
该模式展示了如何通过把所有的聚合的对象属性,集成到单个的表中的方法,把聚合映射到一个关系数据模型。 请看以下例子,现在有两个类,“学生”类和“联系”类,“学生”类有一属性是联系方式,其类型为“联系”类,现在要把这样的结构映射到数据表当中。按照单表聚合的设计思路,把被聚合对象的属性和使用聚合对象的属性放在同一张表中即可,图3-21为这种策略的通用表示,图3-22则是对应于本例子的图示。
44
通用的单表聚合 AggregatingObject1 Attributes Attributes …… is mapping to
AggregatedObject2 Attributes
45
单表聚合映射方法讨论 映射完成后,可以从若干个技术点对这个映射方法进行讨论:
(1). 性能:在性能方面,该方案是最佳的,因为只需要访问一张表就能够获取一个带聚合的对象,并读入所有聚合对象。另一方面,由于聚合对象的字段的增多,一次读取将会增大数据库读入的页面数,导致IO带宽的浪费。 (2). 可维护性和灵活性:如果聚合的对象类型被多个对象所引用,那么将会降低可维护性,因为每一次对聚合对象类型的修改,都会导致对所有引用聚合对象的修改。 譬如“地址”类新添加了电话号码属性,那么数据库表“学生”表就要添加一个名为电话号码的新列。由于该例子是示例性的例子,结构非常简单,但在实际的设计当中则要进行更多的繁琐的修改。 (3). 数据库的一致性:删除使用聚合的对象时,聚合对象将会自动删除。不需要任何其它的程序或数据库触发器来控制。 (4). 特殊查询:类似查询数据库中所有的“地址”类对象之类的查询,都会变得很难处理。
46
2. 外键聚合(Foreign Key Aggregation)
现在有两个类,“学生”类和“地址”类,“学生”类有属性是家庭住址和宿舍地址,其类型都为“地址”类。按照这种设计思路,可以得出图3-23所示的通用图示和图3-24的对于该例子的图示。
47
图3-23 通用的外键聚合 AggregatingObjects Table ……
is mapping to AggregatingObjects Table …… AggregatedObjectsOID char(64) AggregatedObjects Table SysotherOID char(64) Foreign Key
48
图3-24 “学生”类和“地址”类的外键聚合
49
外键聚合映射方法讨论 (1). 读性能:读取一个学生对象将需要一个连接操作或两次读操作。可以在学生对象中加入地址的引用集合。
(2). 写性能:该模式将按照1:n的关联写入依赖对象,如果写入操作不写入未改变的对象的话,那么写入的成本依赖于改变的依赖对象的个数。 (3). 性能和冗余 VS 维护成本和普通窗体:该映射模式是关系数据库中最常见的模式,因此它和普通的窗体并没有任何的冲突,因此它的维护成本是比较合理的。 所占空间接近于最优--除了在依赖对象表中需要的外键字段以外。 (4). 特殊查询:由于映射是关系数据库应用最为常见的形式,因此特殊的查询也是不难实现的。 (5). 应用程序类型:这种映射模式最适合于关系型应用程序。它不适合用于CAD或CASE应用系统中。因为它是基于以外键形式连接关系表的。实现一个关联需要一次的连接操作或两次的数据库访问。基于页面的存储系统,例如OODBMS,能够更快的处理类似的问题。 (6). 和旧有系统的集成:因为大多数的旧有系统正式使用这种映射关系的,把1:n的关联转换为对象不会出现任何新的问题。
50
3. 关联表(Association Table)
这种策略是展示了如何在两个n:m的对象之间建立映射表。 现在看一个例子。在图书管信息管理系统中,读者类与图书类之间的关系是n:m的,我们要把这两个类映射到数据库表中。按照这种设计思路,要在这两个类之间建立一张关联表,表中存放这两个类所对应表的主键。如图3-25所示。
51
数据库建模经典案例分析 计算机网络系统的设计、安装、调试和维护,主要是网络节点上服务器的设计、安装、调试和维护。
计算机网络信息系统的分析、设计与实现,主要是数据库服务器上数据库的分析、设计与实现,即数据库建模。 数据库分析、设计与实现的关键,是设计出它的概念数据模型,即画出它的实体关系图(E-R图)。 本节对国内IT企业若干个经典软件产品的数据库建模案例,进行简要分析,目的之一是拓展读者的行业领域知识面,以利于就业岗位的选择;目的之二是引导读者进行数据库分析与设计,逐步积累大型信息系统中的大型数据库分析与设计经验。 作为软件工程实践教学的案例,可以抓住以下介绍的任何一个系统,分项目组去组织学生,进行系统的需求分析、设计、编码、测试、运行和维护。
52
1.财务系统案例分析
53
2.混凝土系统案例分析
54
3.进销存系统案例分析
55
4.酒店系统案例分析
56
5.人力资源系统案例分析
57
6.医院系统案例分析
58
7.迭课系统案例分析
59
7.排课系统案例分析
60
8.餐饮系统案例分析
61
9.运动会系统案例分析
62
10.ERP系统案例分析
Similar presentations