新手浅谈数据库中的设计技巧(一)

新手浅谈数据库中的设计技巧(一),第1张

说到数据 我认为不能不先谈数据结构 年 在我初入大学学习计算机编程时 当时的老师就告诉我们说 计算机程序=数据结构+算法 尽管现在的程序开发已由面向过程为主逐步过渡到面向对象为主 但我还是深深赞同 年前老师的告诉我们的公式 计算机程序=数据结构+算法 面向对象的程序开发 要做的第一件事就是 先分析整个程序中需处理的数据 从中提取出抽象模板 以这个抽象模板设计类 再在其中逐步添加处理其数据的函数(即算法) 最后 再给类中的数据成员和函数划分访问权限 从而实现封装 数据库的最初雏形据说源自美国一个奶牛场的记账薄(纸质的 由此可见 数据库并不一定是存储在电脑里的数据^_^) 里面记录的是该奶牛场的收支账目 程序员在将其整理 录入到电脑中时从中受到启发 当按照规定好的数据结构所采集到的数据量大到一定程度后 出于程序执行效率的考虑 程序员将其中的检索 更新维护等功能分离出来 做成单独调用的模块 这个模块后来就慢慢发展 演变成现在我们所接触到的数据库管理系统(dbms)——程序开发中的一个重要分支 下面进入正题 首先按我个人所接触过的程序给数据库设计人员的功底分一下类 1 没有系统学习过数据结构的程序员 这类程序员的作品往往只是他们的即兴玩具 他们往往习惯只设计有限的几个表 实现某类功能的数据全部塞在一个表中 各表之间几乎毫无关联 网上不少的免费管理软件都是这样的东西 当程序功能有限 数据量不多的时候 其程序运行起来没有什么问题 但是如果用其管理比较重要的数据 风险性非常大 2 系统学习过数据结构 但是还没有开发过对程序效率要求比较高的管理软件的程序员 这类人多半刚从学校毕业不久 他们在设计数据库表结构时 严格按照教科书上的规定 死扣e r图和 nf(别灰心 所有的数据库设计高手都是从这一步开始的) 他们的作品 对于一般的access型轻量级的管理软件 已经够用 但是一旦该系统需要添加新功能 原有的数据库表差不多得进行大换血 3 第二类程序员 在经历过数次程序效率的提升 以及功能升级的折腾后 终于升级成为数据库设计的老鸟 第一类程序员眼中的高人 这类程序员可以胜任二十个表以上的中型商业数据管理系统的开发工作 他们知道该在什么样的情况下保留一定的冗余数据来提高程序效率 而且其设计的数据库可拓展性较好 当用户需要添加新功能时 原有数据库表只需做少量修改即可 4 在经历过上十个类似数据库管理软件的重复设计后 第三类程序员中坚持下来没有转行 而是希望从中找出 偷懒 窍门的有心人会慢慢觉悟 从而完成量变到质变的转换 他们所设计的数据库表结构有一定的远见 能够预测到未来功能升级所需要的数据 从而预先留下伏笔 这类程序员目前大多晋级成数据挖掘方面的高级软件开发人员 5 第三类程序员或第四类程序员 在对现有的各家数据库管理系统的原理和开发都有一定的钻研后 要么在其基础上进行二次开发 要么自行开发一套有自主版权的通用数据库管理系统 我个人正处于第三类的末期 所以下面所列出的一些设计技巧只适合第二类和部分第三类数据库设计人员 同时 由于我很少碰到有兴趣在这方面深钻下去的同行 所以文中难免出现错误和遗漏 在此先行声明 欢迎大家指正 不要藏私哦 ) 一 树型关系的数据表 不少程序员在进行数据库设计的时候都遇到过树型关系的数据 例如常见的类别表 即一个大类 下面有若干个子类 某些子类又有子类这样的情况 当类别不确定 用户希望可以在任意类别下添加新的子类 或者删除某个类别和其下的所有子类 而且预计以后其数量会逐步增长 此时我们就会考虑用一个数据表来保存这些数据 按照教科书上的教导 第二类程序员大概会设计出类似这样的数据表结构 类别表_ (type_table_ )名称类型约束条件说明type_id  int  无重复 类别标识 主键type_name char( ) 不允许为空 类型名称 不允许重复type_father  int  不允许为空 该类别的父类别标识 如果是顶节点的话设定为某个唯一值这样的设计短小精悍 完全满足 nf 而且可以满足用户的所有要求 是不是这样就行呢?答案是no!why?我们来估计一下用户希望如何罗列出这个表的数据的 对用户而言 他当然期望按他所设定的层次关系一次罗列出所有的类别 例如这样 总类别类别 类别 类别 类别 类别 类别 类别 类别 类别 ……看看为了实现这样的列表显示(树的先序遍历) 要对上面的表进行多少次检索?注意 尽管类别 可能是在类别 之后添加的记录 答案仍然是n 次 这样的效率对于少量的数据没什么影响 但是日后类型扩充到数十条甚至上百条记录后 单单列一次类型就要检索数十次该表 整个程序的运行效率就不敢恭维了 或许第二类程序员会说 那我再建一个临时数组或临时表 专门保存类型表的先序遍历结果 这样只在第一次运行时检索数十次 再次罗列所有的类型关系时就直接读那个临时数组或临时表就行了 其实 用不着再去分配一块新的内存来保存这些数据 只要对数据表进行一定的扩充 再对添加类型的数量进行一下约束就行了 要完成上面的列表只需一次检索就行了 下面是扩充后的数据表结构 类别表_ (type_table_ )名称类型约束条件 说明type_id  int无重复 类别标识 主键type_name char( ) 不允许为空 类型名称 不允许重复type_father  int  不允许为空 该类别的父类别标识 如果是顶节点的话设定为某个唯一值type_layer  char( )限定 层 初始值为类别的先序遍历 主要为减少检索数据库的次数按照这样的表结构 我们来看看上面例子记录在表中的数据是怎样的 type_id type_name  type_father  type_layer 总类别 类别 类别 类别 类别 类别 类别 类别 类别 类别 ……现在按type_layer的大小来检索一下 select from type_table_ order by type_layer列出记录集如下 type_id type_name  type_father  type_layer 总类别  类别 类别 类别 类别 类别 类别 类别 类别 类别 ……现在列出的记录顺序正好是先序遍历的结果 在控制显示类别的层次时 只要对type_layer字段中的数值进行判断 每 位一组 如大于 则向右移 个空格 当然 我这个例子中设定的限制条件是最多 层 每层最多可设 个子类别 只要按用户的需求情况修改一下type_layer的长度和位数 即可更改限制层数和子类别数 其实 上面的设计不单单只在类别表中用到 网上某些可按树型列表显示的论坛程序大多采用类似的设计 或许有人认为 type_table_ 中的type_father字段是冗余数据 可以除去 如果这样 在插入 删除某个类别的时候 就得对 type_layer 的内容进行比较繁琐的判定 所以我并没有消去type_father字段 这也正符合数据库设计中适当保留冗余数据的来降低程序复杂度的原则 后面我会举一个故意增加数据冗余的案例 二 商品信息表的设计 假设你是一家百货公司电脑部的开发人员 某天老板要求你为公司开发一套网上电子商务平台 该百货公司有数千种商品出售 不过目前仅打算先在网上销售数十种方便运输的商品 当然 以后可能会陆续在该电子商务平台上增加新的商品出售 现在开始进行该平台数据库的商品信息表的设计 每种出售的商品都 lishixinzhi/Article/program/Oracle/201311/17002

