当前位置: 首页 > news >正文

别再死记硬背了!用这5个真实业务场景(选课/图书/医院),手把手教你画E-R图和设计数据库表

实战数据库设计:5个真实业务场景下的E-R图与表结构解析

在数据库设计的教学过程中,最常听到的抱怨就是"学了一堆理论,遇到真实项目还是无从下手"。确实,单纯记忆E-R图的菱形、矩形符号,或是背诵范式的定义,并不能真正培养出解决实际问题的能力。本文将打破传统教学模式,选取教育、医疗、图书管理等五个典型业务场景,带您从零开始完成完整的数据库设计流程。

1. 选课管理系统:从需求到实现的完整设计

大学选课系统是理解多对多关系的经典案例。让我们从一个真实的需求出发:某高校需要开发新系统,要求记录学生选课情况、成绩,并能统计各班级选课人数。系统需支持学生查询已修学分,教师录入成绩,管理员生成报表等功能。

核心实体识别

  • 学生:学号(主键)、姓名、性别、年龄
  • 班级:班号(主键)、班名、所属专业
  • 课程:课程号(主键)、课程名、学分、开课学期

关键业务规则

  1. 一个班级包含多个学生,每个学生只属于一个班级(1:n)
  2. 学生可选修多门课程,每门课程可被多个学生选修(m:n)
  3. 成绩只存在于学生与课程建立联系后(联系属性)
-- 最终表结构SQL实现 CREATE TABLE 班级 ( 班号 CHAR(6) PRIMARY KEY, 班名 VARCHAR(20) NOT NULL, 专业 VARCHAR(30) ); CREATE TABLE 学生 ( 学号 CHAR(10) PRIMARY KEY, 姓名 VARCHAR(10) NOT NULL, 性别 CHAR(1) CHECK(性别 IN ('男','女')), 年龄 SMALLINT, 班号 CHAR(6) REFERENCES 班级(班号) ); CREATE TABLE 课程 ( 课程号 CHAR(8) PRIMARY KEY, 课程名 VARCHAR(30) NOT NULL, 学分 SMALLINT DEFAULT 2, 开课学期 SMALLINT ); CREATE TABLE 选课 ( 学号 CHAR(10) REFERENCES 学生(学号), 课程号 CHAR(8) REFERENCES 课程(课程号), 成绩 DECIMAL(5,2), 选课时间 DATE, PRIMARY KEY (学号, 课程号) );

注意:成绩应该作为选课表的属性而非学生表,因为只有选课后才会产生成绩。学分则属于课程固有属性。

2. 医院病房管理系统:复杂业务关系的处理技巧

医疗系统的数据模型往往涉及复杂的业务规则。某三甲医院需要建立住院管理系统,需管理科室、病房、医生和病人的多级关系。特殊要求包括:每个病人有唯一主管医生,医生只能属于一个科室,病房需按科室分配。

设计过程中的关键决策点

  1. 科室-病房关系:采用1:n设计,病房表包含科室外键
  2. 医生分配:医生表中设置科室外键,病人表设置医生外键
  3. 病房分配:病人表需要同时记录病房号和床位号(复合外键)

E-R图转换关系模型

表名主键外键特殊约束
科室科名科电话需符合格式校验
病房病房号科名→科室.科名床位号需与病房号联合唯一
医生工作证号科名→科室.科名职称需在预设范围内
病人病历号工作证号→医生.工作证号病房号+床位号→病房.病房号+床位号
-- 病房表的特殊设计 CREATE TABLE 病房 ( 病房号 VARCHAR(10), 床位号 VARCHAR(5), 科名 VARCHAR(20) REFERENCES 科室(科名), PRIMARY KEY (病房号, 床位号), UNIQUE (病房号, 床位号, 科名) -- 确保病房属于指定科室 );

3. 图书借阅系统:时间维度与历史记录设计

