简介:图书馆管理系统设计开发中,如何梳理业务模块与数据关系往往是首要难点,这份doc文档恰好给出了一套可直接参考的解决方案,适合课程设计、毕业设计及系统需求分析人员使用。文档按开发流程组织:先罗列检索慢、借还书工作量大等现状问题,明确系统目标,再用系统功能结构图、业务流程图、数据流图、总体ER图和数据字典,逐步展开用户管理、书籍类型管理、书籍管理、读者管理、借阅管理六大模块的逻辑与调用关系;同时细化到借书、还书、图书查询的功能定义,并给出相关字段的取值含义说明,方便开发或写作时参照。包体为单个Word文档,共1个doc文件,压缩后大小约1024KB,内容集中,便于打印或直接复制编辑。这份文档发布后已有3099人学习/下载,对补充数据库设计说明、梳理系统流程、撰写设计文档都有较直接的参考价值。
1. 图书馆管理系统业务流程图、数据流程图与 ER 图:开发前先把这三张图画明白
如果你接过课程设计或毕业设计,大概率遇到过这种情况:代码写了一半,导师突然要你补交业务流程图、数据流程图和 ER 图。这时候你才意识到,真正的坑不是写代码,而是你根本说不清读者借书之后,系统里哪张表减了复本量、哪张表加了当前借书量、哪张表插入了借阅记录。这份图书馆管理系统设计文档,把需求分析、功能结构、业务流程图、数据流程图、ER 图和数据字典完整打包,正好解决"文档不知道怎么写、图不知道怎么画"的问题。它适合两类人:一类是做图书馆管理系统课程设计的学生,另一类是刚接触系统设计文档、想把表结构和业务流程理清的开发者。我拆完这份文档后最直观的感受是:它把"借书、还书、读者管理"这三个高频场景背后的数据变化路径全部画清楚了,照着它建表、写功能模块,基本不会出现逻辑断层。
2. 需求分析与功能结构:先把六大模块的边界拆明白,再谈建表和编码
2.1 需求分析里的三个高频痛点
这份文档在一开头就列出了传统图书馆管理存在的问题,这三条基本决定了你后面所有功能模块的设计方向。第一是检索速度慢、效率低,因为藏书量大、分类复杂,手工查找书籍信息非常耗时,而且经常出现查到了书的信息、实际馆中没有或已被借走的情况。第二是借书还书工作量大,借阅频率越高,人工登记、图书更新、超期遗失处理的工作量越大,还容易出错。第三是图书统计难、藏书更新不能及时完成,因为数量和种类太多,加上自然损耗与人为破坏,图书统计和分析很难及时完成。
这三个痛点直接映射到系统的功能需求上:检索慢对应图书查询模块,借还书工作量大对应借阅管理模块,统计难对应书籍类型管理和系统管理。也就是说,这份文档不是为写而写的需求分析,而是每一条痛点都有对应的功能模块去解决。你在写自己的需求分析章节时,也可以用同样的思路:先列问题,再说系统目标,最后引出功能需求,这样的逻辑链条答辩时很加分。
2.2 功能结构图拆解:六大模块的边界划分
文档给出的系统功能结构图包含六个模块:用户管理、书籍类型管理、书籍管理、借阅管理、读者管理、系统管理。这里要注意,文档中的功能结构图原文用的是"图书管理系统的用户管理、书籍类型管理、书籍管理、借阅管理、读者管理、系统管理"这种并列关系,但细看会发现系统管理是基础配置层,书籍管理是核心数据层,借阅管理是业务操作层。
用户管理模块包含添加用户、编辑用户、删除用户、修改密码,服务对象是系统管理员。书籍类型管理包含添加类型、浏览类型,核心字段是类型编号、类型名称、借阅天数、罚金。书籍管理包含添加书籍、编辑书籍、删除书籍、查找书籍,核心字段是书籍编号、书籍名称、书籍类型、作者、当前复本量。借阅管理是文档里处理得最细的部分,它分为借阅书籍、归还书籍、查询书籍、修改借阅天数、修改过期罚金,这一块在数据流程图里被单独拆成了三层来画。读者管理维护读者编号、姓名、电话、最大借阅量、当前借书量。系统管理负责退出系统。
实际开发时,这六个模块可以对应到不同的数据表,但这种对应关系不是一一对应的。比如读者管理模块会同时操作 tbReader 表和 tbBorrow 表,借阅管理模块会同时操作 tbBorrow、tbBook、tbReader 三张表。这也是很多新手在画数据流程图时容易卡住的地方:模块和表不是一对一,而是多对多的关系。
2.3 角色权限设计:三类管理员的权限边界
文档在功能需求定义里明确了三类角色:系统管理员、图书管理员、借阅管理员。系统管理员能增删改查所有管理员的信息、书籍类型信息、书籍信息、读者信息,并且能借阅和归还图书。图书管理员只负责书籍类型和书籍信息的增删改查。借阅管理员只负责读者信息的增删改查以及借书还书操作。
这种角色划分直接决定了 tbUser 表中的 Qx(权限)字段怎么取值。我一般会用数字或字符串来区分权限级别,比如 0 代表系统管理员、1 代表图书管理员、2 代表借阅管理员。权限控制通常在登录后根据 Qx 值决定渲染哪些菜单和按钮,这样在业务代码里只需要在路由或菜单配置里做一次判断,不需要每个接口都写权限校验逻辑。文档里虽然没有展开权限控制的实现细节,但这个字段的存在已经足够支撑起前端的权限管理系统。
3. 业务流程图与数据流程图:从顶层图到三层图,看数据是怎么一步步流动的
3.1 业务流程图里最容易出错的借阅闭环
文档的业务流程图包含五个部分:用户管理、书籍类型管理、书籍管理、读者管理、借阅管理。其中借阅管理又细分为借阅和归还两个流程。很多人画业务流程图时容易把借书和还书画成两个孤立的流程,但实际业务中它们是一个闭环:借书时减少书籍当前复本量、增加读者当前借书量、新增一条借阅记录;还书时增加书籍当前复本量、减少读者当前借书量、更新借阅记录的还书日期。
如果你用 Visio 或 Draw.io 画业务流程图,建议用泳道图来表达,泳道按角色划分:读者、借阅管理员、系统。读者提交借书申请,借阅管理员检查读者当前借书量是否达到 Maxjsl 上限,检查书籍当前复本量 Zt 是否大于 0,通过后写入借阅记录,然后同时更新 tbBook 的 Zt 减 1 和 tbReader 的 Yjsl 加 1。这一条路径画完,借书流程才算是闭环。还书流程则是反向操作,但多了一个超期判断:如果当前日期减去 Jsdate 超过 tbType 中该类型对应的 Jt(借阅天数),则按 Fj(罚金)计算罚款。
3.2 数据流程图分层规则:顶层图、1 层图、2 层图、3 层图怎么看
数据流程图是这份文档里最核心也最容易晕的部分。文档给出的分层结构是顶层图、1 层图、2 层图、3 层图。顶层图通常只画一个系统和一个外部实体,外部实体就是管理员。1 层图开始拆出主要处理模块,比如 P2.1 登录、P2.2 用户管理、P2.3 书籍类型管理、P2.4 书籍管理、P2.5 读者管理、P2.6 借阅管理。2 层图进一步细化,比如 P2.6 借阅管理会拆出 P2.6.1 处理书籍信息、P2.6.2 处理读者信息、P2.6.3 处理借阅信息。3 层图则更细。
画数据流程图的关键是遵守"父图与子图平衡"原则:父图中某个处理模块的输入输出数据流,必须和子图的输入输出保持一致。文档里 P2.6 借阅管理的输入是 F10,组成是 Jyid+Rid+Bid+Jsdate+Hsdate+Zt+Maxjsl+Yjsl,输出是 F11(处理后的借阅书籍信息)和 F12(处理后归还书籍信息)。到了 3 层图,P2.6.1 处理书籍信息的输入是 F6、F10,输出是 F13;P2.6.2 处理读者信息的输入是 F8、F10,输出是 F14。
3.3 借阅管理的三层分解:P2.6 的内部处理逻辑
这里我把文档里最值钱的一段拆出来讲。P2.6.1 处理书籍信息,输入 F6(书籍信息)和 F10(借阅管理信息),输出 F13,处理逻辑是"将借阅书籍的当前复本量减 1"。P2.6.2 处理读者信息,输入 F8(读者信息)和 F10,输出 F14,处理逻辑是"将读者的当前借阅量减 1"。注意这里文档有个笔误,处理读者信息时应该是"当前借阅量加 1",因为读者借书后当前借书量是增加的。这个笔误我在第 5 章识别 ER 图与数据字典矛盾时会再次提到,属于典型的文档复制粘贴错误。P2.6.3 处理借阅信息,输入 F13、F14,输出 F11,处理逻辑是"将 F13、F14 的数据流拼合起来,写入 tbBorrow"。
这个三层分解的价值在于,它把一次借书操作拆成了三个独立的数据处理步骤,每个步骤只关注一张表的变化。你在写代码时,如果按照这个拆分来做事务管理,借书接口就会非常清晰:先更新 tbBook 表,再更新 tbReader 表,最后插入 tbBorrow 表。而且这三个步骤必须在同一个数据库事务里,任何一个失败都要回滚,否则会出现书扣了复本量但没加借阅记录的脏数据。
3.4 避坑:数据流程图里常见的 4 个翻车点
第一个问题是父图与子图的数据流不一致。常见现象:顶层图里有 F1 登录信息,但 1 层图里 P2.1 的输入输出没有对应上。原因是画图时先画了子图再拼父图,数据流名没统一。解决方法是先定义好数据流编号,比如 F1 到 F14,然后每层图只引用这些编号,不新建名称。
第二个问题是外部实体画错了位置。数据流程图中外部实体是系统之外的人员或系统,比如管理员、读者。常见现象:把 tbUser、tbBook 这些数据存储画成了外部实体。原因是分不清"数据的来源"和"数据的存储"。解决办法是记住一个原则:凡是带表的,都是数据存储;凡是人,才是外部实体。
第三个问题是数据处理编号混乱。常见现象:P2.6.1 在 2 层图中出现了,但 3 层图中编号对不上。原因是分层细化时没有按"父处理编号+小数点+子序号"的规则命名。解决办法是 P2.6 的子处理必须是 P2.6.1、P2.6.2、P2.6.3,不能跳号。
第四个问题是数据流命名与数据字典不一致。常见现象:数据字典里写的是 F10 借阅管理信息,但图里标成了 F10 借阅信息。原因是画图和写字典不同步。解决办法是画完图后,拿着数据字典逐条核对每个 F 编号的名称和组成字段,一个字母都不要差。这一步看起来很笨,但答辩时评审老师最喜欢查的就是这里。
4. ER 图与数据字典:五大表设计背后的字段参数与关系
4.1 总体 ER 图:五个实体的关系梳理
文档给出的总体 ER 图包含五个实体:书籍(tbBook)、读者(tbReader)、用户(tbUser)、书籍类型(tbType)、借阅(tbBorrow)。实体间的关系是:书籍属于书籍类型(N:1),读者借阅书籍(M:N,通过 tbBorrow 表现为 1:N 的两条边),用户不直接参与借阅业务。
在我画过的图书管理类项目里,最容易画错的是书籍和借阅的关系。很多新手会画成读者直接借阅书籍的多对多关系,然后单独建一张借阅表,这没有错,但更规范的做法是把借阅表当成一个实体来画,它同时连接书籍和读者两个实体,并且携带借书日期、还书日期、状态等属性。文档采用的正是这种思路:tbBorrow 是实体,不是关系,它有自己独立的字段 Jyid、Rid、Bid、Jsdate、Hsdate。
4.2 表结构与字段参数详解
这里把文档数据字典里的核心表整理成表格,方便你对照建表和画 ER 图。
| 表名 | 字段名 | 类型 | 长度/范围 | 说明 |
|---|---|---|---|---|
| tbBook | Bid | nvarchar | 50 | 书籍编号,主键 |
| tbBook | Bookname | nvarchar | 50 | 书籍名称 |
| tbBook | Typename | nvarchar | 50 | 所属类型名称 |
| tbBook | Author | nvarchar | 50 | 作者 |
| tbBook | Zt | nvarchar | 50 | 当前复本量 |
| tbBorrow | Jyid | nvarchar | 50 | 借阅编号,主键 |
| tbBorrow | Rid | nvarchar | 50 | 读者编号,外键 |
| tbBorrow | Bid | nvarchar | 50 | 书籍编号,外键 |
| tbBorrow | Jsdate | datetime | 8 | 借书日期 |
| tbBorrow | Hsdate | datetime | 8 | 还书日期 |
| tbType | Typeid | nvarchar | 50 | 书籍类型编号,主键 |
| tbType | Typename | nvarchar | 50 | 书籍类型名称 |
| tbType | Jt | Int | 4 | 借阅天数 |
| tbType | Fj | money | 8 | 每日罚金 |
| tbReader | Rid | nvarchar | 50 | 读者编号,主键 |
| tbReader | Readername | nvarchar | 50 | 读者姓名 |
| tbReader | Phone | nvarchar | 50 | 联系电话 |
| tbReader | Maxjsl | Int | 4 | 最大借阅量 |
| tbReader | Yjsl | Int | 4 | 当前借书量 |
| tbUser | Userid | nvarchar | 50 | 用户编号,主键 |
| tbUser | Name | nvarchar | 50 | 用户名 |
| tbUser | Pass | nvarchar | 50 | 用户密码 |
| tbUser | Qx | nvarchar | 50 | 权限 |
| tbUser | Phone | nvarchar | 50 | 用户联系电话 |
这份文档里有个很典型的问题:tbBook 的 Zt(当前复本量)字段类型定义成了 nvarchar(50),这从数据库设计角度是不合理的。复本量是数量,应该用 Int,否则你无法对它做加减运算。文档里 P2.6.1 处理书籍信息的逻辑是"将借阅书籍的当前复本量减 1",如果 Zt 是字符串类型,这条逻辑在代码里就需要先转换类型再计算。我在第 5 章会给出修正方案。
另外一个值得注意的点是 tbBook 的 Typename 直接用了类型名称,而不是引用 tbType 的 Typeid。这个设计的优点是查询时少一次连表,缺点是如果类型改名,所有引用这个 Typename 的书籍记录都要批量更新。实际项目中我倾向于在 tbBook 里存 Typeid 外键,查询时 JOIN 出 Typename,这样符合数据库第三范式,虽然多一次连表,但数据一致性更好。
4.3 数据流定义:F1~F14 与外部的连接
数据字典里定义了 13 条数据流,编号从 F1 到 F14,其中 F3 和 F4 之间的命名我核对后确认文档里没有 F11 到 F14 之外的跳号,实际上 F10 和 F11 之间是连续的。这里给你梳理关键几条:F1 登录信息,来源是用户,去处是 P2.1,组成是 Name+Pass+Qx。F2 用户信息,来源是 tbUser,去处是 P2.2,组成是 Userid+Name+Pass+Qx。F6 书籍信息,来源是 tbBook,去处是 P2.4,组成是 Bid+Bookname+Typename+Author+Zt。F8 读者信息,来源是 tbReader,去处是 P2.5,组成是 Rid+Readername+Phone+Maxjsl+Yjsl。F10 借阅管理信息,来源是 tbBorrow、tbBook、tbReader,去处是 P2.6,组成是 Jyid+Rid+Bid+Jsdate+Hsdate+Zt+Maxjsl+Yjsl。
数据流定义的价值在于,它明确了每个处理模块的输入输出边界。你在写接口时,每个接口的入参和出参基本可以直接照抄这些数据流的组成。比如借书接口,入参是 Rid、Bid,处理后返回当前复本量减 1 后的书籍信息和当前借书量加 1 后的读者信息,这和 F13、F14 的定义是吻合的。把数据字典里 F 编号的数据流定义整理成接口文档,是一个非常省力的方式。
5. 从 ER 图到建表 SQL:文档落地的完整转换过程
5.1 实体、属性、关系转表的三条规则
ER 图转成数据库表,核心是三条规则。第一,每个实体建一张表,实体的每个属性对应表的一个字段。第二,1:N 关系通过在 N 端表中添加外键来实现,比如书籍属于书籍类型,就在 tbBook 里加 Typeid 外键。第三,M:N 关系需要拆成一张中间表,比如读者和书籍的借阅关系,拆成 tbBorrow 表,这张表同时包含读者端外键和书籍端外键,以及自身的业务属性。
文档里的总体 ER 图采用的是简化设计:读者借阅书籍是 M:N,但通过 tbBorrow 表把多对多关系转成了两个 1:N 关系。tbBorrow 表里同时有 Rid 外键和 Bid 外键,以及借书日期、还书日期属性。这是经典的"借阅记录"建模方式,也是我推荐你在课程设计里采用的方式,因为它符合直觉、容易解释、查询也方便。
5.2 建表 SQL 与关键约束
把 ER 图和数据字典落到建表脚本,是这个资源最直接的落地方式。我根据文档的数据字典给出一个修正版的建表 SQL,其中把 tbBook 的 Zt 改成了 Int,把 Typename 改成了 Typeid 外键:
CREATE TABLE tbType ( Typeid nvarchar(50) PRIMARY KEY, Typename nvarchar(50) NOT NULL, Jt INT NOT NULL, Fj DECIMAL(10, 2) NOT NULL ); CREATE TABLE tbBook ( Bid nvarchar(50) PRIMARY KEY, Bookname nvarchar(50) NOT NULL, TypeId nvarchar(50) NOT NULL, Author nvarchar(50), Zt INT NOT NULL DEFAULT 0, CONSTRAINT FK_Book_Type FOREIGN KEY (TypeId) REFERENCES tbType(Typeid) ); CREATE TABLE tbReader ( Rid nvarchar(50) PRIMARY KEY, Readername nvarchar(50) NOT NULL, Phone nvarchar(50), Maxjsl INT NOT NULL DEFAULT 5, Yjsl INT NOT NULL DEFAULT 0 ); CREATE TABLE tbBorrow ( Jyid nvarchar(50) PRIMARY KEY, Rid nvarchar(50) NOT NULL, Bid nvarchar(50) NOT NULL, Jsdate DATETIME NOT NULL, Hsdate DATETIME, CONSTRAINT FK_Borrow_Reader FOREIGN KEY (Rid) REFERENCES tbReader(Rid), CONSTRAINT FK_Borrow_Book FOREIGN KEY (Bid) REFERENCES tbBook(Bid) ); CREATE TABLE tbUser ( Userid nvarchar(50) PRIMARY KEY, Name nvarchar(50) NOT NULL, Pass nvarchar(50) NOT NULL, Qx nvarchar(50) NOT NULL, Phone nvarchar(50) );这段 SQL 与原文档有两个重要差异。第一,tbBook 表的 Zt 字段从 nvarchar(50) 改成了 INT,因为复本量参与加减运算,必须是数值类型,你如果在 SQL Server 里复查原表结构时会发现 nvarchar 类型无法直接执行UPDATE tbBook SET Zt = Zt - 1。第二,tbBook 不再直接存 Typename,而是增加 TypeId 外键引用 tbType 表,这样书籍类型改名时只需要更新 tbType 一条记录,不需要批量更新 tbBook。如果你坚持用 Typename 直存,也可以从原文档,但不推荐。
外键约束是文档里没有明确写、但必须有的部分。tbBorrow 表的 Rid 外键和 Bid 外键保证了借阅记录不会引用不存在的读者或书籍。同时我还给 tbReader 的 Yjsl 字段设置了 DEFAULT 0,给 Maxjsl 设置了 DEFAULT 5,这些默认值在实际借阅流程里很重要,能防止空值导致的业务异常。
5.3 借书、还书两个过程的数据变化
建完表之后,借书和还书这两个过程对应 SQL 操作就非常清晰了。借书时,系统需要执行三个动作:第一步检查读者当前借书量是否小于最大借阅量,第二步检查书籍当前复本量是否大于 0,第三步插入借阅记录并同时更新书籍复本量和读者借书量。
-- 借书:三个动作要在同一个事务里执行 BEGIN TRANSACTION; -- 1. 检查并插入借阅记录 INSERT INTO tbBorrow (Jyid, Rid, Bid, Jsdate, Hsdate) VALUES ('JY20240001', 'R001', 'B001', GETDATE(), NULL); -- 2. 书籍复本量减 1 UPDATE tbBook SET Zt = Zt - 1 WHERE Bid = 'B001'; -- 3. 读者当前借书量加 1 UPDATE tbReader SET Yjsl = Yjsl + 1 WHERE Rid = 'R001'; COMMIT;这里要注意,事务的顺序是先插入借阅记录再更新书籍和读者数据,因为如果先更新了复本量再插入借阅记录,万一插入失败回滚,复本量会保持一致。另一个常见错误是忘记做检查:插入前先执行SELECT Yjsl FROM tbReader WHERE Rid = 'R001'判断是否超过 Maxjsl,以及SELECT Zt FROM tbBook WHERE Bid = 'B001'判断复本量是否大于 0。这两个检查如果漏了,就会出现超借和负库存的问题。
归还时执行反向操作,同时更新还书日期:
-- 还书:同一事务内更新三张表 BEGIN TRANSACTION; -- 1. 更新借阅记录的还书日期 UPDATE tbBorrow SET Hsdate = GETDATE() WHERE Jyid = 'JY20240001'; -- 2. 书籍复本量加 1 UPDATE tbBook SET Zt = Zt + 1 WHERE Bid = 'B001'; -- 3. 读者当前借书量减 1 UPDATE tbReader SET Yjsl = Yjsl - 1 WHERE Rid = 'R001'; COMMIT;如果你要做超期罚金计算,可以在第 1 步更新 Hsdate 前先查询 Jsdate 和 tbType 中对应的 Jt,用DATEDIFF(DAY, Jsdate, GETDATE()) - Jt计算逾期天数,然后乘以 Fj 得到罚金。文档里 tbType 表的 Jt 和 Fj 字段就是为这个场景准备的。
5.4 常见问题:字段类型与业务逻辑的矛盾
这份文档里最典型的字段类型问题是 tbBook.Zt 用了 nvarchar(50),这几乎可以肯定是复制粘贴产生的错误。我判断的依据是数据字典里对 Zt 的取值含义写的是"标识书籍的当前复本量",而复本量一定是数字,用 nvarchar 会导致排序和计算都出错。你在照着文档建表时,直接改成 Int 即可,不需要犹豫。
另一个常见问题是借阅天数 Jt 的默认值。文档里 tbType 表的 Jt 是 Int 类型,但没给默认值。实际业务中不同书籍类型的借阅天数不同,比如小说类 30 天、教材类 15 天。建议在插入类型数据时为 Jt 指定具体值,不要依赖默认值。还有一个隐蔽的坑是 fj 罚金字段用了 money 类型,SQL Server 的 money 类型在计算时容易出现精度问题,我的习惯是改用 DECIMAL(10,2),这样在计算逾期罚金时不容易出现四舍五入的错误。
最后要注意的是,文档里 P2.6.2 处理读者信息的描述是"将读者的当前借阅量减 1",这在借书的场景下明显是错的,借书应该加 1。这个错误我建议你在写文档说明时修正过来,否则答辩时老师问到这一句,你很难解释清楚。这个坑再次说明了一个事实:任何设计文档都需要在落地时用代码逻辑去反查,不能盲信。
6. 验证 ER 图与数据字典一致性的具体技巧
6.1 用图反查文档:三张图之间的对应关系
拿到这份文档后,我建议你做一次"图查文档"的反向验证:先只看 ER 图,列出所有实体和字段,然后打开数据字典逐条比对,再打开数据流程图检查每个数据流编号是否都能在数据字典里找到。具体分三步走。第一步,从 ER 图提取实体清单,包括实体名、每个实体的属性列表。第二步,拿着清单去对数据字典里的数据结构部分,逐条检查字段名和类型。第三步,对数据流编号,把 F1 到 F14 的数据流定义和数据流程图里的每个处理模块一一对应。
6.2 一个可以复用的检查清单
我在核对这份文档时用了一个检查清单,你也可以直接套用。检查实体是否全部有对应数据表,检查每个表的字段类型是否和业务语义一致,检查外键关系是否在数据字典中有明确字段体现,检查借书、还书流程涉及的表是否和 P2.6 的子处理一致,检查数据流编号是否连续、命名是否一致。
6.3 从文档到数据库映射的实操习惯
这部分分享一个我自己的实操习惯。我从文档落地数据库时,会先把数据字典整理成一份映射表,表头是"实体名、字段名、字段类型、字段含义、对应表名、对应模块"。把这份文档的五大实体全部填进去之后,再开始建表。这样做的直接好处是,建表过程中每加一个字段都能回头查到这个字段来自哪个实体、服务于哪个模块,不会出现"表建完了代码写到一半发现少了字段"的情况。
从那以后我每次拿到设计文档,都会强制走一遍"图查文档"的反向验证流程,先画图、再对字段、再对数据流,最后才动手建表。这个过程看起来多花了一个小时,实际省掉的是后面改表和改接口的几天时间。希望这份图书馆管理系统设计文档的拆解对你有帮助,把它下载下来照着画一遍图、建一遍表,你会比只看不练多收获一倍的理解。
本文还有配套的精品资源,点击获取