数据库三范式详解

数据库三范式

�8�5 1NF-第一范式

每个字段都不可再分。

�8�5 2NF-第二范式

所有字段都完全依赖而不是部分依赖于联合主键。

3NF-第三范式

不存在非主键字段对主键字段的传递依赖。

虽然三范式是这样写,但是现实中不一定都要遵从3范式,而且第三范式基本上很少用到,至于数据库设计的方法就多种多样咯,主要是根据需求来看的

自增长primary key

采用自增长primary key主要是性能 早期的数据库系统 经常采用某种编号 比如身份z号码 公司编号等等作为数据库表的primary key 然而 很快 大家就发现其中的不利之处

比如早期的医院管理系统 用身份z号码作为病人表的primary key 然而 第一 不是每个人都有身份z;第二 对于国外来的病人 不同国家的病人的证件号码并不见得没有重复 因此 用身份z号码作为病人表的primary key是一个非常糟糕的设计 考虑到没有医生或者护士会刻意去记这些号码 使用自增长primary key是更好的设计

公司编号采用某种特定的编码方法 这也是早期的数据库系统常见的做法 它的缺点也显而易见 很容易出现像千年虫的软件问题 因为当初设计数据库表的时候设计的位数太短 导致系统使用几年后不能满足要求 只有修改程序才能继续使用 问题在于 任何人设计系统的时候 在预计某某编号多少位可以够用的时候 都存在预计不准的风险 而采用自增长primary key 则不存在这种问题 同样的道理 没有人可以去记这些号码