图书馆管理系统需要特别关注时间维度的处理。以某市图书馆为例,系统需记录每本书的借还历史,计算逾期罚款,并限制读者借阅数量。关键业务规则包括:同一本书可能被反复借阅,需要完整历史记录;还书日期可能为空(表示未还);不同类型读者借阅上限不同。

历史数据处理的三种方案对比

  1. 状态标记法(简单但不完整):

    CREATE TABLE 借阅 ( 读者编号 VARCHAR(10), 图书编号 VARCHAR(20), 借期 DATE NOT NULL, 还期 DATE NULL, 状态 CHAR(1) DEFAULT '0' -- 0在借 1已还 );
  2. 版本号法(适合频繁更新):

    CREATE TABLE 借阅历史 ( record_id SERIAL PRIMARY KEY, 读者编号 VARCHAR(10), 图书编号 VARCHAR(20), 操作时间 TIMESTAMP, 操作类型 CHAR(1), -- B借 R还 经办人 VARCHAR(10) );
  3. 触发器辅助法(自动维护历史):

    CREATE TABLE 借阅日志 ( log_id SERIAL PRIMARY KEY, 原记录ID INT, 操作类型 VARCHAR(10), 操作时间 TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 操作人 VARCHAR(20) );

提示:对于需要完整审计追踪的系统,建议采用方案3,虽然实现复杂但数据最可靠。

4. 电商订单系统:主从表设计与事务处理

电商平台的订单系统是典型的一对多关系案例。一个订单包含多个商品,每个商品条目有独立的价格、数量(考虑促销价可能变化)。设计时需要特别注意数据一致性和事务完整性。

订单核心表结构

CREATE TABLE 订单 ( 订单号 VARCHAR(20) PRIMARY KEY, 用户ID VARCHAR(20) NOT NULL, 下单时间 TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 总金额 DECIMAL(10,2) CHECK(总金额 >= 0), 状态 VARCHAR(10) CHECK(状态 IN ('待支付','已支付','已发货','已完成','已取消')), 收货地址 TEXT ); CREATE TABLE 订单明细 ( 明细ID SERIAL PRIMARY KEY, 订单号 VARCHAR(20) REFERENCES 订单(订单号), 商品ID VARCHAR(15) NOT NULL, 购买价 DECIMAL(10,2) NOT NULL, 数量 INT CHECK(数量 > 0), 优惠金额 DECIMAL(10,2) DEFAULT 0, UNIQUE (订单号, 商品ID) -- 防止同一商品重复添加 );

常见问题处理方案

  1. 价格不一致问题:记录购买时的快照价格,而非实时引用商品表价格
  2. 库存扣减时机:支付成功后异步扣减,采用预扣库存机制
  3. 订单取消处理:需要事务处理订单状态和库存回滚

5. 仓储管理系统:多对多关系的复杂案例

仓库管理系统涉及零件、供应商和工程项目的复杂多对多关系。特殊挑战包括:同一零件可能来自不同供应商且价格不同;工程项目需要记录每种零件的需求总量;需要跟踪每次采购的交货情况。

核心表设计技巧

  1. 三元关系处理:引入供应关系表记录供应商-零件-工程的三方关系
  2. 历史价格追踪:在采购表中记录每次交易价格,而非仅在零件表中维护
  3. 库存事务设计:采用入库单、出库单模式,便于审计追踪
CREATE TABLE 供应关系 ( 供应商ID VARCHAR(10), 零件ID VARCHAR(15), 工程ID VARCHAR(12), 报价 DECIMAL(10,2), 最小起订量 INT, 交货周期 INT, PRIMARY KEY (供应商ID, 零件ID, 工程ID) ); CREATE TABLE 采购单 ( 采购单号 VARCHAR(20) PRIMARY KEY, 供应商ID VARCHAR(10), 工程ID VARCHAR(12), 创建时间 TIMESTAMP, 预期到货 DATE, 状态 VARCHAR(10) ); CREATE TABLE 采购明细 ( 明细ID SERIAL PRIMARY KEY, 采购单号 VARCHAR(20) REFERENCES 采购单(采购单号), 零件ID VARCHAR(15), 数量 INT, 实际单价 DECIMAL(10,2), 到货状态 VARCHAR(10) );

