第一大题
在某电商系统数据库中设计如下关系模式:
订单表(orders)(订单号,用户编号,用户名称,商品编号,商品名称,优惠券编号,订单时间,订单金额,订单状态,用户vip等级)
用户表(users)(用户编号,用户名称,累计金额,用户vip等级)
问题1:
(1)分析订单表存在的函数依赖。
(2)订单表属于第几范式?为什么?
(3)对订单表进行分解,使其满足BCNF范式,给出分解后的关系模式。
问题2:针对问题1的分解结果:
(1)分解是否保持函数依赖?说明理由。
(2)分解是否是无损分解?说明理由。
问题3:补充触发器SQL代码空白:
CREATE TRIGGER update_vip_level
AFTER (a) ON_(b)
FOREACH_( c)
BEGIN
UPDATE 订单表
SET用户vip等级=_ ( d) _
分析师
WHERE用户编号=:NEW.(e) ;
END;
问题4:
(1)上述触发器存在哪些性能问题?
(2)给出至少2个优化方案。
第二大题某软件企业开发一套类似于淘宝网上商城业务的电子商务网站。该系统涉及多种用户角色,包括购物用户,商铺管理员,系统管理员等。
在数据库设计中,该系统数据库的核心关系包括:
产品(
产品编码,产品名称,产品价格,库存数量,商铺编码)商铺(
商铺编码,商铺名称,商铺地址,商铺邮箱,服务电话;用户(用户编码,用户名称,用户地址,联系电话)
订单(订单编码,
订单日期,用户编码,商铺编码,产品编码,产品数量,订单总价)不同用户角色也有不同的数据需求,为此该软件企业在基本数据库关系模式的基础上,定制了许多试图。其中,有很多视图涉及到多表关联和聚集函数运算。问题1】(8分) 商铺用户需要实时统计本商铺的货物数运和销售情况,以便及时补货,或者为商铺调整销售策略。为此专门设计了可实时查看当天商铺中货物销售情况和存贷情况的视图,商铺产品销售情况日报表(商铺编码,产品编码,日销售产品数量,库存数量,日期)。数据库运行测试过程中,发现针对该视图查询性能比较差,不满足用户需求。请说明数据库视图的基木概念及其优点,并说明本视图设计导致查询性能较差的原因。 `1、视图能简化用户的操作` `2、视图机制可以使用户以不同的方式查询同一数据` `3、视图对数据库重构提供了一定程度的逻辑独立性` `4、视图可以对机密的数据提供安全保护` `查询性能较差的原因是视图中"日销售产品数量"需要针对订单表做统计分析,订单表中有数量庞大的历史销售记录,所以这种操作极为耗时。` 【问题2】(8分) 为解决该枧图查洵性能比较差的问题,张工建议为该数据建立单独的商品当天货物销售、存货情况的关系表。但李工认为张工的方案造成了数据不一致的问题,必须采用一定的手段来解决。 1)说明张工方案是否能够对该视图查询性能有所提升,并解释原因。 `张工方案能够对该视图查询性能有所提升,因为这样做能极大的减少统计分析的数据量,对小数据量进行统计,性能是能得以保障的。` 2)解释说明李工指出的数据不一致问题产生的原因。 `由于当日订单数据既存储在订单表中,又存储在单独的当天货物销售、存货情况表中。同一数据存储了两份,一旦出现修改,未同步修改,则会造成数据不一致。` 【问题3】(9分) 针对李工提出的问题,常见的解决手段有应用程序实现,触发器实现和物化视图实现等、请用300字以内的文字解释说明这三种方案。 `应用程序实现:在进行订单的添加、修改、删除操作时,从应用程序中,控制对两个数据表都进行相关操作,以保障数据的一致性。` `触发器实现:在应用程序中,只对订单表进行操作。但写触发器,当订单表发生变化时,把当日订单内容同步更新到当天货物销售、存货情况表中。` `物化视图实现:建立"当天货物销售、存货情况"的物化视图,物化视图会把相应的数据物理存储起来,而且在订单表发生变化时,会自动更新。` 【分析】 视图(View)是从一个或多个表(或视图)导出的表。视图与表(有时为与视图区别,也称表为基本表一-Base Table)不同,视图是一个虚表,即视图所对应的数据不进行实际存储,数据库中只存储视图的定义,在对视图的数据进行操作时,系统根据视图的定义去操作与视图相关联的基本表。
1)应用程序实现
在 Java/后端代码里手动维护汇总表。
说是手动同步,本质做个逻辑判断让代码自动同步
- 当订单新增、商品库存变化时,业务代码里同步更新汇总表
- 比如:下单成功后,不仅插订单表,还要更新当天销售统计表
- 由应用层保证两张表数据一致
优点 :灵活,逻辑完全可控
缺点:代码侵入强,容易漏写,出错就不一致
① 业务逻辑更灵活
汇总逻辑可能很复杂:
满减、折扣、优惠券计算
不同商品不同统计规则
异常订单要过滤
这些写在 Java 里简单、易读、好维护
写在触发器里会变成一堆复杂 SQL,非常难改。
② 便于控制事务
Java 可以用事务:
订单插入成功 → 再更新汇总
任意一步失败 → 整体回滚
触发器是数据库隐式事务,出问题很难排查。
③ 便于扩展、加日志、加监控
Java 里可以:
打日志
监控统计是否正确
发送消息、通知、报表
数据库触发器做不到这么灵活。
④ 避免数据库压力过大
触发器是行级触发,订单量大时数据库 CPU 爆掉。
Java 可以做批量更新、异步更新、限流,更稳定。
2)触发器实现
用数据库触发器自动同步。
- 在订单表、产品表上建立 INSERT/UPDATE/DELETE 触发器
- 只要原表数据发生变化,数据库自动触发 SQL 更新汇总表
- 不需要改业务代码,数据库自己保证同步
优点 :实时同步,不用改程序
缺点:触发器多了性能差,排错难
3)物化视图实现
把视图结果物理存储,定时/自动刷新。
- 物化视图 = 物理化的视图,真实存储数据
- 查询直接读物化视图,极快
- 原表变化后,通过刷新(手动/定时/自动) 保持一致
优点 :性能最好,不用写代码,数据库原生支持
缺点:部分数据库(MySQL)不支持,数据有短暂延迟
第三大题
阅读以下关于系统数据分析与建模的叙述,在答题纸上回答问题1至问题3。
说明】某软件公司受快递公司委托,拟开发一套快递业务综合管理系统,实现快递单和物流信息的综合管理。项目组在系统逻辑数据模型设计中,需要描述的快递单样式如图2-1所示,图2-2是项目组针对该快递单所设计的候选实体及其属性。  【问题1】(6分) 数据库设计主要包括概念设计、逻辑设计和物理设计三个阶段,请用200字以内文字说明这三个区阶段的主要任务。 `概念结构设计阶段` `绘制 E-R 图,抽象实体、属性、联系,与具体数据库无关。` `逻辑结构设计阶段` `把实体→表,属性→字段,联系→外键 / 关联表,做范式优化。` ` 物理结构设计阶段` `选择存储引擎、设计索引、分区、主从复制等物理实施方案。` 【问题2】(11分) 根据快递单样式图,请说明: 1)图2-2中三个候选实体对应的主属性PK1、PK2和PK3分别是什么? `证件号` `编号` `证件号` 2)图2-2中应设计哪些实体之间的联系,并说明联系的类型。 `一对一` `一对多` `其中寄件人和快递单一对多(1:n)` `其中收件人和快递单一对多(1:n)` 【问题3】(8分) 在图2-2中添加实体之间的联系后,该实体联系图是否满足第一范式、第二范式和第三范式中的要求(对于每种范式判定时,假定己满足低级别范式要求)。如果不满足,请用200字以内文字分别说明其原因。 `寄件人,收件人均满足第3范式,因为这两个关系均消除了部分函数依赖与传递函数依赖。(自然也就同时满足第1范式与第2范式)。` ` 快递单满足第2范式,但不满足第3范式,快递单的主键为编号,编号确定:保价金额、代收货款、运费、加急费、包装费、保价费,而这一系列费用的组合确定总计。所以存在传递函数依赖。` `注:增加了寄件人证件号与收件人证件号到快递单中,并不会影响快递单满足第2范式。`
数据库设计标准4 个阶段
-
需求分析阶段
收集数据需求、处理流程、约束条件,明确要存什么、怎么用。
-
概念结构设计阶段
绘制 E-R 图,抽象实体、属性、联系,与具体数据库无关。
-
逻辑结构设计阶段
把实体→表,属性→字段,联系→外键 / 关联表,做范式优化。
-
物理结构设计阶段
选择存储引擎、设计索引、分区、主从复制等物理实施方案。
需求分析 → 概念设计(E-R)→ 逻辑设计(表结构)→ 物理设计(索引/存储)
-
需求捕获(用例图驱动)
- 分析业务,识别参与者(如:买家、卖家)
- 定义核心用例(如:下单、支付、发货)
- 输出:清晰的功能边界与用户价值
-
数据提取(从用例到实体)
- 遍历每个用例,提取必须存储的业务对象
- "下单" → 实体:用户、商品、订单、订单明细
- "支付" → 实体:支付记录、交易流水
- 规则 :每个用例的执行,必然依赖或产生某些数据
- 遍历每个用例,提取必须存储的业务对象
-
ER 图设计
- 将提取的"业务对象"转为ER图实体
- 定义属性与主键
- 根据业务规则定义关系(1:N, M:N)
- 输出:完整的概念数据模型
-
双向校验(关键)
- 用例 → 数据:所有用例所需数据是否都在ER图中?
- 数据 → 用例:ER图中所有实体是否被至少一个用例使用?
- 目的 :确保功能与数据完全匹配,无遗漏、无冗余
实例:电商系统
用例图
- 参与者:顾客、管理员
- 用例 :注册、登录、浏览商品、加入购物车、提交订单 、支付