使用自增长primary key另外一个原因是性能问题 略有编程常识的人都知道 数字大小比较比字符串大小比较要快得多 使用自增长primary key可以大大地提高数据查找速度

避免用复合主键 (pound primary key)

这主要还是因为性能问题 数据检索是要用到大量的 primary key 值比较 只比较一个字段比比较多个字段快很多 使用单个primary key 从编程的角度也很有好处 sql 语句中 where 条件可以写更少的代码 这意味着出错的机会大大减少

双主键

双主键是指数据库表有两个字段 这两个字段独立成为主键 但又同时存在 数据库系统的双主键最早用在用户管理模块 最早的来源可能是参照 *** 作系统的用户管理模块

*** 作系统的用户管理有两个独立的主键 *** 作系统自己自动生成的随机 ID (Linux windows 的 SID) login id 这两个 ID 都必须是唯一的 不同的是 删除用户 test 然后增加一个用户 test SID 不同 login id 相同 采用双主键主要目的是为了防止删除后增加同样的 login id 造成的混乱 比如销售经理 hellen 本机共享文件给总经理 peter 一年后总经理离开公司 进来一个普通员工 peter 两个peter 用同样的 login id 如果只用 login id 作 *** 作系统的用户管理主键 则存在漏洞 普通员工 peter 可以访问原来只有总经理才能看的文件 *** 作系统自己自动生成的随机 ID 一般情况下面用户是看不到的

双主键现在已经广泛用在各种数据库系统中 不限于用户管理系统

以固定的数据库 表应付变化的客户需求

这主要基于以下几个因素的考虑

大型EPR系统的正常使用 维护需要软件厂商及其众多的合作伙伴共同给客户提供技术服务 包括大量的二次开发

如果用户在软件正常使用过程中需要增加新的表或者数据库 将给软件厂商及其众多的合作伙伴带来难题

软件升级的需要

没有一个软件能够让客户使用几十上百年不用升级的 软件升级往往涉及数据库表结构的改变 软件厂商会做额外的程序将早期版本软件的数据库数据升级到新的版本 但是对于用户使用过程中生成的表进行处理就比较为难

软件开发的需要

使用固定的数据库库表从开发 二次开发来说 更加容易 对于用户使用过程中生成的表 每次查找数据时都要先查表名 再找数据 比较麻烦

举例来说 早期的用友财务软件用Access作数据库 每年建立一个新的数据库 很快 用户和用友公司都发现 跨年度数据分析很难做 因此这是一个不好的设计 在 ERP 中 很少有不同的年度数据单独分开 一般来说 所有年份的数据都在同一个表中 对于跨国公司甚至整个集团公司都用同一个 ERP 系统的时候 所有公司的数据都在一起 这样的好处是数据分析比较容易做

现在大多数数据库系统都能做到在常数时间内返回一定量的数据 比如 Oracle 数据库中 根据 primary key 在 万条数据中取 条数据 与在 亿条数据中取 条数据 时间相差并不多

避免一次取数据库大量数据 取大量数据一定要用分页

这基本上是现在很多数据库系统设计的基本守则 ERP 系统中超过 万条数据的表很多 对于很多表中的任何一个 一次取所有的会导致数据库服务器长时间处于停滞状态 并且影响其它在线用户的系统响应速度

一般来说 日常 *** 作 在分页显示的情况下面 每次取得数据在 之间 系统响应速度足够快 客户端基本没有特别长的停顿 这是比较理想的设计 这也是大型数据库系统往往用 ODBC ADO 等等通用的数据库联接组件而不用特定的速度较快的专用数据库联接组件的原因 因为系统瓶颈在于数据库( Database) 方面(数据量大) 而不在于客户端(客户端每次只取少量数据)

在 B/S 数据库系统中 分页非常普遍 早期的数据库系统经常有客户端程序中一次性取大量数据做缓冲 现在已经不是特别需要了 主要原因有

