简介:这份文档资料是Access自带的经典示例数据库——罗斯文数据库的完整学习教程,面向数据库入门者、Access自学者以及需要理解关系型数据库设计思路的开发者。它以虚构的罗斯文商贸公司为业务背景,围绕食品采购与销售流程,系统讲解表、关系、查询、报表、窗体、切换面板等核心对象。资源包共1个doc文件,约3.58MB,内容以图文并茂的连载形式展开,涵盖表设计思路、数据类型用法、字段属性设置,以及供应商表、类别表、产品表等具体表的分析,并重点介绍查阅列、索引、有效性规则等实用技巧。已有818人学习,适合希望从实例中掌握数据库建模与Access操作、对照练习并查漏补缺的读者参考。
1. 罗斯文数据库:一个被低估的 Access 学习样本
很多人第一次打开 Access 自带的罗斯文数据库时,反应是「就这?」——一个卖食品的虚构公司,几张订单表,几个查询,看起来平平无奇。但如果你正在学表设计、查询或者准备用 Access 做一套小型业务系统,罗斯文其实是一个被严重低估的练手样本。它把「客户-订单-订单明细-产品-供应商-类别-员工」这条典型业务链完整搭了出来,表与表之间的主外键关系、复合主键、计算字段、汇总查询、参数查询全都有现成例子。换句话说,你不需要自己从零设计一个业务场景,就能直接在一个结构完整、数据量适中的库上练习表设计和查询。这篇文章面向两类人:一是刚接触 Access、想找一个能直接上手的示例库的新手;二是用过 Access 但没认真拆过罗斯文结构、想借它理解关系型数据库设计思路的从业者。接下来我会从罗斯文的结构拆解讲起,再落到怎么用它练表设计、写查询、避坑,最后给一个进阶技巧。
2. 拆开罗斯文:表结构与关系设计的真实意图
2.1 八张核心表各自承担什么角色
罗斯文数据库的核心表大致可以分成三类。第一类是主数据表:Customers(客户)、Products(产品)、Suppliers(供应商)、Categories(类别)、Employees(员工)、Shippers(承运商)。这些表存的是相对稳定的业务实体信息,每条记录代表一个对象。第二类是业务流水表:Orders(订单)和Order Details(订单明细)。这两张表记录的是随时间不断产生的交易数据。第三类是辅助表,比如Customers里嵌的客户类型字段、Products里的库存状态字段,这些在罗斯文里没有单独建表,而是用字段值区分。
理解这个分类很重要,因为它直接决定了你后面建表时的思路:主数据表通常用单一主键(比如CustomerID、ProductID),业务流水表则要考虑复合主键。罗斯文里Order Details用的就是OrderID + ProductID的复合主键,这个设计不是随便定的——同一个订单里同一个产品只应该出现一次,复合主键天然保证了这一点。
2.2 主键、外键和复合主键在罗斯文里怎么落地
打开Order Details表的设计视图,你会看到OrderID和ProductID两个字段前面都有钥匙图标,这就是复合主键。同时OrderID又是指向Orders表的外键,ProductID是指向Products表的外键。这种「既是主键一部分又是外键」的字段,在订单明细这种场景里非常典型。
罗斯文里还有一个容易被忽略的细节:Orders表里的CustomerID、EmployeeID、ShipVia都是外键,分别指向Customers、Employees、Shippers。这意味着一条订单记录同时关联了三个主数据表。你在做查询的时候,如果要显示客户名称、员工姓名和承运商名称,就需要三次 JOIN。很多新手写查询时只 JOIN 一两次就晕了,罗斯文正好提供了这种多级关联的练习场景。
提示:在 Access 的关系窗口里,你可以直接拖拽字段建立外键关系,但要注意勾选「实施参照完整性」,否则外键约束不会生效。
2.3 用关系窗口验证你的理解
打开「数据库工具」选项卡里的「关系」按钮,你会看到罗斯文的完整关系图。建议你按以下步骤自己走一遍:
第一步,找到Orders表,观察它伸出了几条关系线。正常应该有三条:连向Customers、Employees、Shippers。
第二步,找到Order Details表,观察它和Orders、Products的关系。这里的关系线是「一对多」还是「多对多」?实际上Order Details作为中间表,把Orders和Products之间的多对多关系拆成了两个一对多。
第三步,双击任意一条关系线,查看「编辑关系」对话框里的选项。你会看到「实施参照完整性」「级联更新相关字段」「级联删除相关记录」三个勾选框。罗斯文默认勾了参照完整性,但没有勾级联删除——这是有意的,因为订单明细不应该因为删了一个产品就被自动删掉。
这个验证过程看起来简单,但很多人用 Access 几年都没认真看过关系窗口。花十分钟走一遍,你对关系型数据库的理解会比看十篇教程都扎实。
3. 用罗斯文练表设计:从模仿到改造
3.1 照着罗斯文的结构建一张自己的表
学表设计最快的方式不是从头想,而是找一个现成的结构改。假设你要做一个图书管理的小系统,可以照着Products表的结构来建一张Books表。Products表里有ProductID(自动编号主键)、ProductName(短文本)、SupplierID(数字,外键)、CategoryID(数字,外键)、QuantityPerUnit(短文本)、UnitPrice(货币)、UnitsInStock(数字)、UnitsOnOrder(数字)、ReorderLevel(数字)、Discontinued(是/否)。对应到图书,就是BookID、BookName、PublisherID、CategoryID、Spec、Price、StockQty、OnOrderQty、ReorderLevel、Discontinued。
在 Access 里建表的操作步骤:
-- 在 Access 的 SQL 视图中可以直接执行建表语句 CREATE TABLE Books ( BookID AUTOINCREMENT PRIMARY KEY, BookName TEXT(100) NOT NULL, PublisherID INTEGER, CategoryID INTEGER, Spec TEXT(50), Price CURRENCY, StockQty INTEGER DEFAULT 0, OnOrderQty INTEGER DEFAULT 0, ReorderLevel INTEGER DEFAULT 10, Discontinued YESNO DEFAULT NO );这段 SQL 里几个关键点:AUTOINCREMENT对应 Access 的自动编号类型,TEXT(100)指定字段长度,CURRENCY是货币类型,YESNO是是/否类型。DEFAULT给字段设默认值,StockQty默认 0、ReorderLevel默认 10,这样新增记录时不用每次手填。注意 Access 的 SQL 方言和标准 SQL 有差异,比如AUTOINCREMENT在 SQL Server 里是IDENTITY,在 MySQL 里是AUTO_INCREMENT,不要混用。
建完表之后,打开设计视图检查字段类型是否正确。特别是Price字段,如果误设成DOUBLE而不是CURRENCY,后面做金额汇总时可能出现浮点误差。罗斯文里所有金额字段用的都是货币类型,这个细节值得学。
3.2 索引和字段属性怎么设才不拖后腿
罗斯文里Products表的ProductName字段设了索引(有重复),Customers表的CompanyName也设了索引。索引的作用是加快查询速度,但不是什么字段都该设。经验规则是:经常出现在 WHERE 条件、JOIN 关联字段、ORDER BY 排序里的字段,考虑加索引;频繁更新的字段、值重复率极高的字段(比如性别只有两三个值),加索引反而拖慢写入。
在 Access 设计视图里设索引的步骤:打开表设计视图,选中字段,在下方的「常规」选项卡里找到「索引」属性,改成「有(有重复)」或「有(无重复)」。主键字段自动是「有(无重复)」,外键字段一般设「有(有重复)」。
字段属性里还有几个容易忽略但很实用的设置。格式属性控制显示格式,比如日期字段设成「短日期」显示为2024/1/1,设成「长日期」显示为2024年1月1日。输入掩码属性可以强制用户按固定格式输入,比如电话号码。验证规则属性可以在字段级别做数据校验,比如UnitPrice字段设>=0,防止录入负数价格。必填字段属性设成「是」时,该字段不允许为空。
罗斯文里Orders表的OrderDate字段设了默认值=Date(),意思是新增订单时自动填入当天日期。这个技巧在实际项目里很常用,能减少用户输入量。你可以在自己的表里照搬这个做法,把创建时间、订单日期这类字段设上默认值。
3.3 用查阅向导把外键字段变成下拉选择
罗斯文里Orders表的CustomerID字段在数据表视图里显示的是客户名称而不是 ID 数字,这是通过「查阅向导」实现的。查阅向导的本质是给字段设一个「查阅」属性,让它在显示时查另一张表的值。
操作步骤:在表设计视图里选中外键字段(比如CustomerID),在「数据类型」下拉里选「查阅向导」,然后按向导提示选择「我想让查阅列从表或查询中获取值」,接着选Customers表,选要显示的字段(比如CompanyName),设置排序,最后确认。完成后,数据表视图里这个字段就变成下拉框了。
这个功能的好处是录入数据时不用记 ID,直接选名称。但要注意一个坑:查阅向导只是在显示层做了转换,底层存的仍然是 ID 数字。如果你在查询里直接对这个字段做条件筛选,用的还是 ID 值,不是显示的名称。很多新手在这里翻车,以为存的是名称,结果查询条件写错了。
4. 在罗斯文上练查询:从单表到多表关联
4.1 用查询设计器写第一个多表查询
罗斯文自带了不少查询,但自己动手写一遍收获更大。假设你要查每个客户的订单总金额,需要用到Customers、Orders、Order Details三张表。在 Access 里点「创建」→「查询设计」,把这三张表加进来,Access 会自动识别它们之间的关系。如果关系没自动出现,手动拖拽Customers.CustomerID到Orders.CustomerID,拖拽Orders.OrderID到Order Details.OrderID。
然后双击字段列表里的CompanyName、OrderID、UnitPrice、Quantity、Discount,把它们加到下方的字段行。接着点「汇总」按钮(工具栏上的 Sigma 符号),把OrderID的「总计」行改成Group By,UnitPrice改成Sum,Quantity改成Sum。但这样算出来的金额不对,因为UnitPrice * Quantity * (1 - Discount)才是实际金额。Access 查询设计器里可以写表达式字段:
-- 在查询设计器的字段行里直接写表达式 SELECT Customers.CompanyName, Orders.OrderID, Sum(OrderDetails.UnitPrice * OrderDetails.Quantity * (1 - OrderDetails.Discount)) AS OrderTotal FROM (Customers INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID) INNER JOIN OrderDetails ON Orders.OrderID = OrderDetails.OrderID GROUP BY Customers.CompanyName, Orders.OrderID;这段 SQL 的关键在于Sum函数里的表达式。UnitPrice * Quantity * (1 - Discount)先算出每条明细的实际金额,再用Sum汇总到订单级别。GROUP BY后面跟的是非聚合字段。注意 Access 的 JOIN 嵌套写法需要用括号把前两个表的 JOIN 包起来,再和第三个表 JOIN,这是 Access SQL 的特殊语法,和 MySQL 的直接链式 JOIN 写法不同。
4.2 参数查询和交叉表查询在罗斯文里的用法
罗斯文里有一个「按季度统计销售额」的查询,用的是交叉表查询。交叉表查询可以把行数据转成列,适合做报表。比如你要看每个类别在每个季度的销售额,行是类别,列是季度,交叉点是汇总金额。
在 Access 里创建交叉表查询的步骤:点「创建」→「查询设计」→「交叉表查询」。然后把Categories.CategoryName拖到行位置,把Orders.OrderDate拖到列位置(用Format(OrderDate, 'q')提取季度),把金额表达式拖到值位置并选Sum。Access 会自动生成TRANSFORM ... PIVOT ...的 SQL。
参数查询则是在条件行里写[请输入客户名称]这样的提示文本。运行查询时会弹出输入框,用户输入的值会替换到条件里。罗斯文里有一个「按客户查订单」的查询就用了这个技巧。参数查询的坑在于:如果用户点了取消,查询会返回空结果而不是报错;如果输入的类型和字段类型不匹配,Access 会尝试隐式转换,转换失败时可能返回意外结果。所以参数查询适合内部使用,不适合做面向最终用户的界面。
4.3 用 SQL 视图直接写查询的注意事项
Access 的查询设计器虽然方便,但复杂查询还是直接写 SQL 更可控。点「创建」→「查询设计」,关闭弹出的表选择窗口,然后点左上角「SQL 视图」按钮,就可以直接写 SQL 了。
写 Access SQL 有几个和标准 SQL 不一样的地方需要记住。日期常量用#2024-01-01#而不是'2024-01-01'。字符串连接用&而不是+(+在遇到 NULL 时会返回 NULL,&会把 NULL 当空字符串处理)。通配符用*和?而不是%和_(不过在 ADO 或 DAO 里可以用%)。TOP关键字可以限制返回行数,比如SELECT TOP 10 * FROM Products。
还有一个容易踩的坑:Access 查询里如果用了GROUP BY,SELECT列表里的非聚合字段必须全部出现在GROUP BY里,否则 Access 会报错。这和 MySQL 的宽松模式不同,MySQL 在某些配置下允许不写全。写 Access 查询时养成习惯,先把GROUP BY字段列全,再检查SELECT列表。
5. 罗斯文使用中的避坑与排查
5.1 打开罗斯文提示「不可识别的数据库格式」
现象:双击罗斯文数据库文件,Access 弹出「不可识别的数据库格式」错误。
原因:罗斯文数据库有多个版本,早期版本是.mdb格式,Access 2007 之后是.accdb格式。如果你用高版本 Access 打开低版本文件,通常没问题;但用低版本 Access 打开高版本文件,就会报这个错。另外,如果文件在传输过程中损坏,也可能出现这个提示。
解决:先确认你的 Access 版本和文件格式是否匹配。如果是.accdb文件但你的 Access 是 2003,需要升级 Access 或找.mdb版本的罗斯文。如果格式匹配仍然报错,尝试用 Access 的「压缩和修复数据库」功能修复文件。还不行的话,新建一个空数据库,用「外部数据」→「导入」的方式把罗斯文里的表逐个导入。
5.2 查询结果里金额出现多位小数
现象:用查询汇总金额时,结果出现123.45000000001这样的浮点数误差。
原因:金额字段的数据类型设成了DOUBLE或SINGLE,这两种浮点类型在计算时会有精度损失。罗斯文里金额字段用的是CURRENCY类型,但如果你自己建表时选错了类型,就会出现这个问题。
解决:打开表设计视图,把金额字段的类型改成「货币」。如果表里已有数据,改类型时 Access 会提示可能丢失精度,确认即可。改完之后重新运行查询,金额应该显示为两位小数。如果还有问题,在查询里用Round(表达式, 2)强制保留两位。
5.3 外键字段显示为数字而不是名称
现象:在数据表视图里,CustomerID列显示的是ALFKI这样的代码,而不是Alfreds Futterkiste这样的公司名。
原因:查阅向导没有设置,或者设置后被清除了。罗斯文原版是设了查阅属性的,但如果你复制表结构时没复制查阅属性,或者手动改了字段类型,查阅就会失效。
解决:打开表设计视图,选中该字段,在「查阅」选项卡里检查「显示控件」是否设为「组合框」,「行来源」是否指向了正确的表和字段。如果查阅选项卡是空的,重新运行查阅向导。注意查阅属性是字段级别的,复制表时如果只复制了字段名和类型,查阅属性不会跟着复制。
5.4 删除主表记录时提示违反参照完整性
现象:想删除Customers表里的一条客户记录,Access 提示「无法删除或更改该记录,因为表'Orders'中需要相关记录」。
原因:这个客户在Orders表里有订单记录,外键约束阻止了删除。这是参照完整性在起作用,防止出现「孤儿订单」。
解决:如果确实要删除客户,先删除该客户的所有订单和订单明细,再删客户。或者在关系窗口里双击关系线,勾选「级联删除相关记录」,这样删客户时会自动删掉关联订单。但级联删除要慎用,删错了没法撤销。更稳妥的做法是给客户表加一个「是否活跃」字段,用逻辑删除代替物理删除。
5.5 查询运行速度越来越慢
现象:随着数据量增加,原本秒出的查询要等好几秒甚至更久。
原因:缺少索引、JOIN 字段类型不匹配、或者查询里用了函数导致索引失效。比如WHERE Format(OrderDate, 'yyyy') = '2024'这种写法,即使OrderDate有索引也用不上,因为函数作用在字段上,数据库无法直接利用索引。
解决:把函数移到条件值一侧,改成WHERE OrderDate >= #2024-01-01# AND OrderDate < #2025-01-01#。检查 JOIN 字段的两边类型是否一致,如果一边是文本一边是数字,Access 会做隐式转换,速度会慢很多。给常用的查询条件字段加索引。如果查询涉及多张大表,考虑先用一个查询筛选出小结果集,再基于这个查询做后续关联。
6. 把罗斯文改造成自己的业务原型
罗斯文最大的价值不是拿来直接用,而是拿来改。我自己的习惯是:每接一个小型管理系统的需求,先复制一份罗斯文,把表名和字段名改成业务对应的名称,保留表结构和关系,然后在这个基础上加字段、改查询。这样做的好处是关系设计不用从零想,查询也有现成模板可以改。
具体操作上,我一般会先做三件事。第一,把Customers改成业务里的「客户」或「会员」表,字段名改成中文拼音或英文缩写,但保留CustomerID作为主键。第二,把Products改成业务里的「商品」或「服务项目」表,Categories改成「分类」表。第三,把Orders和Order Details保留原结构,只改显示名称。这三步做完,一个业务原型的骨架就有了。
进阶一点的做法是用 Access 的「数据库拆分」功能,把表放到后端数据库(可以是另一个 Access 文件,也可以是 SQL Server),前端只留查询、窗体和报表。这样多人可以同时使用,数据也更安全。拆分之后,罗斯文里的查询大部分还能直接用,只需要把表名改成链接表的名称。
验证改造是否成功的方法很简单:往主数据表里录几条测试数据,然后走一遍「新增订单→添加明细→查询汇总」的完整流程。如果每一步都能正常走通,说明表结构和关系没问题。如果某一步报错,大概率是外键关系没设对,回到关系窗口检查。
我踩过最深的坑是:改字段名的时候只改了表设计里的名称,忘了改查询和窗体里引用的名称,结果打开窗体就报「找不到字段」。后来养成了一个习惯:改字段名之前,先用「对象依赖项」功能查一下这个字段被哪些查询、窗体、报表引用了,改完之后逐个检查。这个习惯帮我省了很多后悔药。
希望帮到你。
本文还有配套的精品资源,点击获取