> 技术文档 > 数据库课程设计:书店管理系统_数据库课设网上书店系统

数据库课程设计:书店管理系统_数据库课设网上书店系统


1、系统分析

1.1项目背景

        随着全民阅读意识的提升和知识经济的快速发展,图书零售行业持续增长,传统书店和线上书店均面临激烈的市场竞争,优化库存管理、提升客户体验、降低运营成本成为书店经营者的核心需求。然而,当前许多中小型书店仍依赖手工管理,导致效率低下、数据错误频发;库存管理困难,难以平衡畅销书与滞销书;客户体验不足,缺乏精准的会员管理和个性化推荐;线上线下数据割裂,影响运营效率。为此,开发一套书店管理系统势在必行,通过自动化管理实现图书入库、销售等流程的数字化,利用智能库存监控提供预警和补货提醒,并支持全渠道协同以提升运营效率。技术层面可采用采用使用 Python 语言开发,结合 MySQL 实现对书店中图书、库存和用户信息的统一管理。系统支持普通用户和管理员两类角色,界面采用菜单式命令行操作,简洁直观。该系统的实施将推动传统书店数字化转型,助力文化传播,同时提升读者购书体验,实现书店的降本增效和个性化服务。

1.2可行性分析

1.2.1技术可行性

       本系统采用Python语言结合MySQL数据库的技术方案,具有显著的技术优势和实施可行性。Python凭借其丰富的库支持(如Pandas用于数据处理、SQLAlchemy作为ORM工具),不仅开发效率高且学习曲线平缓,在数据处理和中小型系统开发领域已有广泛验证,能够充分满足系统开发需求。MySQL作为开源关系型数据库,提供ACID事务支持和成熟的索引优化机制,可稳定支持百万级图书和用户数据的管理。系统初期采用命令行界面,其开发成本比GUI界面降低50%以上,完全能够满足后台管理需求,同时为后期扩展Web界面保留了技术灵活性。这一技术组合在保证系统功能完整性的同时,兼具开发效率、运行稳定性和成本优势,为系统的成功实施提供了可靠的技术保障。

1.2.2经济可行性

       该书店管理系统采用Mysql免费版本作为数据库,搭配常规Python运行环境,对硬件配置要求较低,普通PC即可流畅运行,整体基础软硬件投入和维护成本较低。项目实施后预计将带来显著效益:直接效益方面可降低库存差错率80%,采购决策时间从3天缩短至2小时,库存周转率提升30%;间接效益方面预计客户留存率提升15-20%,并积累有价值的销售数据用于优化进货策略。投资回报周期方面,中型书店约需6-8个月收回成本,小型书店约需12-15个月,具有较高的经济可行性和投资价值。