数据库本身的缓冲技术大大提高

大部分数据库都会自动将常用的数据自动放在内存中缓冲 以提高性能

数据库联接组件的缓冲技术也在提高

包括 ADO 在内的一些数据库联接组件都会自动对数据结果集(result set)进行缓冲 并且效果不错 比较新颖的数据库联接组件 比如 Hibernate 也加入了一些数据结果集缓冲功能

当然 也有一些数据库联接组件没有对数据结果集进行缓冲 比如 JDBC Driver 不过几年之内情况应该有所改观 也有些不太成功的数据缓冲 比如 EJB 中的实体Bean 性能就不尽如人意 实体Bean数据也是放在内存中 可能是因为占用内存过多的缘故

lishixinzhi/Article/program/SQL/201311/16157

(1)存储记录结构设计综合分析数据存储要求和应用需求,设计存储记录格式

(2)存储空间分配存储空间分配有两个原则:①存取频度高的数据尽量安排在快速、随机设备上,存取频度低的数据则安排在速度较慢的设备上

②相互依赖性强的数据尽量存储在同一台设备上,且尽量安排在邻近的存储空间上

从提高系统性能方面考虑,应将设计好的存储记录作为一个整体合理地分配物理存储区域

尽可能充分利用物理顺序特点,把不同类型的存储记录指派到不同的物理群中

(3)访问方法的设计一个访问方法包括存储结构和检索机构两部分

存储结构限定了访问存储记录时可以使用的访问路径;检索机构定义了每个应用实际使用的访问路径

(4)物理设计的性能评价①查询响应时间从查询开始到有结果显示之间所经历的时间称为查询响应时间

查询响应时间可进一步细分为服务时间、等待时间和延迟时间

在物理设计过程中,要对系统的性能进行评价

性能评价包括时间、空间、效率、开销等各个方面

⊙CPU服务时间和I/O服务时间的长短取决于应用程序设计

⊙CPU队列等待时间和I/O队列等待时间的长短受计算机系统作业的影响

⊙设计者可以有限度地控制分布式数据库系统的通信延迟时间

②存储空间存储空间存放程序和数据

程序包括运行的应用程序、DBMS子程序、OS子程序等

数据包括用户工作区、DBMS工作区、OS工作区、索引缓冲区、数据缓冲区等

存储空间分为主存空间和辅存空间

设计者只能有限度地控制主存空间,例如可指定缓冲区的分配等

但设计者能够有效地控制辅存空间

③开销与效率设计中还要考虑以下各种开销,开销增大,系统效率将下降

⊙事务开销指从事务开始到事务结束所耗用的时间

更新事务要修改索引、重写物理块、进行写校验等 *** 作,增加了额外的开销

更新频度应列为设计的考虑因素

⊙报告生成开销指从数据输入到有结果输出这段时间

报告生成占用CPU及I/O的服务时间较长

设计中要进行筛选,除去不必要的报告生成

⊙对数据库的重组也是一项大的开销

设计中应考虑数据量和处理频度这两个因数,做到避免或尽量减少重组数据库

在物理设计阶段,设计、评价、修改这个过程可能要反复多次,最终得到较为完善的物理数据库结构说明书

建立数据库时,DBA依据物理数据库结构说明书,使用DBMS提供的工具可以进行数据库配置

在数据库运行时,DBA监察数据库的各项性能,根据依据物理数据库结构说明书的准则,及时进行修正和优化 *** 作,保证数据库系统能够保持高效率地运行

6

程序编制及调试在逻辑数据库结构确定以后,应用程序设计的编制就可以和物理设计并行地展开程序模块代码通常先在模拟的环境下通过初步调试,然后再进行联合调试

联合调试的工作主要有以下几点:(1)建立数据库结构根据逻辑设计和物理设计的结果,用DBMS提供的数据语言(DDL)编写出数据库的源模式,经编译得到目标模式,执行目标模式即可建立实际的数据库结构

(2)调试运行数据库结构建立后,装入试验数据,使数据库进入调试运行阶段

运行应用程序,测试(3)装入实际的初始数据在数据库正式投入运行之前,还要做好以下几项工作:(1)制定数据库重新组织的可行方案

(2)制定故障恢复规范(3)制定系统的安全规范7

运行和维护数据库正式投入运行后,运行维护阶段的主要工作是:(1)维护数据库的安全性与完整性