ER 图(从用例推导)
- 实体 :用户(User)、商品(Product)、购物车(Cart)、订单(Order)、订单明细(OrderItem)
- 关系 :
- 用户 1:N 订单
- 订单 1:N 订单明细
- 订单明细 N:1 商品

第四大题阅读以下关于数据库分析与建模的叙述,在答题纸上回答问题1至问题3.
说明】 某电子商务企业随着业务不断发展,销售订单不断增加,每月订单超过了50万笔,急需开发一套新的互联网电子订单系统。同时该电商希望建立相应的数据中心,能够对订单数据进行分析挖掘,以便更好地服务用户。 王工负责订单系统的数据库设计与开发,初步设计的核心订单关系模式为: orders (order_no, customer_no, order_date, product_no, price, ...); 考虑订单数据过多,单一表的设计会对系统性能产生较大影响,仅仅采用索引不足以解决性能问 题。因此,需要将订单表拆分,按月存储。王工采用反规范化设计方法来解决,给出了相应的解决方案。李工负责数据中心的设计与开发。李工认为王工的解决方案存在问题,建议采用数据物理分区技术。在解决性能问题的同时,也为后续的数据迁移、数据挖掘和分析等工作提供支持。 【问题1】(8分) 常见的反规范化设计包括增加冗余列、增加派生列、重新组表和表分割。为解决题干所述需求,王工采用的是哪种方法?请用300字以内的文字解释说明该方法,并指出其优缺点。 `王工采用的是表分割的方式进行反规范化设计。` `表分割包括水平分割与垂直分割两种形式:` `水平分割:把一张表的数据按行切成多张表,表结构一样,数据不同。` `垂直分割:把主码和一些列放到一个表,然后把主码和另外的列放到另一个表中。` `优点:` `(1)表分割的方式将数据分布到多个逻辑与物理上均独立的不同的表。对于电子商务中的订单,最频紧的操作针对的是当月的订单表,表分割后有效地减少了操作表(即当月订单表)的记录数,可有效提升性能。同时按月进行表分割后,也可以针对各月份数据进行管理,有利于数据迁移、备份和管理。` `缺点: (1)表分割的方式从逻辑上破坏了关系概念的完整性,由一个关系变为多个关系。因此,进行历史数 居的数据挖掘和分析时,必须执行多表集合并操作,相对于单表形式,复杂度较高,增加了数据维护的难度,应用软件设计和实现也更为复杂。` 【问题2】(8分) 物理数据分区技术一般分为水平分区和垂直分区,数据库中常见的是水平分区。水平分区分为范围分区、哈希分区、列表分区等。请阅读下表,在(1)\~(8)中填写不同分区方法在数据值、数据管理能力、实施难度与可维护性、数据分布等方面的特点。  `(1)连续` `(2)离散` `(3)弱` `(4)强` `(5)好` `(6)好` `(7)不均匀` `(8)均匀` 【问题3】(9分) 根据需求,李工宜选择物理水平分区中的哪种分区方法?请用300字以内的文字分别解释说明该方法的优缺点。 `范围分区李工宜选择范围分区方式。` `范围分区优点包括:实现容易、数据管理能力强、提高查询效果、利于维护如备份恢复时间都可缩短、利于做过期过处理。` `范围分区缺点包括:数据分布不均匀所以可以与哈希分区组合应用`
一、常见的反规范化设计(高频考点)
1. 冗余字段(最常用)
- 把关联表的常用字段直接复制一份到主表
- 例:订单表
order里,不只存user_id,还冗余存user_name、user_phone - 好处:查订单时不用再关联用户表
2. 合并表(两张表合成一张)
- 把一对一、一对多的表强行合并
- 例:用户表 + 用户详情表 → 合并成一张大表
- 好处:少一次 join
3. 增加汇总/统计字段
- 提前算好总数、合计,存在表里
- 例:商品表加
total_sales总销量,而不是每次查订单去 sum - 好处:统计查询极快
4. 建立中间表/快照表(物化视图思路)
- 把多表 join 的结果物理存成一张表
- 报表专用,定时更新
- 好处:复杂报表秒出
5. 数组/集合类型(NoSQL 思路)
- 把一对多数据存在一个字段里
- 例:用户表加
hobby存'篮球,游戏,读书' - 好处:不用建子表,不用关联
6. 允许部分数据重复
- 比如大量日志、历史记录,允许重复存储
- 不追求完全干净,追求写入快
- 规范化:减少冗余、保证一致性、方便更新
- 反规范化 :增加冗余、减少 JOIN、提高查询速度
水平分区 vs 垂直分区 技术对比表
| 类型 | 拆分方式 | 常见具体分区技术 | 典型场景 | 优点 | 缺点 |
|---|---|---|---|---|---|
| 水平分区 (按行切) | 把同一张表的不同行 分到不同分区 表结构完全一样 | 1. 范围分区 2. 哈希分区 3. 列表分区 4. 组合分区(如范围+哈希) | 订单表按年/月 日志按时间 用户按地区/ID | 单表数据量小 查询更快 删除历史数据极快 | 跨分区查询复杂 需要路由规则 |
| 垂直分区 (按列切) | 把一张表的列 拆成多张表 按字段使用频率拆分 | 1. 基础+扩展拆分 2. 冷热列分离 3. 大字段独立表 | 字段极多的大表 含 TEXT/BLOB 字段 常用字段与不常用字段分离 | 热字段表更小 IO 更快 减少不必要字段读取 | 需要 JOIN 查询 增加表数量 |
三种水平分区技术再简单说明(必考点)
-
范围分区(RANGE)
按连续区间拆分,如:时间、价格、ID 区间
例:订单按 2023、2024、2025 年分区
-
列表分区(LIST)
按离散值列表拆分
例:按省份/地区/状态分区
-
哈希分区(HASH)
对字段做哈希运算均匀分散数据
例:用户 ID 哈希取模,均匀分布到多个分区
- 水平分区:切行,表结构不变 → 常用范围、哈希、列表
- 垂直分区:切列,拆成多个表 → 冷热分离、基础+扩展
第五大题
阅读以下关于数据库设计的叙述,在答题纸上回答问题1至问题3。某航空公司要开发一个订票信息处理系统,以方便各个代理商销售机票。开发小组经过设计,给出该系统的部分关系模式如下:
航班(航班编号,航空公司,起飞地,起飞时间,目的地,到达时间,剩余票数,票价)
代理商(代理商编号,代理商名称,客服电话,地址,负责人)
机票代理(代理商编号,航班编号,票价)
旅客(身份证号,姓名,性别,出生日期,电话)
购票(购票单号,身份证号,航班编号,搭乘日期,购票金额)
在提供给用户的界面上,其核心功能是当用户查询某航班时,将该航班所有的代理商信息及其优惠票价信息,返回给用户,方便用户购买价格优惠的机票。在实现过程中发现,要实现此功能,需要在代理商和机票代理两个关系模式上进行连接操作,性能很差。为此开发小组将机票代理关系模式进行了扩充,结果为:
机票代理(代理商编号,航班编号,代理商名称,客服电话,票价)这样,用户在查找信息时只需对机票代理关系模式进行查询即可,提高了查询效率。
【问题1】(6分)
机票代理关系模式的修改,满足了用户对代理商机票价格查询的需求,提高了查询效率。但这种修改导致机票代理关系模式不满足3NF,会带来存储异常的问题。
1)请具体说明其问题,并举例说明。
会带来数据的冗余,比如需要存大量重复的客服电话、代理商名称
修改异常,由于有上述冗余情况,比如客服电话变更了,就需要大量修改客服电话并保持一致,否则就会出现客服电话值不一致的情况2)这种存储异常会造成数据不一致,请给出解决该存储异常的方案。
可使用触发器在修改时,检查并更新对应数据的方式来解决数据不一致的问题【问題2】(9分)
在机票销售信息处理系统中,两个代理商的售票并发执行,可能产生的操作序列如表4-1所示。
假设两个代理商执行之前,该航班仅剩1张机票。
1)请说明上述两个代理商操作的结果。
两个代理商都成功售出一张票,剩余票数为02)并发操作会带来数据不一致的问题,请具体说明3种问题。
脏读:你看到别人写了字,结果他Ctrl+Z 撤销了
不可重复读:你看同一行,第一次 100,第二次 90
丢失修改:你改完,别人也改,你的修改直接没了问题3】(10分) 为了避免问题2中的问题,开发组使用库的读写锁机制,操作序列变为表4-2所示。表4-2加入读写锁机制后,两个代理商可能的操作序列  请填写表中的空白项,并用150字以内的文字说明读写锁机制的缺点。 `(1)加写锁` `(2)加读锁` `(3)加写锁` `(4)等待` `(5)得到通知` `(6)加写锁` `读多写易饿,实现复杂开销大,优先级反转,还可能死锁。`
读写锁核心规则
- 加了读锁 → 还能再加读锁
(读读共享,多人可以一起读) - 加了读锁 → 不能加写锁
- 加了写锁 → 任何锁都加不了
(写写互斥、读写互斥,独占)