在实际项目中,数据库设计从来不是一蹴而就的过程。我曾参与一个图书管理系统的重构,最初设计忽略了读者可能续借的情况,导致后来不得不增加续借次数字段并修改相关查询逻辑。经验告诉我们:好的设计应该预留适当的扩展空间,同时保持核心数据结构的稳定。

http://www.jsqmd.com/news/763056/

相关文章:

  • 2026去屑止痒洗发水实测榜:谁真正从根源解决问题? - 新闻快传
  • 2026最新翡翠高端私人定制公司/厂商/工厂推荐!广东优质权威榜单发布,实力靠谱佛山公司/厂商/工厂值得选 - 十大品牌榜
  • 实战避坑:DolphinScheduler调度Seatunnel任务时,部署模式(deploy-mode)选错怎么办?
  • 你的进化树为什么不好看?可能是IBS矩阵到NJ树这一步没做对(R语言实战避坑指南)
  • OpenCore Legacy Patcher:让老款Mac重获新生的三大核心功能
  • CobaltStrike BOF进阶:手写一个实用的内网信息收集工具(含源码解析)
  • Orbio OpenClaw插件:在聊天工具中实现B2B客户自动发现与导出
  • 别再傻傻分不清!用FreeRTOS和STM32CubeMX实战,彻底搞懂ARM Cortex-M的SVC和PendSV
  • SFTP连接报Broken pipe?别慌,八成是chroot目录权限没设对(附详细排查步骤)
  • 招聘软件哪个最好用?2026权威榜单:易直聘领跑行业 - 博客万
  • 重庆看心理医生?这份暖心指南+案例分享太实用了
  • 企业教练服务机构怎么选?埃里克森专业沉淀树立行业标杆,四大维度破解选型难题 - 资讯焦点
  • 2026年山西精准获客与GEO生成式引擎优化深度指南:中小企业低成本获客系统全景横评 - 企业名录优选推荐
  • 护发精油推荐:6款热门护发精油品牌的明星产品 - 博客万
  • 新手零基础入门:无需git下载配置,AI一键生成带详解的待办事项应用
  • 别只当视频生成器!Runway Gen2的Motion Brush和风格预设,才是短视频创作者的效率神器
  • Windows11开发环境避坑指南:RocketMQ 5.1.0从下载到Dashboard的完整配置流程
  • 键盘连击终极解决方案:免费开源工具KeyboardChatterBlocker完整指南
  • 保姆级教程:手把手教你用IgH Master配置EtherCAT DC同步(附Shift Time避坑指南)
  • AI全栈开发蓝图:基于Python+TypeScript的生产级应用架构实践
  • S9赛季三角洲游戏头部商行口碑评测推荐 - 资讯焦点
  • 海南医学院考研辅导班机构推荐:排行榜单与哪家好评测 - michalwang
  • AI Agents 开源 LLM 简报 (2026年5月5日)
  • 浙江理工大学考研辅导班机构推荐:排行榜单与哪家好评测 - michalwang
  • 重庆交通大学考研辅导班机构推荐:排行榜单与哪家好评测 - michalwang
  • 别再让Chocolatey拖慢你的Node.js安装!Windows 11纯净安装与包管理分离指南
  • 企业级消息中台架构设计:基于飞书分发框架的实践指南
  • 告别GNS3和eNSP!在Ubuntu 22.04上用VirtualBox 7.0搭建全能网络实验室EVE-NG保姆级教程
  • 河北经贸大学考研辅导班机构推荐:排行榜单与哪家好评测 - michalwang
  • 20分钟搭好专属测试用例Skill,效率直提8倍(附模板+可复制Prompt)