1.2.3操作可行性

        本系统针对不同用户角色进行了针对性设计,确保良好的用户适应性。对于管理员用户,采用命令行界面设计,配合详细操作手册和快捷键列表,使书店IT人员能够快速掌握系统操作。面向店员用户,系统将高频操作封装为简单命令(如\"销售 B001 2\"格式),并在关键操作环节设置确认提示,有效防止误操作。在培训方面,系统基础操作仅需0.5天培训即可上岗使用,而包含模拟演练的高级功能专项培训也仅需2天时间,大幅降低了人员培训成本和使用门槛,确保系统能够快速投入实际运营。

1.3需求分析 

        该书店管理系统是一个基于角色权限设计的数据库应用系统,整体业务流程围绕图书销售和库存管理两大核心功能展开。系统采用MySQL数据库存储数据,通过Python的pymysql模块实现数据库连接与操作。用户首先需要通过用户名和密码进行登录验证,系统根据用户角色(管理员或普通用户)展示不同的功能菜单。对于普通用户,系统提供完整的图书购买流程:用户可以浏览全部图书列表或按类型筛选图书,将选中的图书加入购物车并指定购买数量,购物车会实时计算商品小计和总金额。用户可以在购物车中查看当前选购情况,确认无误后进行结算,系统会自动生成订单记录和订单明细,同时清空购物车内容。订单处理过程中,系统会计算每本图书的小计金额和订单总金额,并记录下单时间。历史订单查询功能进一步完善了用户体验,用户可以随时查看过往订单的详细信息,包括下单时间、订单总额和每本书的购买数量及小计金额,系统会按照时间倒序排列订单,最新订单显示在最前面,当用户购买图书后不满意,用户可以申请退货。用户还可对以购买的图书进行评价并查看。当用户的个人信息发生变化时,如电话和地址,用户可以自行修改。

        管理员拥有更高级的系统管理权限,主要包括库存管理,图书管理和用户管理三大模块。在库存管理方面,管理员可以查看当前所有图书的库存情况,对库存数量进行调整(入库或出库),系统会自动记录每次库存变动的操作类型、数量和操作时间。当库存低于预设阈值时,系统会提示低库存预警。在图书管理方面,管理员支持新书上架及通过销售统计视图分析销量、销售额等数据,管理员可以修改图书信息,可以对用户的评价进行管理,从而展现更好的销售氛围。在订单与退货管理模块,通过退货数据深度分析哪本书用户购买后最不满意,哪个用户退货次数最多等,还能监控所有用户的购物车与订单情况,当用户提出退货申请时,管理员进行批准或拒绝。在用户管理方面,管理员可以添加新用户、删除用户账号或重置用户密码,同时可以查看所有用户列表及详细信息。整个系统的业务流程设计紧密结合实际书店运营场景,通过数据库事务确保数据一致性,各功能模块之间通过用户编号和图书编号等关键字段建立关联,实现了从用户登录、图书选购、订单生成到库存管理的完整闭环。

1.3.1功能需求

用户购书模块

        图书展示:列表显示图书编号、名称、作者、类型、库存数量、价格,支持按类型筛选(如文学艺术、儿童读物等)购物车功能:添加商品到购物车,显示订单总额,支持重置购物车,结算订单,查询个人历史订单,申请退货

控制台操作示例:
        1. 浏览图书列表
        2. 按类型筛选图书
        3. 添加图书到购物车
        4. 查看购物车
        5. 清空购物车
        6. 结算订单                                                                                                                                
        7. 查询个人历史订单
        8. 申请退货 

管理员模块

库存管理模块 库存监控:实时查看库存总量和单本图书库存,设置库存预警阈值,自动提示低库存图书,查看库存变动记录(如进货、销售、退货等)。

控制台操作示例:
        1. 查看所有库存
        2. 增加/减少库存
        3. 查看库存预警图书
        4. 查看库存变动记录

用户信息管理模块 存储用户信息(编号、姓名、电话、地址、密码),支持加密处理,自动生成用户编号,管理员可新增、编辑、删除用户信息,密码可重置,支持查看当前用户总数。

控制台操作示例:
        1. 添加新用户
        2. 编辑用户信息
        3. 删除用户
        4. 重置密码
        5. 查看用户列表与总数

图书管理模块 添加新书,查看图书销售排名包括销售量排名和销售额排名,查看用户购物车即用户已加入购物车但还未购买的书,查看所有图书销售订单,查看并处理用户退货申请,查看退货数据深度分析

控制台操作示例:
        1. 添加新书
        2. 查看销售排名
        3. 查看用户购物车
        4. 查看历史订单 
        5. 查看用户退货申请
        6. 处理退货申请
        7. 查看退货分析表

1.3.2业务流程

顶层结构

说明:1.系统登录 → 身份验证 → 分支为 普通用户 和 管理员 2.普通用户进入 图书销售模块 3.管理员进入 管理员控制台

管理员业务流程

1. 登录验证

  • 输入:电话、密码
  • 验证:检查管理员表中是否存在匹配
  • 成功:进入管理员菜单
  • 失败:提示错误并返回登录界面

2. 库存管理

2.1 查看全部库存

  • 操作:查询库存表和图书表,显示图书名称、作者、当前库存、库存阈值及状态(充足/需补货)

2.2 修改库存

  • 输入:图书名称、变动数量(正数为入库,负数为出库)
  • 逻辑:更新库存表的当前库存字段。在库存变动记录表中添加一条记录(操作类型为\"进货\"或\"销售\")。
  • 约束:出库时需检查库存是否充足(避免负数库存)。

2.3 低库存预警

  • 操作:查询库存量低于阈值的图书,并标记为\"需补货\"

2.4 查看库存变动记录

  • 操作:按时间降序显示库存变动记录表中的操作记录。

3. 图书管理

3.1 添加新书

  • 输入:图书编号、名称、作者、类型、单价、出版社、ISBN、初始库存、库存阈值。
  • 逻辑:调用存储过程添加新图书,同时向图书表和库存表插入数据。若图书已存在,则提示错误。

3.2 销售统计

  • 操作:查询图书销售统计视图,展示销量、销售额、购买用户数等数据。

3.3 查看用户购物车

  • 操作:查看用户购物车即用户已加入购物车但还未购买的书

3.4查看历史订单

4. 用户管理

4.1 添加用户

  • 输入:用户编号、姓名、电话、地址、密码、角色(用户/管理员)。
  • 约束:电话需唯一,否则提示错误。

4.2 编辑用户信息

  • 输入:原电话、新电话、新姓名、新地址。
  • 逻辑:根据原电话更新用户信息。

4.3 删除用户

  • 输入:用户电话。
  • 约束:若用户有未完成的订单或购物车,需先清理关联数据(代码中未实现此约束)。

4.4 重置密码

  • 输入:用户电话、新密码。

4.5 用户列表

  • 操作:显示所有用户的编号、姓名、电话、地址和角色。

普通用户业务流程图

1.图书浏览

  • 图书列表:直接展示图书库存表的联合查询结果。
  • 模糊查找:调用存储过程查询图书模糊,支持书名/作者/出版社/ISBN的多字段搜索。

2.购物车管理

  • 加入购物车:检查库存是否充足(若不足立即提示),使用ON DUPLICATE KEY UPDATE实现数量累加。
  • 清空购物车:直接删除对应用户的所有记录。

3.订单处理

  • 结算订单:从购物车获取数据生成订单明细。自动清空购物车(事务保证一致性)。
  • 历史订单:按下单时间分组显示,并计算每单总额。

4.异常处理

  • 所有数据库操作均通过try-except实现事务回滚(如结算失败时恢复购物车数据)。

1.3.3数据流图

0层数据流图

1层数据流图

用户功能模块

管理员功能模块

典型数据流示例

用户购买图书

管理员修改库存

2.系统设计

2.1系统功能设计

        基于以上内容书店管理系统需要实现图书销售、库存管理、用户管理和交易分析等核心功能,采用直观的控制台界面设计,满足中小型书店的日常运营需求。

2.2数据库设计

2.2.1数据库需求分析

本系统需存储图书、库存、销售记录、用户信息、购物车等核心数据。所有表名及字段名使用中文,便于中文场景系统交付与展示。数据表结构须满足以下需求:字段命名语义清晰;主外键约束完整;密码字段采用加密;数据类型匹配业务精度(如价格用 DECIMAL)

2.2.2数据库概念模型设计

实体名 主要属性(字段) 图书 图书编号、图书名称(主键)、作者、类型、出版社、单价、ISBN、创建时间、更新时间 用户 用户编号、姓名、电话(主键)、地址、密码、角色、创建时间、更新时间 库存 图书名称(主键,外键,关联图书表图书名称 )、ISBN、当前库存、库存阈值 购物车 购物车编号(主键)、用户电话(外键,关联用户表电话 )、用户名称、图书名称(外键,关联图书表图书名称 )、图书数量、创建时间 订单明细 订单明细编号(主键)、用户电话(外键,关联用户表电话 )、用户名称、图书名称(外键,关联图书表图书名称 )、购买数量、单价、总金额、下单时间 库存变动记录 库存变动编号(主键)、图书名称(外键,关联图书表图书名称 )、操作类型、数量、操作时间

实体之间的关系

用户与购物车:一对多(一个用户可拥有多个购物车记录)

用户与订单:一对多(一个用户可创建多个订单明细)

图书与库存:一对一(每本图书对应唯一库存记录)

图书与订单:多对多(通过订单明细表关联,一本图书可出现在多个订单中)

购物车与订单:一对多(购物车结算后生成多条订单明细)

管理员与用户:一对多(一个管理员可添加多个用户)

2.2.3数据库逻辑结构设计

在概念结构基础上,转换为如下7个关系模式:

图书(图书编号、图书名称、作者、类型、出版社、单价、ISBN、创建时间、更新时间)

用户(用户编号、姓名、电话、地址、密码、创建时间、更新时间)

管理员(管理员编号、姓名、电话、地址、密码、创建时间、更新时间)

库存(图书名称、ISBN、当前库存、库存阈值)

购物车(购物车编号、用户电话、用户名称、图书名称、图书数量、创建时间)

订单明细(订单明细编号、用户电话、用户名称、图书名称、购买数量、单价、总金额、下单时间)

库存变动记录(库存变动编号、图书名称、操作类型、数量、操作时间)

  • 用户:涵盖用户基本信息,如编号、姓名、电话(主键)等。电话设为主键,方便用户身份识别与关联其他表操作,同时记录创建和更新时间,利于追踪信息变更 。
  • 图书:以图书名称为主键,结合图书编号、作者、类型等属性,全面描述图书特征。ISBN 设为唯一键,保证图书国际标准书号的唯一性 。
  • 库存:图书名称作为主键和外键关联图书表,记录当前库存和库存阈值,能实时反映图书库存状态,为库存管理提供基础数据 。
  • 库存变动记录:库存变动编号为主键,记录图书库存变动情况,包括操作类型(进货 / 销售 / 退货 )、数量和时间,便于追溯库存变化历史 。
  • 购物车:购物车编号为主键,通过用户电话和图书名称外键关联用户和图书表,记录用户购物车信息,用户电话和图书名称联合唯一键避免重复记录 。
  • 订单明细:订单明细编号为主键,关联用户电话和图书名称外键,记录订单具体信息,如购买数量、单价、总金额等,是订单业务核心记录 。
范式 说明 第一范式 所有字段为原子值,无多重字段;满足 1NF 第二范式

所有非主属性完全依赖主键(如购物车的数量依赖 用户电话+图书名称);满足 2NF

第三范式 无传递依赖(例如 图书 → 库存;库存不包含除主键外的派生字段);满足 3NF

2.2.4数据库物理结构设计

图书表

字段名 类型 主 / 外键 约束条件 描述 图书编号 VARCHAR(20) NOT NULL 唯一编号 图书名称 VARCHAR(100) 主键 NOT NULL 图书名称 作者 VARCHAR(50) NOT NULL 作者名称 类型 VARCHAR(30) NOT NULL 分类 单价 DECIMAL(10,2) NOT NULL 售价 出版社 VARCHAR(100) NOT NULL 出版机构 ISBN VARCHAR(20) UNIQUE NOT NULL 国际标准书号 创建时间 TIMESTAMP DEFAULT CURRENT_TIMESTAMP 记录图书信息创建时间

用户表

字段名 类型 主 / 外键 约束条件 描述 用户编号 INT AUTO_INCREMENT 编号 姓名 VARCHAR(50) NOT NULL 用户姓名 电话 VARCHAR(20) 主键 NOT NULL UNIQUE 联系电话(唯一) 地址 VARCHAR(255) 收货地址 密码 VARCHAR(255) NOT NULL 加密存储 创建时间 TIMESTAMP DEFAULT CURRENT_TIMESTAMP 账户创建时间 更新时间 TIMESTAMP ON UPDATE CURRENT_TIMESTAMP 信息更新时间

管理员表

字段名 类型 主 / 外键 约束条件 描述 管理员编号 INT AUTO_INCREMENT 编号 姓名 VARCHAR(50) NOT NULL 管理员姓名 电话 VARCHAR(20) 主键 NOT NULL UNIQUE 联系电话(唯一) 地址 VARCHAR(255) 收货地址 密码 VARCHAR(255) NOT NULL 加密存储 创建时间 TIMESTAMP DEFAULT CURRENT_TIMESTAMP 账户创建时间 更新时间 TIMESTAMP ON UPDATE CURRENT_TIMESTAMP 信息更新时间

库存表

字段名 类型 主 / 外键 约束条件 描述 图书名称 VARCHAR(100) 主键 NOT NULL 关联图书表的图书名称 ISBN VARCHAR(20) 唯一键 UNIQUE NOT NULL 国际标准书号 当前库存 INT NOT NULL DEFAULT 0 当前库存数量 库存阈值 INT NOT NULL DEFAULT 10 库存预警阈值

库存变动记录表

字段名 类型 主 / 外键 约束条件 描述 库存变动编号 INT 主键 AUTO_INCREMENT 变动记录的唯一标识 图书名称 VARCHAR(100) 外键 NOT NULL 关联图书表的图书名称 操作类型 VARCHAR(10) NOT NULL 操作类型(进货 / 销售 / 退货) 数量 INT NOT NULL 库存变动数量(正数为增加) 操作时间 DATETIME DEFAULT CURRENT_TIMESTAMP 记录操作的时间

购物车表

字段名 类型 主 / 外键 约束条件 描述 购物车编号 INT 主键 AUTO_INCREMENT 购物车记录的唯一标识 用户电话 VARCHAR(20) 外键 NOT NULL 关联用户表的用户电话 用户名称 VARCHAR(50) NOT NULL 用户的姓名 图书名称 VARCHAR(100) 外键 NOT NULL 关联图书表的图书名称 图书数量 INT NOT NULL DEFAULT 1 购买数量(默认值为 1) 创建时间 TIMESTAMP DEFAULT CURRENT_TIMESTAMP 加入购物车的时间

订单明细表

字段名 类型 主 / 外键 约束条件 描述 订单明细编号 INT 主键 AUTO_INCREMENT 订单明细的唯一标识 用户电话 VARCHAR(20) 外键 NOT NULL 关联用户表的用户电话 用户名称 VARCHAR(50) NOT NULL 下单用户的姓名 图书名称 VARCHAR(100) 外键 NOT NULL 关联图书表的图书名称 购买数量 INT NOT NULL 购买的图书数量 单价 DECIMAL(10,2) NOT NULL 下单时的图书单价 总金额 DECIMAL(10,2) NOT NULL 购买金额(单价 × 数量) 下单时间 TIMESTAMP DEFAULT CURRENT_TIMESTAMP 订单创建的时间

索引设计

索引名 表名 字段 类型 说明 idx_用户电话 用户 电话 UNIQUE 唯一索引,确保用户电话的唯一性,加速用户查询和关联操作 idx_图书名称 图书 图书名称 UNIQUE 唯一索引,确保图书名称的唯一性,常用于主键关联和快速查询 idx_ISBN 图书 ISBN UNIQUE 唯一索引,确保 ISBN 编号的唯一性,便于通过国际标准书号检索图书 idx_图书名称_库存 库存 图书名称 普通索引 用于加速基于图书名称的库存查询和关联操作 idx_当前库存 库存 当前库存 普通索引 用于快速查询特定库存数量的图书,支持库存预警和库存管理查询 idx_图书名称_变动 库存变动记录 图书名称 普通索引 用于加速基于图书名称的库存变动查询,便于追踪特定图书的库存变化 idx_操作时间 库存变动记录 操作时间 普通索引 用于按时间顺序查询库存变动记录,支持时间范围检索和历史记录查询 订单明细 用户电话 普通索引 用于加速基于用户电话的订单查询,支持用户订单历史检索 idx_图书名称_订单 订单明细 图书名称 普通索引 用于加速基于图书名称的订单查询,支持图书销售统计和分析 idx_下单时间 订单明细 下单时间 普通索引 用于按时间顺序查询订单记录,支持订单时间范围检索和统计 INDEX (订单明细编号) 订单明细 订单明细编号 普通索引 用于加速订单明细编号的查询,提高主键关联效率 idx_用户电话_购物车 购物车 用户电话 普通索引 用于加速基于用户电话的购物车查询,支持用户购物车管理 idx_图书名称_购物车 购物车 图书名称 普通索引 用于加速基于图书名称的购物车查询,支持图书相关的购物车操作 idx_管理员电话 管理员 电话 UNIQUE 唯一索引,确保管理员电话的唯一性,加速管理员查询和关联操作

以上建立表格和索引的代码如下

-- 创建书店管理系统数据库CREATE DATABASE 书店管理系统 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;CREATE TABLE 用户 ( 用户编号 VARCHAR(20) NOT NULL COMMENT \'用户编号\', 姓名 VARCHAR(50) NOT NULL COMMENT \'姓名\', 电话 VARCHAR(20) PRIMARY KEY COMMENT \'电话(主键)\', 地址 VARCHAR(255) COMMENT \'地址\', 密码 VARCHAR(255) NOT NULL COMMENT \'密码(建议存储加密后的值)\', 角色 VARCHAR(20) NOT NULL COMMENT \'角色\', 创建时间 TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT \'创建时间\', 更新时间 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT \'更新时间\') ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=\'用户信息表\';-- 用户INSERT INTO 用户 VALUES (1, \'张三\', \'13811112222\', \'北京市海淀区\', \'pass123\', \'用户\', \'2023-01-01 10:00:00\', \'2023-01-01 10:00:00\');INSERT INTO 用户 VALUES (2, \'李四\', \'13933334444\', \'上海市浦东新区\', \'abc456\', \'管理员\', \'2023-01-02 11:30:00\', \'2023-01-02 11:30:00\');INSERT INTO 用户 VALUES (3, \'王五\', \'13755556666\', \'广州市天河区\', \'xyz789\', \'用户\', \'2023-01-03 09:15:00\', \'2023-01-03 09:15:00\');INSERT INTO 用户 VALUES (4, \'赵六\', \'13699990000\', \'成都市武侯区\', \'pwd888\', \'用户\', \'2023-01-04 14:45:00\', \'2023-01-04 14:45:00\');CREATE TABLE 图书 ( 图书编号 VARCHAR(20) NOT NULL COMMENT \'图书编号\', 图书名称 VARCHAR(100) PRIMARY KEY COMMENT \'图书名称(主键)\', 作者 VARCHAR(50) NOT NULL COMMENT \'作者\', 类型 VARCHAR(30) NOT NULL COMMENT \'图书类型\', 单价 DECIMAL(10,2) NOT NULL COMMENT \'单价\', 出版社 VARCHAR(100) NOT NULL COMMENT \'出版社\', ISBN VARCHAR(20) UNIQUE NOT NULL COMMENT \'国际标准书号\', 创建时间 TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT \'创建时间\', 更新时间 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT \'更新时间\') ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=\'图书信息表\';INSERT INTO 图书 VALUES (\'B001\', \'活着\', \'余华\', \'文学艺术\', 38.00, \'作家出版社\', \'9787506365437\', \'2023-01-10 09:00:00\', \'2023-01-10 09:00:00\');INSERT INTO 图书 VALUES (\'B002\', \'解忧杂货店\', \'东野圭吾\', \'推理小说\', 45.00, \'南海出版公司\', \'9787544258979\', \'2023-01-11 10:30:00\', \'2023-01-11 10:30:00\');INSERT INTO 图书 VALUES (\'B003\', \'窗边的小豆豆\', \'黑柳彻子\', \'儿童读物\', 30.00, \'新星出版社\', \'9787513310545\', \'2023-01-12 14:15:00\', \'2023-01-12 14:15:00\');INSERT INTO 图书 VALUES (\'B004\', \'红楼梦\', \'曹雪芹\', \'古典名著\', 59.90, \'人民文学出版社\', \'9787020002207\', \'2023-01-13 11:20:00\', \'2023-01-13 11:20:00\');INSERT INTO 图书 VALUES (\'B005\', \'三体\', \'刘慈欣\', \'科幻小说\', 58.00, \'重庆出版社\', \'9787536692930\', \'2023-01-14 16:45:00\', \'2023-01-14 16:45:00\');CREATE TABLE 库存 ( 图书名称 VARCHAR(100) PRIMARY KEY COMMENT \'图书名称(主键)\', ISBN VARCHAR(20) UNIQUE NOT NULL COMMENT \'国际标准书号\', 当前库存 INT NOT NULL DEFAULT 0 COMMENT \'当前库存数量\', 库存阈值 INT NOT NULL DEFAULT 10 COMMENT \'库存预警阈值\', FOREIGN KEY (图书名称) REFERENCES 图书(图书名称) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=\'图书库存信息表\';INSERT INTO 库存 VALUES (\'活着\', \'9787506365437\', 25, 5);INSERT INTO 库存 VALUES (\'解忧杂货店\', \'9787544258979\', 18, 8);INSERT INTO 库存 VALUES (\'窗边的小豆豆\', \'9787513310545\', 12, 10);INSERT INTO 库存 VALUES (\'红楼梦\', \'9787020002207\', 30, 15);INSERT INTO 库存 VALUES (\'三体\', \'9787536692930\', 8, 10);CREATE TABLE 库存变动记录 ( 库存变动编号 INT PRIMARY KEY AUTO_INCREMENT COMMENT \'变动记录唯一标识\', 图书名称 VARCHAR(100) NOT NULL COMMENT \'关联图书名称\',操作类型 VARCHAR(10) NOT NULL COMMENT \'操作类型:进货/销售/退货\', 数量 INT NOT NULL COMMENT \'变动数量(正数表示增加,负数表示减少)\', 操作时间 DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT \'记录操作时间\', FOREIGN KEY (图书名称) REFERENCES 图书(图书名称) ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=\'库存变动明细记录表\';INSERT INTO 库存变动记录 VALUES (\'001\',\'活着\', \'进货\', 25, \'2023-03-01 09:00:00\');INSERT INTO 库存变动记录 VALUES (\'002\',\'解忧杂货店\', \'进货\', 40, \'2023-03-01 10:30:00\');INSERT INTO 库存变动记录 VALUES (\'003\',\'窗边的小豆豆\', \'进货\', 35, \'2023-03-02 11:15:00\');INSERT INTO 库存变动记录 VALUES (\'004\',\'红楼梦\', \'进货\', 30, \'2023-03-02 14:45:00\');INSERT INTO 库存变动记录 VALUES (\'005\',\'三体\', \'进货\', 34, \'2023-03-03 16:20:00\');CREATE TABLE 购物车 ( 购物车编号 INT PRIMARY KEY AUTO_INCREMENT COMMENT \'购物车记录ID\', 用户电话 VARCHAR(20) NOT NULL COMMENT \'关联用户电话\', 用户名称 VARCHAR(50) NOT NULL COMMENT \'用户姓名\', 图书名称 VARCHAR(100) NOT NULL COMMENT \'关联图书名称\', 图书数量 INT NOT NULL DEFAULT 1 COMMENT \'购买数量\', 创建时间 TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT \'加入购物车时间\', FOREIGN KEY (用户电话) REFERENCES 用户(电话) ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (图书名称) REFERENCES 图书(图书名称) ON DELETE CASCADE ON UPDATE CASCADE, UNIQUE KEY (用户电话, 图书名称) COMMENT \'同一用户同一图书只保留一条记录\') ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=\'用户购物车信息表\';INSERT INTO 购物车 VALUES (1, \'13811112222\', \'张三\', \'活着\', 2, \'2023-03-05 10:15:00\');INSERT INTO 购物车 VALUES (2, \'13811112222\', \'张三\', \'三体\', 1, \'2023-03-05 11:30:00\');INSERT INTO 购物车 VALUES (3, \'13933334444\', \'李四\', \'解忧杂货店\', 1, \'2023-03-06 09:45:00\');INSERT INTO 购物车 VALUES (4, \'13755556666\', \'王五\', \'红楼梦\', 3, \'2023-03-06 14:20:00\');CREATE TABLE 订单明细 ( 订单明细编号 INT PRIMARY KEY AUTO_INCREMENT COMMENT \'订单明细ID\', 用户电话 VARCHAR(20) NOT NULL COMMENT \'关联用户电话\', 用户名称 VARCHAR(50) NOT NULL COMMENT \'用户姓名\', 图书名称 VARCHAR(100) NOT NULL COMMENT \'关联图书名称\', 购买数量 INT NOT NULL COMMENT \'购买数量\', 单价 DECIMAL(10,2) NOT NULL COMMENT \'下单时图书单价\', 总金额 DECIMAL(10,2) NOT NULL COMMENT \'小计金额(单价×数量)\', 下单时间 TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT \'订单创建时间\', FOREIGN KEY (用户电话) REFERENCES 用户(电话) ON UPDATE CASCADE, FOREIGN KEY (图书名称) REFERENCES 图书(图书名称) ON UPDATE CASCADE, INDEX (订单明细编号) COMMENT \'订单明细编号索引\') ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=\'订单明细信息表\';INSERT INTO 订单明细 VALUES (\'001\', \'13811112222\', \'张三\', \'活着\', 2, 38.00, 76.00, \'2023-03-15 10:30:00\');INSERT INTO 订单明细 VALUES (\'002\', \'13811112222\', \'张三\', \'三体\', 1, 58.00, 58.00, \'2023-03-15 10:30:00\');INSERT INTO 订单明细 VALUES (\'003\', \'13933334444\', \'李四\', \'解忧杂货店\', 1, 45.00, 45.00, \'2023-03-16 14:15:00\');-- 创建索引-- 用户表CREATE UNIQUE INDEX idx_用户电话 ON 用户(电话);-- 图书表CREATE UNIQUE INDEX idx_图书名称 ON 图书(图书名称);CREATE UNIQUE INDEX idx_ISBN ON 图书(ISBN);-- 库存表CREATE INDEX idx_图书名称_库存 ON 库存(图书名称);CREATE INDEX idx_当前库存 ON 库存(当前库存);-- 库存变动记录CREATE INDEX idx_图书名称_变动 ON 库存变动记录(图书名称);CREATE INDEX idx_操作时间 ON 库存变动记录(操作时间);-- 订单明细表CREATE INDEX idx_用户电话_订单 ON 订单明细(用户电话);CREATE INDEX idx_图书名称_订单 ON 订单明细(图书名称);CREATE INDEX idx_下单时间 ON 订单明细(下单时间);-- 购物车表CREATE INDEX idx_用户电话_购物车 ON 购物车(用户电话);CREATE INDEX idx_图书名称_购物车 ON 购物车(图书名称);

2.2.5数据库视图设计

库存预警视图

视图名称 用途 关联表 关键字段 筛选条件 输出字段 库存预警视图 用于监控图书库存状态,判断库存是否低于预警阈值,提示是否需要补货 库存表、图书表 图书名称(关联字段) 无特殊筛选 图书名称、作者、类型、出版社、当前库存、库存阈值、库存差额、库存状态

        该库存预警视图提供了全面的库存监控功能,通过关联库存表和图书表,直观展示了每本图书的库存状态。视图计算了当前库存与阈值的差额(库存差额),并根据差额大小将图书分为三类状态:\"需补货\"(当前库存低于阈值)、\"临界值\"(等于阈值)和\"库存充足\"(高于阈值)。结果按库存差额升序排列,使需要紧急补货的图书能够优先显示,便于管理人员快速识别库存风险。该视图不仅包含库存数据(当前库存、阈值),还整合了图书的基本信息(作者、类型、出版社),为补货决策提供了完整的参考依据。

图书销售统计视图

视图名称 用途 关联表 关键字段 筛选条件 输出字段 图书销售统计视图 统计每本图书的销售数据,包括销售总量、总额、购买用户数及日均销售量 图书表、订单明细表 图书名称(关联字段) 无特殊筛选 图书编号、图书名称、作者、类型、出版社、单价、销售总量、销售总额、购买用户数、日均销售量

        该图书销售统计视图通过关联图书表和订单明细表,全面分析了每本图书的销售表现。视图不仅展示基础图书信息(编号、名称、作者、类型、出版社、单价),还计算了关键销售指标:销售总量反映图书受欢迎程度,销售总额衡量创收能力,购买用户数体现客户覆盖广度。特别设计的日均销售量指标(销售总量/图书上架天数)消除了时间因素影响,可客观比较不同时期上架图书的销售效率。使用LEFT JOIN确保无销售记录的图书也能显示(销售数据为0),IFNULL函数处理空值,GREATEST函数避免除零错误。结果按销售总额降序排列,便于快速识别最畅销图书,为库存管理、营销策略制定提供数据支持。

视图设计代码如下

-- 库存预警视图CREATE OR REPLACE VIEW 库存预警视图 ASSELECT k.图书名称, b.作者, b.类型, b.出版社, k.当前库存, k.库存阈值, (k.当前库存 - k.库存阈值) AS 库存差额, CASE WHEN k.当前库存 < k.库存阈值 THEN \'需补货\' WHEN k.当前库存 = k.库存阈值 THEN \'临界值\' ELSE \'库存充足\' END AS 库存状态FROM 库存 kJOIN 图书 b ON k.图书名称 = b.图书名称ORDER BY 库存差额 ASC;-- 图书销售统计视图(仅销售数据)CREATE OR REPLACE VIEW 图书销售统计视图 ASSELECT b.图书编号, b.图书名称, -- 修改这里,从 K.图书名称 改为 b.图书名称 b.作者, b.类型, b.出版社, b.单价, IFNULL(SUM(o.购买数量), 0) AS 销售总量, IFNULL(SUM(o.总金额), 0) AS 销售总额, COUNT(DISTINCT o.用户电话) AS 购买用户数, IFNULL(SUM(o.购买数量), 0) / GREATEST(DATEDIFF(CURRENT_DATE, MIN(b.创建时间)), 1) AS 日均销售量FROM 图书 bLEFT JOIN 订单明细 o ON b.图书名称 = o.图书名称GROUP BY b.图书编号, b.图书名称, b.作者, b.类型, b.出版社, b.单价ORDER BY 销售总额 DESC;

2.2.6函数设计

计算订单总金额函数

        这个计算订单总金额函数是一个简洁实用的MySQL存储函数,主要用于根据订单明细编号快速查询并返回对应订单的总金额。函数采用DETERMINISTIC声明,表示相同输入总是返回相同结果,便于查询优化。函数内部通过SELECT...INTO语句从订单明细表中检索指定编号的订单金额,并使用IFNULL函数确保当订单不存在时返回0而非NULL,增强了数据的可靠性。该函数封装了订单金额查询逻辑,可在SQL语句中直接调用(如SELECT 计算订单总金额(1001)),简化了业务代码编写,提高了查询的可读性和复用性。特别适合需要频繁计算订单金额的报表生成或对账场景。

-- 计算订单总金额函数 DELIMITER //CREATE FUNCTION 计算订单总金额(订单明细编号参数 INT) RETURNS DECIMAL(10,2)DETERMINISTICBEGIN DECLARE 结果 DECIMAL(10,2); SELECT 总金额 INTO 结果 FROM 订单明细 WHERE 订单明细编号 = 订单明细编号参数; RETURN IFNULL(结果, 0);END //DELIMITER ;

获取图书当前库存函数

        这个函数创建了一个名为\"查询库存\"的存储函数,它接收一个图书名称参数,通过查询\"库存\"表中对应图书名称的\"当前库存\"字段值,返回该图书的库存数量(如果查询不到则返回0),函数被声明为DETERMINISTIC表示对相同输入总是返回相同结果。

-- 获取图书当前库存函数DELIMITER //CREATE FUNCTION 查询库存(图书名称参数 VARCHAR(100)) RETURNS INTDETERMINISTICBEGIN DECLARE 库存量 INT; SELECT 当前库存 INTO 库存量 FROM 库存 WHERE 图书名称 = 图书名称参数; RETURN IFNULL(库存量, 0);END //DELIMITER ;

2.2.7存储过程设计

图书模糊查询

        这个存储过程名为\"查询图书模糊\",主要用于根据用户输入的关键词对图书信息进行模糊查询,并返回包含库存状态的详细图书信息。存储过程接收一个输入参数\"关键词\",该参数用于在图书名称、作者、出版社和ISBN字段中进行模糊匹配(使用LIKE操作符和通配符%实现)。查询结果包含图书编号、图书名称、作者、类型、单价、出版社、ISBN以及当前库存等基本信息,同时通过CASE语句计算库存状态:当当前库存低于库存阈值时标记为\"需补货\",等于阈值时标记为\"临界值\",否则标记为\"库存充足\"。该过程通过JOIN操作关联\"图书\"和\"库存\"表,确保返回的数据包含库存信息,并按照图书名称排序输出结果。此存储过程的优点在于提供了灵活的模糊搜索功能,用户可以通过书名、作者、出版社或ISBN等多个维度检索图书,同时直观地展示库存状态,便于管理人员进行库存管理和补货决策。

-- 存储过程根图书模糊查询图书DELIMITER //CREATE PROCEDURE 查询图书模糊( IN 关键词 VARCHAR(100))BEGIN SELECT b.图书编号, b.图书名称, b.作者, b.类型, b.单价, b.出版社, b.ISBN, k.当前库存, CASE WHEN k.当前库存 < k.库存阈值 THEN \'需补货\' WHEN k.当前库存 = k.库存阈值 THEN \'临界值\' ELSE \'库存充足\' END AS 库存状态 FROM 图书 b JOIN 库存 k ON b.图书名称 = k.图书名称 WHERE b.图书名称 LIKE CONCAT(\'%\', 关键词, \'%\') OR b.作者 LIKE CONCAT(\'%\', 关键词, \'%\') OR b.出版社 LIKE CONCAT(\'%\', 关键词, \'%\') OR b.ISBN LIKE CONCAT(\'%\', 关键词, \'%\') ORDER BY b.图书名称;END //DELIMITER ;

减少库存即退货

        这个存储过程名为“减少库存”,主要用于在图书销售时安全地扣减库存,并记录库存变动情况。其核心功能是确保库存扣减操作的原子性和数据一致性,防止库存超卖。存储过程接收两个参数:图书名称参数(指定要扣减的图书)和减少数量(要销售的数量)。首先,它查询当前库存值,并进行库存充足性检查。如果库存足够(当前库存 ≥ 减少数量),则执行库存扣减操作(UPDATE),并记录一条库存变动日志(INSERT),标记为“销售”类型,数量为负数表示减少。最后返回成功状态(执行结果=1)和提示消息。如果库存不足,则直接返回失败状态(执行结果=0)和当前库存信息,避免无效操作。该设计具有以下优点:事务安全:检查库存和扣减操作在同一个存储过程中完成,减少竞态条件风险。操作可追溯:通过库存变动记录表记录每次销售,便于后续对账或审计。友好反馈:明确返回执行结果和消息,方便调用方处理成功或失败情况。适用于销售系统调用,确保库存管理的准确性和可靠性。

-- 存储过程减少库存(用于销售)DELIMITER //CREATE PROCEDURE 减少库存( IN 图书名称参数 VARCHAR(100), IN 减少数量 INT)BEGIN DECLARE 当前库存值 INT; -- 检查库存是否足够 SELECT 当前库存 INTO 当前库存值 FROM 库存 WHERE 图书名称 = 图书名称参数; IF 当前库存值 >= 减少数量 THEN -- 减少库存 UPDATE 库存 SET 当前库存 = 当前库存 - 减少数量 WHERE 图书名称 = 图书名称参数; -- 记录库存变动 INSERT INTO 库存变动记录(图书名称, 操作类型, 数量, 操作时间) VALUES (图书名称参数, \'销售\', -减少数量, NOW()); SELECT 1 AS 执行结果, \'库存减少成功\' AS 消息; ELSE SELECT 0 AS 执行结果, CONCAT(\'库存不足,当前库存:\', 当前库存值) AS 消息; END IF;END //DELIMITER ;

添加新书和库存

        这个名为\"添加新图书\"的存储过程实现了图书信息管理和库存管理的完整业务流程,用于在系统中新增图书并初始化其库存信息。该过程接收9个输入参数,包括图书的基本信息(编号、名称、作者等)和库存相关参数(初始库存、库存阈值)。存储过程首先将图书信息插入\"图书\"表,包含完整的图书元数据。随后在\"库存\"表中创建对应的库存记录,其中库存阈值参数使用了IFNULL函数提供默认值10,增强了程序的健壮性。最后,在\"库存变动记录\"表中记录本次进货操作,形成完整的操作日志。该设计的主要特点包括:业务完整性:将图书信息录入、库存初始化和进货记录三个关联操作封装在单一事务中,确保数据一致性;参数灵活性:通过IFNULL处理可选参数,当库存阈值未提供时使用默认值10;可追溯性:自动记录初始进货操作,为后续库存审计提供依据;用户友好:返回明确的操作结果提示。此存储过程特别适合用于图书采购入库场景,简化了前端调用逻辑,同时保证了后端数据的完整性和一致性。默认阈值的设计也体现了良好的用户体验考虑,减少了必填参数数量。整个流程符合图书管理系统的业务规范,是典型的数据录入与初始化相结合的实现方案。

-- 存储过程添加新图书及库存DELIMITER //CREATE PROCEDURE 添加新图书( IN 图书编号_ VARCHAR(20), IN 图书名称_ VARCHAR(100), IN 作者_ VARCHAR(50), IN 类型_ VARCHAR(30), IN 单价_ DECIMAL(10,2), IN 出版社_ VARCHAR(100), IN ISBN_ VARCHAR(20), IN 初始库存 INT, IN 库存阈值_ INT)BEGIN -- 插入图书信息 INSERT INTO 图书( 图书编号, 图书名称, 作者, 类型, 单价, 出版社, ISBN ) VALUES ( 图书编号_, 图书名称_, 作者_, 类型_, 单价_, 出版社_, ISBN_ ); -- 插入库存信息 INSERT INTO 库存( 图书名称, ISBN, 当前库存, 库存阈值 ) VALUES ( 图书名称_, ISBN_, 初始库存, IFNULL(库存阈值_, 10) -- 默认阈值10 ); -- 记录库存变动 INSERT INTO 库存变动记录( 图书名称, 操作类型, 数量, 操作时间 ) VALUES ( 图书名称_, \'进货\', 初始库存, NOW() ); SELECT \'图书添加成功\' AS 结果;END //DELIMITER ;

2.2.8触发器设计

订单明细插入时自动减库存并写日志

DELIMITER //CREATE TRIGGER 订单触发减库存AFTER INSERT ON 订单明细FOR EACH ROWBEGIN -- 减少库存 UPDATE 库存 SET 当前库存 = 当前库存 - NEW.购买数量 WHERE 图书名称 = NEW.图书名称; -- 记录库存变动 INSERT INTO 库存变动记录(图书名称, 操作类型, 数量, 操作时间) VALUES (NEW.图书名称, \'销售\', -NEW.购买数量, NOW());END;//DELIMITER ;-- 测试触发器SELECT 图书名称, 当前库存 FROM 库存 WHERE 图书名称 = \'三体\';INSERT INTO 订单明细(用户电话, 用户名称, 图书名称, 购买数量, 单价, 总金额)VALUES (\'13755556666\', \'王五\', \'三体\', 2, 58.00, 116.00);SELECT 图书名称, 当前库存 FROM 库存 WHERE 图书名称 = \'三体\';SELECT * FROM 库存变动记录 WHERE 图书名称 = \'三体\' ORDER BY 操作时间 DESC;

        这个名为\"订单触发减库存\"的触发器实现了订单处理与库存联动的自动化机制,是典型的业务逻辑与数据一致性保障方案。该触发器定义为在\"订单明细\"表发生INSERT操作后自动执行,确保每笔新订单都能实时扣减库存并留下操作记录。触发器的工作原理是:当新的订单明细记录插入时,立即执行两个关键操作:库存扣减:通过UPDATE语句将对应图书的当前库存减少订单中的购买数量;操作记录:在库存变动记录表中插入一条类型为\"销售\"的负向变动记录

购物车插入时检查是否存在该书记录

-- 触发器购物车插入时检查是否存在该书记录DELIMITER //CREATE TRIGGER 添加购物车合并BEFORE INSERT ON 购物车FOR EACH ROWBEGIN -- 检查是否已存在相同用户和图书的购物车记录 IF EXISTS ( SELECT * FROM 购物车 WHERE 用户电话 = NEW.用户电话 AND 图书名称 = NEW.图书名称 ) THEN -- 如果存在,则更新数量而不是插入新记录 UPDATE 购物车 SET 图书数量 = 图书数量 + NEW.图书数量 WHERE 用户电话 = NEW.用户电话 AND 图书名称 = NEW.图书名称; -- 取消当前插入操作 SIGNAL SQLSTATE \'45000\' SET MESSAGE_TEXT = \'已合并购物车项,禁止重复插入\'; END IF;END;//DELIMITER ;

        这个名为\"添加购物车合并\"的触发器实现了一个智能化的购物车商品合并机制,是电商系统中提升用户体验和保证数据一致性的关键设计。该触发器采用BEFORE INSERT时机,在数据实际插入前进行业务逻辑处理,展现了数据库层面的业务规则封装能力。触发器核心逻辑包含三个关键部分:存在性检查:通过查询判断当前用户是否已将该图书加入购物车;数量合并:对已存在的商品自动累加新数量,避免重复记录;插入阻断:通过SIGNAL主动终止重复插入操作

删除订单时记录库存还原(模拟退货)

-- 触发器删除订单时记录库存还原(模拟退货)DELIMITER //CREATE TRIGGER 删除订单退库存AFTER DELETE ON 订单明细FOR EACH ROWBEGIN -- 增加库存 UPDATE 库存 SET 当前库存 = 当前库存 + OLD.购买数量 WHERE 图书名称 = OLD.图书名称; -- 记录库存变动 INSERT INTO 库存变动记录( 图书名称, 操作类型, 数量, 操作时间 ) VALUES ( OLD.图书名称, \'退货\', OLD.购买数量, NOW() );END //DELIMITER ;

        这个名为\"删除订单退库存\"的触发器实现了一个完整的订单取消/退货业务场景的自动化处理逻辑,是库存管理系统中的重要组成部分。该触发器在\"订单明细\"表发生DELETE操作后自动触发,模拟了退货场景下的库存恢复过程。触发器执行两个核心操作:库存恢复:通过UPDATE语句将原订单中图书的购买数量加回到库存中;操作记录:在库存变动记录表中新增一条\"退货\"类型的正向变动记录

以下是书店管理系统总的设计图

3.系统实现

3.1数据库访问设计

        该书店管理系统采用了PyMySQL作为数据库访问技术,实现了基于Python的MySQL数据库操作框架。系统通过模块化的函数设计,将数据库连接、用户认证、图书销售、库存管理和用户管理等核心功能进行了清晰划分。在数据库连接方面,系统使用统一的get_conn()函数建立连接,采用utf8mb4字符集确保中文支持,每次操作后都显式关闭连接以保证资源释放。SQL执行全部采用参数化查询方式,有效防范了SQL注入攻击,特别是在登录验证、购物车操作等关键功能中体现了良好的安全实践。系统实现了完整的事务处理机制,特别是在订单结算(checkout)功能中,通过组合多个SQL操作并配合commit()确保数据一致性。数据库操作涵盖了CRUD全流程,包括多表连接查询(如查看购物车时关联图书表)、聚合计算(如计算订单总金额)、存储过程调用(如销售排名统计)等复杂操作。

# 数据库连接函数def get_conn(): return pymysql.connect( host=\"localhost\", user=\"root\", password=\"123456\", database=\"书店管理系统\", charset=\"utf8mb4\" )

3.2登录模块设计

        登录模块的设计采用了典型的用户名密码验证机制,通过数据库查询实现身份认证和权限控制。系统首先通过get_conn()函数建立与MySQL数据库的连接,配置了主机、用户名、密码、数据库名和字符集等参数。在login()函数中,用户需要输入用户名和密码,程序将这些凭据与\"用户\"表中的记录进行比对,执行SQL查询时使用了参数化查询以防止SQL注入攻击。查询结果返回用户的角色信息(管理员或用户),若验证失败则返回None。登录成功后,系统根据角色类型进入不同的功能菜单:管理员可以访问库存管理、用户管理等高级功能,而普通用户则进入图书销售模块。值得注意的是,用户登录后还需要额外输入用户编号才能继续操作,这个设计可能用于二次验证或会话绑定。

# 登录功能def login(): name = input(\"用户名:\") pwd = input(\"密码:\") conn = get_conn() with conn.cursor() as cur: cur.execute(\"SELECT 角色 FROM 用户 WHERE 姓名=%s AND 密码=%s\", (name, pwd)) row = cur.fetchone() conn.close() return row[0] if row else None

3.3管理员模块设计

        管理员模块的设计围绕书店管理系统的核心管理功能展开,提供了全面的后台管理能力,主要包括库存管理、用户管理和销售分析三大功能板块。在库存管理方面,管理员可以实时查看所有图书的库存情况,通过输入图书编号和变动数量来调整库存水平,系统会自动记录每次库存变动的详细信息(包括操作类型和时间戳),并设有低库存预警功能,当库存量低于预设阈值时会醒目提示,这些设计大大提升了库存管理的效率和准确性。用户管理模块则提供了完整的用户生命周期管理功能,包括添加新用户(需要填写姓名、电话、地址、密码和角色等完整信息)、编辑用户基本信息、删除用户账号以及密码重置等操作,同时支持查看所有用户的完整列表,这些功能通过直接的数据库操作实现,确保了用户数据管理的灵活性和可控性。特别值得注意的是,管理员模块还集成了销售分析功能,可以按指定天数统计图书销售排名,从销量和销售额两个维度展示图书的销售情况并生成排名,为经营决策提供数据支持。整个管理员模块采用菜单驱动的交互方式,通过清晰的数字选项引导操作,每个功能都封装为独立函数,与数据库的交互都使用了参数化查询来防止SQL注入,且严格遵守了打开连接-执行操作-关闭连接的数据访问模式,确保了系统的安全性和稳定性。

# 管理员功能:库存管理模块def view_all_stock(): conn = get_conn() with conn.cursor() as cur: cur.execute(\"\"\" SELECT k.图书名称, b.作者, k.当前库存, k.库存阈值,  CASE WHEN k.当前库存 < k.库存阈值 THEN \'需补货\' ELSE \'充足\' END AS 状态 FROM 库存 k JOIN 图书 b ON k.图书名称 = b.图书名称 \"\"\") print(\"\\n{:<20}{:<15}{:<10}{:<10}{:<10}\".format( \"书名\", \"作者\", \"库存\", \"阈值\", \"状态\")) for row in cur.fetchall(): print(\"{:<20}{:<15}{:<10}{:<10}{: 0 else \"销售\" conn = get_conn() try: with conn.cursor() as cur: # 更新库存 cur.execute(\"\"\" UPDATE 库存 SET 当前库存 = 当前库存 + %s  WHERE 图书名称 = %s \"\"\", (delta, book_name)) # 记录库存变动 cur.execute(\"\"\" INSERT INTO 库存变动记录(图书名称, 操作类型, 数量) VALUES (%s, %s, %s) \"\"\", (book_name, op_type, delta)) conn.commit() print(\"库存更新成功\") except Exception as e: conn.rollback() print(\"库存更新失败:\", e) finally: conn.close()def view_low_stock(): conn = get_conn() with conn.cursor() as cur: cur.execute(\"\"\" SELECT k.图书名称, b.作者, k.当前库存, k.库存阈值 FROM 库存 k JOIN 图书 b ON k.图书名称 = b.图书名称 WHERE k.当前库存 < k.库存阈值 \"\"\") print(\"\\n{:<20}{:<15}{:<10}{:<10}\".format(\"书名\", \"作者\", \"库存\", \"阈值\")) for row in cur.fetchall(): print(\"{:<20}{:<15}{:<10}{:<10}\".format(*row)) conn.close()def view_stock_log(): conn = get_conn() with conn.cursor() as cur: cur.execute(\"\"\" SELECT r.图书名称, b.作者, r.操作类型, r.数量, r.操作时间 FROM 库存变动记录 r JOIN 图书 b ON r.图书名称 = b.图书名称 ORDER BY r.操作时间 DESC \"\"\") print(\"\\n{:<20}{:<15}{:<10}{:<10}{:<20}\".format( \"书名\", \"作者\", \"类型\", \"数量\", \"时间\")) for row in cur.fetchall(): print(\"{:<20}{:<15}{:<10}{:<10}{:<20}\".format(*row)) conn.close()# ===========================# 管理员功能:图书管理模块# ===========================def add_book(): print(\"\\n=== 添加新书 ===\") book_id = input(\"图书编号:\") title = input(\"图书名称:\") author = input(\"作者:\") book_type = input(\"类型:\") price = float(input(\"单价:\")) publisher = input(\"出版社:\") isbn = input(\"ISBN:\") stock = int(input(\"初始库存量:\")) threshold = int(input(\"库存阈值:\")) conn = get_conn() try: with conn.cursor() as cur: # 调用存储过程添加新书 cur.callproc(\"添加新图书\", ( book_id, title, author, book_type, price, publisher, isbn, stock, threshold )) conn.commit() print(f\"成功添加新书《{title}》\") except Exception as e: conn.rollback() print(\"添加新书失败:\", e) finally: conn.close()def view_sales_stats(): conn = get_conn() with conn.cursor() as cur: cur.execute(\"SELECT * FROM 图书销售统计视图\") print(\"\\n{:<10}{:<20}{:<15}{:<15}{:<10}{:<10}{:<10}{:<15}{:<10}\".format( \"编号\", \"书名\", \"作者\", \"类型\", \"单价\", \"销量\", \"销售额\", \"购买用户数\", \"日均销量\")) for row in cur.fetchall(): print(\"{:<10}{:<20}{:<15}{:<15}{:<10}{:<10}{:<10}{:<15}{:<10.2f}\".format(*row)) conn.close()# ===========================# 管理员功能:用户管理模块# ===========================def add_user(): user_id = input(\"用户编号:\") name = input(\"姓名:\") phone = input(\"电话:\") address = input(\"地址:\") password = input(\"密码:\") role = input(\"角色(用户/管理员):\") conn = get_conn() try: with conn.cursor() as cur: cur.execute(\"\"\" INSERT INTO 用户(用户编号, 姓名, 电话, 地址, 密码, 角色) VALUES (%s, %s, %s, %s, %s, %s) \"\"\", (user_id, name, phone, address, password, role)) conn.commit() print(\"用户添加成功\") except Exception as e: conn.rollback() print(\"添加用户失败:\", e) finally: conn.close()def edit_user(): phone = input(\"原电话:\") new_phone = input(\"新电话:\") new_name = input(\"新姓名:\") new_address = input(\"新地址:\") conn = get_conn() try: with conn.cursor() as cur: cur.execute(\"\"\" UPDATE 用户 SET 电话=%s, 姓名=%s, 地址=%s  WHERE 电话=%s \"\"\", (new_phone, new_name, new_address, phone)) conn.commit() print(\"用户信息更新成功\") except Exception as e: conn.rollback() print(\"更新用户信息失败:\", e) finally: conn.close()def delete_user(): phone = input(\"电话:\") conn = get_conn() try: with conn.cursor() as cur: cur.execute(\"DELETE FROM 用户 WHERE 电话=%s\", (phone,)) conn.commit() print(\"用户删除成功\") except Exception as e: conn.rollback() print(\"删除用户失败:\", e) finally: conn.close()def reset_password(): phone = input(\"电话:\") new_pwd = input(\"新密码:\") conn = get_conn() try: with conn.cursor() as cur: cur.execute(\"UPDATE 用户 SET 密码=%s WHERE 电话=%s\", (new_pwd, phone)) conn.commit() print(\"密码重置成功\") except Exception as e: conn.rollback() print(\"密码重置失败:\", e) finally: conn.close()def list_users(): conn = get_conn() with conn.cursor() as cur: cur.execute(\"SELECT 用户编号, 姓名, 电话, 地址, 角色 FROM 用户\") print(\"\\n{:<10}{:<15}{:<15}{:<30}{:<10}\".format( \"编号\", \"姓名\", \"电话\", \"地址\", \"角色\")) for row in cur.fetchall(): print(\"{:<10}{:<15}{:<15}{:<30}{:<10}\".format(*row)) conn.close()

3.4用户模块设计

       用户模块的设计充分考虑了普通用户的操作体验和实际需求,构建了一个完整的图书浏览、选购和订单管理流程。系统通过简洁的菜单导航将功能划分为图书查询、购物车管理和订单处理三大板块,用户登录后可以直观地选择所需功能。图书查询功能提供了两种方式:完整的图书列表展示和按类型筛选,每种方式都清晰地呈现图书编号、书名、作者、类型和价格等关键信息,帮助用户快速找到心仪的书籍。购物车系统采用了智能设计,当用户重复添加同一本书时会自动累加数量而非创建重复条目,购物车内容展示时不仅列出每本书的详细信息,还会实时计算并显示总金额,让用户随时掌握消费情况。订单处理环节实现了完整的结算流程,包括订单创建、明细记录、金额计算和购物车清空等操作,所有步骤都在数据库事务的保护下完成,确保数据一致性。历史订单查询功能进一步完善了用户体验,用户可以随时查看过往订单的详细信息,包括下单时间、订单总额和每本书的购买数量及小计金额,系统会按照时间倒序排列订单,最新订单显示在最前面。整个用户模块采用一致的交互风格,所有数据库操作都遵循连接-查询-关闭的最佳实践,并使用参数化查询防范SQL注入攻击,在保持界面简洁易用的同时确保了系统安全性。

# 用户功能:图书销售模块def list_books(): conn = get_conn() with conn.cursor() as cur: cur.execute(\"\"\" SELECT b.图书编号, b.图书名称, b.作者, b.类型, b.单价, k.当前库存 FROM 图书 b JOIN 库存 k ON b.图书名称 = k.图书名称 \"\"\") print(\"\\n{:<10}{:<20}{:<15}{:<15}{:<10}{:<10}\".format( \"编号\", \"书名\", \"作者\", \"类型\", \"价格\", \"库存\")) for row in cur.fetchall(): print(\"{:<10}{:<20}{:<15}{:<15}{:<10}{:<10}\".format(*row)) conn.close()def filter_books_by_type(): book_type = input(\"输入图书类型:\") conn = get_conn() with conn.cursor() as cur: cur.execute(\"\"\" SELECT b.图书编号, b.图书名称, b.作者, b.单价 FROM 图书 b WHERE b.类型 LIKE %s \"\"\", (f\"%{book_type}%\",)) print(\"\\n{:<10}{:<20}{:<15}{:<10}\".format(\"编号\", \"书名\", \"作者\", \"价格\")) for row in cur.fetchall(): print(\"{:<10}{:<20}{:<15}{:<10}\".format(*row)) conn.close()def add_to_cart(user_phone): book_name = input(\"图书名称:\") qty = int(input(\"数量:\")) conn = get_conn() try: with conn.cursor() as cur: # 获取用户姓名 cur.execute(\"SELECT 姓名 FROM 用户 WHERE 电话=%s\", (user_phone,)) user_name = cur.fetchone()[0] # 检查库存是否足够 cur.execute(\"SELECT 当前库存 FROM 库存 WHERE 图书名称=%s\", (book_name,)) stock = cur.fetchone() if not stock or stock[0] < qty: print(\"库存不足或图书不存在!\") return # 添加或更新购物车 cur.execute(\"\"\" INSERT INTO 购物车(用户电话, 用户名称, 图书名称, 图书数量)  VALUES(%s, %s, %s, %s) ON DUPLICATE KEY UPDATE 图书数量=图书数量+%s \"\"\", (user_phone, user_name, book_name, qty, qty)) conn.commit() print(\"已添加到购物车\") except Exception as e: print(\"添加购物车失败:\", e) finally: conn.close()def view_cart(user_phone): conn = get_conn() with conn.cursor() as cur: sql = \"\"\" SELECT c.图书名称, b.作者, c.图书数量, b.单价, c.图书数量*b.单价 AS 小计 FROM 购物车 c JOIN 图书 b ON c.图书名称 = b.图书名称 WHERE c.用户电话 = %s \"\"\" cur.execute(sql, (user_phone,)) print(\"\\n{:<20}{:<15}{:<10}{:<10}{:<10}\".format( \"书名\", \"作者\", \"数量\", \"单价\", \"小计\")) total = 0 for row in cur.fetchall(): print(\"{:<20}{:<15}{:<10}{:<10}{:<10}\".format(*row)) total += row[4] print(\"总金额:\", total) conn.close()def clear_cart(user_phone): conn = get_conn() with conn.cursor() as cur: cur.execute(\"DELETE FROM 购物车 WHERE 用户电话=%s\", (user_phone,)) conn.commit() conn.close() print(\"购物车已清空\")def checkout(user_phone): conn = get_conn() try: with conn.cursor() as cur: # 获取购物车内容 cur.execute(\"\"\" SELECT c.图书名称, c.图书数量, b.单价, b.单价*c.图书数量 AS 小计 FROM 购物车 c JOIN 图书 b ON c.图书名称 = b.图书名称 WHERE c.用户电话 = %s \"\"\", (user_phone,)) items = cur.fetchall() if not items: print(\"购物车为空!\") return # 计算总金额 total = sum(item[3] for item in items) # 获取用户姓名 cur.execute(\"SELECT 姓名 FROM 用户 WHERE 电话=%s\", (user_phone,)) user_name = cur.fetchone()[0] # 创建订单明细 for book_name, qty, price, _ in items: cur.execute(\"\"\"  INSERT INTO 订单明细(用户电话, 用户名称, 图书名称, 购买数量, 单价, 总金额)  VALUES (%s, %s, %s, %s, %s, %s)  \"\"\", (user_phone, user_name, book_name, qty, price, qty * price)) # 清空购物车 cur.execute(\"DELETE FROM 购物车 WHERE 用户电话=%s\", (user_phone,)) conn.commit() print(f\"订单结算成功,总金额:{total}\") except Exception as e: conn.rollback() print(\"结算失败:\", e) finally: conn.close()def view_order_history(user_phone): conn = get_conn() with conn.cursor() as cur: # 查询用户的所有订单明细 cur.execute(\"\"\" SELECT 图书名称, 购买数量, 单价, 总金额, 下单时间 FROM 订单明细 WHERE 用户电话=%s ORDER BY 下单时间 DESC \"\"\", (user_phone,)) orders = cur.fetchall() if not orders: print(\"您还没有任何订单记录\") return print(\"\\n=== 您的历史订单 ===\") # 按下单时间分组显示订单 current_order_time = None total = 0 for order in orders: if order[4] != current_order_time: if current_order_time is not None:  print(f\"订单总额: ¥{total:.2f}\")  print(\"-\" * 50) current_order_time = order[4] total = 0 print(f\"\\n下单时间: {order[4]}\") print(\"{:<20}{:<10}{:<10}{:<10}\".format(\"书名\", \"数量\", \"单价\", \"小计\")) print(\"{:<20}{:<10}{:<10}{:<10.2f}\".format(order[0], order[1], order[2], order[3])) total += order[3] print(f\"订单总额: ¥{total:.2f}\") conn.close()

3.5系统主模块设计

        该书店管理系统的主模块设计构建了一个层次分明、职责清晰的应用程序架构,以主函数main()作为系统入口,通过角色验证将流程分发至不同的功能模块。系统启动后首先呈现欢迎界面,随后调用login()函数进行用户身份认证,这一过程通过数据库查询验证用户名和密码的匹配性,并返回用户角色类型作为权限控制的依据。认证成功后,系统根据用户角色进入相应的功能菜单:管理员用户进入admin_menu(),提供库存管理、用户管理和销售分析等后台功能;普通用户则进入user_menu(),专注于图书浏览和购买流程。主模块通过严格的角色隔离确保了系统安全性,同时采用直观的菜单驱动交互模式,使用数字选项引导用户操作,降低了使用门槛。在数据库连接管理方面,系统通过get_conn()函数集中处理连接配置,确保所有数据库操作使用统一的连接参数,并在每次操作后及时关闭连接,避免资源泄漏。主模块的设计充分体现了模块化思想,将不同的业务功能封装为独立的函数,通过清晰的函数调用关系组织业务流程,既保证了代码的可维护性,又便于功能扩展。整个主控流程采用循环结构实现持续交互,直到用户选择退出系统,期间所有的用户输入和数据库操作都进行了必要的错误处理,保障了系统的稳定性。这种主模块设计方式将系统的核心控制逻辑与具体业务实现分离,形成了一个结构合理、易于维护的应用程序框架,为书店的日常运营管理提供了可靠的技术支持。

def main(): print(\"=== 欢迎进入书店管理系统 ===\") login_result = login() if login_result: role, phone = login_result if role == \"管理员\": admin_menu() else: user_menu(phone) else: print(\"登录失败,请检查电话或密码。\")if __name__ == \"__main__\": main()

4.系统测试

4.1数据库测试设计

4.2数据库测试内容