按照制定的安全规范和故障恢复规范,在系统的安全出现问题时,及时调整授权和更改密码

及时发现系统运行时出现的错误,迅速修改,确保系统正常运行

把数据库的备份和转储作为日常的工作,一旦发生故障,立即使用数据库的最新备份予以恢复

(2)监察系统的性能

运用DBMS提供的性能监察与分析工具,不断地监控着系统的运行情况

当数据库的存储空间或响应时间等性能下降时,立即进行分析研究找出原因,并及时采取措施改进

例如,可通修改某些参数、整理碎片、调整存储结构或重新组织数据库等方法,使数据库系统保持高效率地正常运作

(3)扩充系统的功能在维持原有系统功能和性能的基础上,适应环境和需求的变化,采纳用户的合理意见,对原有系统进行扩充,增加新的功能

第一范式(1NF):数据库表中的字段都是单一属性的,不可再分。这个单一属性由基本类型构成,包括整型、实数、字符型、逻辑型、日期型等。

例如,如下的数据库表是符合第一范式的:

字段1 字段2 字段3 字段4

而这样的数据库表是不符合第一范式的:

字段1 字段2 字段3 字段4

字段31 字段32

很显然,在当前的任何关系数据库管理系统(DBMS)中,傻瓜也不可能做出不符合第一范式的数据库,因为这些DBMS不允许你把数据库表的一列再分成二列或多列。因此,你想在现有的DBMS中设计出不符合第一范式的数据库都是不可能的。

第二范式(2NF):数据库表中不存在非关键字段对任一候选关键字段的部分函数依赖(部分函数依赖指的是存在组合关键字中的某些字段决定非关键字段的情况),也即所有非关键字段都完全依赖于任意一组候选关键字。

假定选课关系表为SelectCourse(学号, 姓名, 年龄, 课程名称, 成绩, 学分),关键字为组合关键字(学号, 课程名称),因为存在如下决定关系:

(学号, 课程名称) → (姓名, 年龄, 成绩, 学分)

这个数据库表不满足第二范式,因为存在如下决定关系:

(课程名称) → (学分)

(学号) → (姓名, 年龄)

即存在组合关键字中的字段决定非关键字的情况。

由于不符合2NF,这个选课关系表会存在如下问题:

(1) 数据冗余:

同一门课程由n个学生选修,"学分"就重复n-1次;同一个学生选修了m门课程,姓名和年龄就重复了m-1次。

(2) 更新异常:

若调整了某门课程的学分,数据表中所有行的"学分"值都要更新,否则会出现同一门课程学分不同的情况。

(3) 插入异常:

假设要开设一门新的课程,暂时还没有人选修。这样,由于还没有"学号"关键字,课程名称和学分也无法记录入数据库。

(4) 删除异常:

假设一批学生已经完成课程的选修,这些选修记录就应该从数据库表中删除。但是,与此同时,课程名称和学分信息也被删除了。很显然,这也会导致插入异常。

把选课关系表SelectCourse改为如下三个表:

学生:Student(学号, 姓名, 年龄);

课程:Course(课程名称, 学分);

选课关系:SelectCourse(学号, 课程名称, 成绩)。

这样的数据库表是符合第二范式的, 消除了数据冗余、更新异常、插入异常和删除异常。

另外,所有单关键字的数据库表都符合第二范式,因为不可能存在组合关键字。

第三范式(3NF):在第二范式的基础上,数据表中如果不存在非关键字段对任一候选关键字段的传递函数依赖则符合第三范式。所谓传递函数依赖,指的是如果存在"A → B → C"的决定关系,则C传递函数依赖于A。因此,满足第三范式的数据库表应该不存在如下依赖关系:

关键字段 → 非关键字段x → 非关键字段y

假定学生关系表为Student(学号, 姓名, 年龄, 所在学院, 学院地点, 学院电话),关键字为单一关键字"学号",因为存在如下决定关系:

(学号) → (姓名, 年龄, 所在学院, 学院地点, 学院电话)

这个数据库是符合2NF的,但是不符合3NF,因为存在如下决定关系:

(学号) → (所在学院) → (学院地点, 学院电话)

即存在非关键字段"学院地点"、"学院电话"对关键字段"学号"的传递函数依赖。

