Day28-05|6.2.1 关系数据库基本概念
Day28-05|6.2.1 关系数据库基本概念:用关系、键和约束守住数据语义
本文对应《系统架构设计师教程(第2版)》第6章“数据库设计基础知识”6.2.1“关系数据库基本概念”。关系数据库以关系模型为基础,用二维表组织结构化数据,并通过键、外键和完整性约束表达实体唯一性、实体之间的联系以及合法数据状态。对系统架构师而言,关系数据库的重点不只是会写查询,更是能够把业务规则转化为稳定的数据结构和可验证的约束。
一、学习目标与考试定位
完成本节后,应掌握域、属性、元组、关系、关系模式、关系实例、候选键、主键、外键等基本术语;理解关系的性质和关系数据库的结构特点;能够说明实体完整性、参照完整性和用户定义完整性;能够分析空值、重复数据、主键选择、外键删除和多对多关系设计问题;能够在案例题和论文中把关系模型与事务、一致性、数据治理和架构演进结合起来。
考试中的概念题常要求辨析“关系”和“关系模式”“主键”和“候选键”“外键是否必须唯一”“空值是否等于零”。案例题则可能给出订单、客户、商品等表结构,让考生指出主键不稳定、外键缺失、关系重复或约束未落实的问题。答题要先使用准确术语,再结合业务影响说明设计理由。
二、关系模型的基本组成
关系模型把现实世界中的数据组织成若干关系。关系在实现上通常表现为表,但关系的数学含义不完全等同于任意一张表。关系由关系模式和关系实例组成:关系模式描述关系的结构、属性和约束,关系实例是某个时刻实际存在的元组集合。
1. 域
域是属性可能取值的集合及其语义。例如性别代码域、金额域、日期域和订单状态域。域不仅约束数据类型,还应说明单位、精度、取值范围和业务含义。金额的“100”究竟表示元、分还是美元,不能只靠字段名猜测。
2. 属性
属性是关系中的列,用于描述实体或联系的特征。属性应具有明确、原子且一致的语义。把“收货地址”拆成省、市、区、详细地址,还是作为一个不可分字符串,取决于检索、统计、校验和生命周期要求。
3. 元组
元组是关系中的一行,表示一个实体实例或联系实例。例如客户关系中的一行表示一个客户,订单明细关系中的一行表示某订单与某商品的一次关联及其数量。
4. 关系
关系是具有相同属性结构的一组元组。关系中的元组理论上无序,属性也应具有明确名称和语义。实际数据库会通过物理顺序、索引和执行计划提高效率,但应用不应依赖自然行顺序。
三、关系模式与关系实例
关系模式可以写成关系名及属性集合,例如 Customer(CustomerId, Name, Phone, Status)。它描述结构,不代表当前有多少客户。关系实例是此模式下的具体数据集合,随着插入、更新和删除而变化。
区分二者很重要:增加一条客户记录是实例变化,增加客户等级字段是模式变化;实例变化通常由业务事务完成,模式变化需要设计、评审、迁移和兼容。若把模式变化当成普通数据操作,容易在生产环境直接修改结构,造成应用和报表失效。
关系数据库还要区分基表、视图和查询结果。基表保存相对持久的数据,视图是由一个或多个关系导出的逻辑结构,查询结果是某次操作得到的数据集。视图可以提供外模式和安全边界,但复杂视图的性能和更新能力需要验证。
四、键的概念
1. 超键
超键是能够唯一标识一个元组的属性或属性组合。例如客户编号是超键,客户编号加姓名也可能是超键,但后者包含多余属性。
2. 候选键
候选键是最小超键,即能够唯一标识元组且去掉其中任何属性后不再具备唯一性。一个关系可能有多个候选键,例如员工编号和身份证号都能唯一标识员工。
3. 主键
主键是从候选键中选定的、作为主要标识的键。主键应稳定、唯一、非空,并尽量少受业务变化影响。使用自然键还是代理键要结合外部交换、可读性、变化频率、唯一性和跨系统集成评估。代理键可以稳定关联,但不能因此取消对业务唯一性的约束。
4. 外键
外键是一个关系中的属性或属性组合,引用另一个关系的候选键,通常引用主键。外键表达关系并支持参照完整性,但不必唯一;例如多个订单可以属于同一客户。外键是否允许空值、删除父记录时如何处理,都要由业务规则确定。
5. 复合键
复合键由多个属性组成,常用于联系关系。例如订单明细可以用订单编号和商品编号作为联合主键,防止同一订单重复出现同一商品。若同一商品允许多批次或多次报价,则需要增加明细序号或业务标识,不能机械使用两个字段。
五、关系的完整性约束
1. 实体完整性
实体完整性要求主键值唯一且非空,因为主键用于识别元组,空值或重复会导致实体无法区分。实际数据库通常通过主键约束和唯一索引实现。
2. 参照完整性
参照完整性要求外键值要么为空(若业务允许),要么必须对应被引用关系中存在的候选键值。例如订单的客户编号必须指向存在的客户。删除或修改被引用的客户时,系统必须依据规则拒绝、级联、置空或转移,不能留下悬挂订单。
3. 用户定义完整性
用户定义完整性是根据具体业务规定的约束,如金额大于等于零、结束时间不早于开始时间、订单状态只能按合法顺序变化、一个用户同一时刻只能有一个有效订阅。约束可以由数据库检查、触发器、应用服务、状态机或跨服务流程共同实现。
完整性约束要尽量靠近数据和业务不变量。仅在前端判断“库存充足”无法防止并发请求同时扣减;仅在单个服务判断“用户名唯一”也无法覆盖并发和多入口写入。关键规则应有数据库级或服务级的最终保障。
六、空值及其语义
空值表示未知、不适用、尚未提供或缺失,不能简单等同于零、空字符串或 false。不同空值语义会影响查询、统计、比较和业务判断。例如“未填写手机号”和“用户没有手机号”可能是不同状态;“折扣为零”和“折扣未知”也不能混淆。
使用空值会引入三值逻辑:真、假和未知。对空值的比较、聚合和连接要遵循数据库规则。设计时应明确字段是否允许空值、缺失原因和默认值,避免用一个字段承载多个含义。对关键标识、金额、状态和审计字段通常应采用非空和明确默认策略。
七、关系之间的联系
实体之间常见一对一、一对多和多对多关系。一对一关系可以合并或拆分,取决于生命周期、权限、访问频率和可选性;一对多关系通常在“多”端保存外键;多对多关系要建立联系关系,并可在联系关系中保存数量、角色、时间和状态等属性。
例如订单与商品是多对多关系,订单明细不只是连接表,还应保存成交数量、成交价、优惠金额和税率。把这些属性放在订单或商品表会破坏语义,造成重复和更新异常。
关系基数和可选性要在概念模型中明确。一个订单是否必须有客户?一个订单至少包含一条明细吗?员工可以没有部门吗?这些规则决定外键是否可空、是否需要检查和何时允许删除。
八、关系数据库的架构价值
关系模型提供结构化和约束能力,适合订单、财务、库存、用户、权限和配置等需要明确规则与事务的业务。通过主键和外键可以建立追踪,通过约束减少非法状态,通过事务保证一组更新的原子性,通过 SQL 支持多种查询和报表。
但是关系模型不等于“所有数据必须一张表”或“所有关系都要强外键”。跨服务数据库共享、超大规模分片和高频异步场景可能需要服务边界、事件、应用级一致性和专门的存储结构。架构师要明确哪些约束在同一数据库事务内,哪些通过消息、幂等、对账和补偿实现。
九、常见设计陷阱
第一,使用姓名、手机号等可变属性作为主键,修改后产生级联风险;第二,只使用代理键却没有给业务唯一字段建立约束,导致重复客户或重复订单;第三,外键类型、长度和字符集不一致,造成关联失败或隐式转换;第四,把多个值用逗号放在一个字段,破坏原子性和查询能力;第五,用特殊值代替空值,统计和判断产生歧义;第六,删除主表记录时没有定义子表策略,出现悬挂数据;第七,应用和数据库对状态规则理解不同,产生非法状态;第八,依赖数据库自然顺序返回数据,分页和结果不稳定。
评审关系设计时应检查键的稳定性、唯一性、非空性、引用关系、空值语义、删除策略、历史保留、并发更新、索引需求和迁移策略。还要用真实数据和典型查询验证模型,不要只看表结构是否“整齐”。
十、案例分析:客户与订单表的重复和悬挂数据
某电商系统有三套客户表:订单系统保存客户姓名和手机号,营销系统保存会员等级,客服系统保存联系方式。三个系统都使用手机号作为客户标识,但手机号可以更换,也可能被家庭成员共享。系统迁移后出现同一客户多个编号,部分订单找不到客户,营销优惠错误发放。
问题分析
手机号不是稳定且全局唯一的客户主键,三个系统各自维护客户事实,导致数据冗余和口径不一致;订单缺少可靠的客户引用或迁移时外键映射不完整,产生悬挂记录;客户主数据所有权和变更流程没有明确。
改进方案
建立稳定的客户内部标识作为主键,手机号作为可变业务属性,并根据业务规则设置受控唯一性或历史表。建立客户主数据服务或明确权威系统,订单、营销和客服通过稳定标识引用;迁移前进行去重、匹配、人工确认和映射,迁移后执行对账。对客户状态、联系方式和会员关系明确生命周期,保留历史有效期。数据库层建立主键、外键和必要的唯一约束,跨系统变更通过事件、幂等和失败补偿同步。
十一、综合知识练习与详细答案
练习一
某订单表只有自增订单编号,没有客户外键,应用通过客户姓名查询客户。请指出问题。
参考答案:姓名可能重复、修改或存在不同写法,不能稳定标识客户;订单与客户之间缺少显式参照关系,数据库无法防止订单指向不存在的客户。应使用稳定客户标识作为订单外键,建立参照完整性和必要索引;客户姓名作为展示属性。若存在跨系统客户,需要先明确主数据和标识映射。
练习二
一个关系中把“商品编号列表”保存为逗号分隔字符串。为什么不合理?如何设计?
参考答案:该字段包含多个值,违反原子性,难以建立外键、查询单个商品、统计数量和保证重复约束,也容易出现格式错误。应拆分为订单和订单明细两个关系,订单明细保存订单编号、商品编号、数量、成交价等联系属性,并通过主键或唯一约束防止不合法重复。
练习三
删除客户时,系统应该拒绝删除、级联删除还是将订单客户置空?如何回答此类问题?
参考答案:不能脱离业务直接选择。若订单是财务和审计凭证,通常不能级联删除,应保留客户历史或做匿名化,必要时将客户标记为注销;若关系是纯临时数据,才可能级联。置空会丢失订单归属,也只有在业务允许且字段可空时适用。答题应说明数据生命周期、审计要求、参照完整性和法律合规,再确定删除、软删除、匿名化或转移策略。
十二、论文写作素材
论文中可以这样描述关系数据库设计:我先识别客户、订单、商品、库存和支付等实体及其生命周期,定义稳定的主键、候选键、外键和关系基数;对多对多关系建立联系表并保存联系属性;对金额、状态、时间和敏感字段明确域、精度、空值语义和业务约束。通过实体完整性、参照完整性和用户定义完整性将关键不变量落实到数据层和服务层。
为支持系统演进,我不使用可变业务属性替代主键,业务唯一性通过独立约束表达;将模式、数据字典、迁移脚本和索引纳入配置管理;对删除、归档、历史和注销采用可审计策略。事务内保证核心一致性,跨服务场景通过消息、幂等、补偿和对账实现最终一致。上线前使用真实规模数据验证查询、并发、迁移、恢复和权限,持续监控数据质量、孤儿记录、重复数据和约束异常。
十三、今日复盘
关系数据库的基本概念要围绕“结构、标识、关联、约束”记忆:域定义取值范围,属性描述特征,元组表示实例,关系组织同类元组,关系模式描述结构;候选键是最小唯一标识,主键是选定的候选键,外键表达引用关系;实体完整性保证主键有效,参照完整性保证引用有效,用户定义完整性保证业务规则。
设计时特别注意主键稳定、业务唯一性、空值语义、多对多联系和删除策略。关系模型的优势是结构和约束清晰,架构价值在于维护可信数据状态;但跨服务和大规模场景要重新划分事务和一致性边界。
记忆主线:
关系由属性和元组构成,键负责识别和关联,约束负责阻止非法状态;表结构服务于业务语义,而不是只追求形式整齐。
下一篇进入 6.2.2 关系运算,学习选择、投影、连接、并、差、笛卡尔积及其在查询和架构分析中的意义。