2.3 表间关系与参照完整性


2.3 表间关系与参照完整性

本节摘要:Access 支持一对多、一对一、多对多三种关系;启用"实施参照完整性"后,引用不存在的客户这类孤儿记录会被引擎当场拒收。本节讲清三种关系的建立姿势、联接字段配对规则,以及级联更新删除的使用纪律。

单表各自精彩,多表咬合成系统。这一节把第 2.2 节定稿的四张表连成网络,并给这张网装上保险丝。

一、关系窗口初体验

操作路径简单得不像话:数据库工具选项卡里点开"关系",把客户、订单、订单明细、货品四张表拖进画布,从客户表的 ID 字段按住拖到订单表的客户 ID 字段上松手,弹出的对话框勾选"实施参照完整性",一条关系的丝带就挂上了:一端是 1,另一端是无限符号。

但界面越是傻瓜,背后的决定越要心里有数。拖线之前先回答三个问题:

  • 两端各是什么对应比例? 一个客户多个订单是一对多;一个员工一枚工牌是一对一;学生选课程是多对多。
  • 联接字段类型一致吗? 主键是自动编号(长整型数字),外键就必须是长整型数字。一个是数字一个是文本,看起来连线成功,查询时却匹配不上任何行——这是排错榜第一名。
  • 要不要级联? 级联更新让主键改动自动同步所有外键(用自动编号后几乎用不上);级联删除则是危险开关,删客户连带清掉他全部订单,慎之又慎。

二、三种关系逐个过

一对多:九成关系的形态,客户对订单、订单对明细、部门对员工都是它。建立口诀只有一句——"多方藏一把单方的钥匙"。订单表里的客户 ID 就是那把钥匙(外键)。

一对一:通常出现在两种场合。其一是垂直拆分保密敏感列或超大字段,把并非人人该看的薪酬列拆出附属表;其二是一表一档的档案场景。实现方式就是两张表的主键互为外键且设为唯一索引。

多对多:现实中最绕但也最常见的形态。货品和供应商之间不能直接连线——一家供应商供多种货,一种货由多家供货。标准解法是在中间架一张连接表(进货表),让"货品对进货"和"供应商对进货"都是一对多,两个一对多拼出一个受控的多对多。没有中间表的 多对多 要么靠逗号拼接字段硬凑,要么靠复制粘贴维护幽灵数据,都是定时炸弹。

三、参照完整性:引擎层的守门员

启用参照完整性的意义说穿了就两句话:

  • 插不进无主之行——订单的客户 ID 若在客户表中查无此人,写入直接被拒绝;
  • 删不掉被引之人——有人还想引用这个客户时,你不允许无声无息地把他抹掉。

这层防护的珍贵之处在于它不依赖使用者自觉。窗体忘了写校验、VBA 代码出了 bug、甚至有人绕开程序直接改表,引擎都在最后一道关口兜底。我们对比一下有没有这道闸的行为差异:

场景:新订单录入 客户ID = 2088 而客户表最大ID为1024 未启用参照完整性: 订单照常写入。月底统计时 该行找不到客户信息 汇总报表出现一行"空名客户" 数据可信度受损 已启用参照完整性: 弹出提示 由于数据表需要相关记录 无法添加或修改 录入者当场发现选错了客户 从源头杜绝脏数据

图题:参照完整性作为最后一道关卡的拦截示意

图题:参照完整性作为最后一道关卡的拦截示意

四、实战坑位提醒

坑一:先建了数据再补关系。 表里已经躺着违反规则的旧数据,此时想启用参照完整性会被拒绝。正确顺序永远是先立规矩再灌数据;万一中招,先用查找不匹配项查询揪出违规行清理干净,再回来启用。

坑二:以为不用 Access 界面就能绕过约束。 恰恰相反,参照完整性设在引擎层,SQL 视图、链接表、外部程序写进来一样被拦。它是最诚实的一层防线。

坑三:滥用级联删除图省事。 销毁证据式的便利迟早反噬。华彩案例里我们的约定是:业务流水一律禁止物理删除,只做作废标记——留痕的需求,比少点几下鼠标重要得多。

五、顺手演练:揪出现有库里的孤儿记录

接手一个没立规矩的旧库时,第一件事就是体检有没有孤儿。Access 的"查找不匹配项"向导能自动生成查询,但读懂它的 SQL 更值钱——以订单表找无主订单为例:

-- 左侧主表取全部行 右侧配不上的一律 NULL 就是被抛弃的孤儿 SELECT o.OrderID, o.OrderNo, o.CustomerID FROM tblOrder AS o LEFT JOIN tblCustomer AS c ON o.CustomerID = c.CustomerID WHERE c.CustomerID Is Null;

两条常见追问顺带答掉。问:关系线和联接类型是什么关系? 关系线管的是写入时的完整性,联接类型(内联接、左外联接)管的是读取时怎么配对;在编辑关系对话框里把联接类型改成"包含所有记录",查询默认就按外联接走,两者共用这条线的定义但各管一段。问:临时数据表要不要也建关系? 导入暂存的中转表不必——它只活一次清理作业的时间,建约束反而碍事;真正需要关系的是长期存活的正式表。

六、把关系网画成活的文档

关系窗口本身值得一点经营性投入。华彩的做法是每月截一张关系图存进交接文件夹——不是截屏完事,而是先把窗口按业务域整理分区(主数据区、流水区、辅助区各自成块再连线),浏览的人顺着布局就能读懂业务分层。凌乱的关系窗和清爽的关系窗承载着同一套约束,但给接手者的信息量天差地别。

另一个小习惯:临时导入表用统一前缀命名并定期清理,绝不让它们混进正式关系网。空降的孤儿表不只是难看——有同事曾把历史上遗留的旧年份表误当成可用的关联源接进查询,结果报表口径悄悄错了半年。可见性管理就是正确性管理的一部分。

本节要点回顾

  • 关系窗口拖线三问:对应比例、类型配对、是否级联;类型不一致是联接失效的头号元凶。
  • 多对多必须落成连接表方案,两个一对多组合而成。
  • 参照完整性挡住孤儿记录与误删被引记录,且不受录入渠道影响。
  • 级联更新基本不需要,级联删除默认关掉;业务流水以作废标记代替物理删除。

到此核心三张表的网络已立起来了。不过团队协作还需要工程化的约定——命名规范与数据字典,下一节见。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U