它也会存在数据冗余、更新异常、插入异常和删除异常的情况,读者可自行分析得知。

把学生关系表分为如下两个表:

学生:(学号, 姓名, 年龄, 所在学院);

学院:(学院, 地点, 电话)。

这样的数据库表是符合第三范式的,消除了数据冗余、更新异常、插入异常和删除异常。

鲍依斯-科得范式(BCNF):在第三范式的基础上,数据库表中如果不存在任何字段对任一候选关键字段的传递函数依赖则符合第三范式。

假设仓库管理关系表为StorehouseManage(仓库ID, 存储物品ID, 管理员ID, 数量),且有一个管理员只在一个仓库工作;一个仓库可以存储多种物品。这个数据库表中存在如下决定关系:

(仓库ID, 存储物品ID) →(管理员ID, 数量)

(管理员ID, 存储物品ID) → (仓库ID, 数量)

所以,(仓库ID, 存储物品ID)和(管理员ID, 存储物品ID)都是StorehouseManage的候选关键字,表中的唯一非关键字段为数量,它是符合第三范式的。但是,由于存在如下决定关系:

(仓库ID) → (管理员ID)

(管理员ID) → (仓库ID)

即存在关键字段决定关键字段的情况,所以其不符合BCNF范式。它会出现如下异常情况:

(1) 删除异常:

当仓库被清空后,所有"存储物品ID"和"数量"信息被删除的同时,"仓库ID"和"管理员ID"信息也被删除了。

(2) 插入异常:

当仓库没有存储任何物品时,无法给仓库分配管理员。

(3) 更新异常:

如果仓库换了管理员,则表中所有行的管理员ID都要修改。

把仓库管理关系表分解为二个关系表:

仓库管理:StorehouseManage(仓库ID, 管理员ID);

仓库:Storehouse(仓库ID, 存储物品ID, 数量)。

这样的数据库表是符合BCNF范式的,消除了删除异常、插入异常和更新异常。

范式应用

我们来逐步搞定一个论坛的数据库,有如下信息:

(1) 用户:用户名,email,主页,电话,联系地址

(2) 帖子:发帖标题,发帖内容,回复标题,回复内容

第一次我们将数据库设计为仅仅存在表:

用户名 email 主页 电话 联系地址 发帖标题 发帖内容 回复标题 回复内容

这个数据库表符合第一范式,但是没有任何一组候选关键字能决定数据库表的整行,唯一的关键字段用户名也不能完全决定整个元组。我们需要增加"发帖ID"、"回复ID"字段,即将表修改为:

用户名 email 主页 电话 联系地址 发帖ID 发帖标题 发帖内容 回复ID 回复标题 回复内容

这样数据表中的关键字(用户名,发帖ID,回复ID)能决定整行:

(用户名,发帖ID,回复ID) → (email,主页,电话,联系地址,发帖标题,发帖内容,回复标题,回复内容)

数据库设计的概念设计阶段,表示概念结构的常用方法和描述工具是实体联系法和实体联系图。

数据库设计(Database Design)是指对于一个给定的应用环境,构造最优的数据库模式,建立数据库及其应用系统,使之能够有效地存储数据,满足各种用户的应用需求(信息要求和处理要求)。在数据库领域内,常常把使用数据库的各类系统统称为数据库应用系统。

数据库设计的设计内容包括:需求分析、概念结构设计、逻辑结构设计、物理结构设计、数据库的实施和数据库的运行和维护。

数据库设计(Database Design)是指根据用户的需求,在某一具体的数据库管理系统上,设计数据库的结构和建立数据库的过程。数据库系统需要 *** 作系统的支持。

数据库设计是建立数据库及其应用系统的技术,是信息系统开发和建设中的核心技术。由于数据库应用系统的复杂性,为了支持相关程序运行,数据库设计就变得异常复杂,因此最佳设计不可能一蹴而就,而只能是一种“反复探寻,逐步求精”的过程,也就是规划和结构化数据库中的数据对象以及这些数据对象之间关系的过程。

以上就是关于新手浅谈数据库中的设计技巧(一)全部的内容,包括:新手浅谈数据库中的设计技巧(一)、数据库设计的内容原则及其方法、数据库进阶:ERP管理软件数据库系统的几种设计方法等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/sjk/9819264.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-02
下一篇 2023-05-02

发表评论

登录后才能评论

评论列表(0条)

保存