河南工业大学实验报告
课程 数据库系统原理及应用_ 实验名称: 实验三 数据完整性实验
院 系____++信息科学与工程学院++ ____ 专业班级__++物联网2303++
姓 名++杜子健 _++ 学 号++231040700302++
指导老师:++张梦雅++ 日 期++2025-11-26++
- 实验目的
- 熟练掌握表的建立和数据完整性速描定义方法,实践DBMS提供的数据完整性功能,加深对数据完整性的理解。
- 用CREATE TABLE命令建立表并定义数据完整性约束,并用ALTER TABLE命令修改表结。
- 结合具体例子能真正掌握主键和外键的概念。
- 实验内容
- 实体完整性的定义和维护方法。
- 参照完整性的定义和维护方法。
- 用户自定义完整性的定义和维护方法。
- 实验要求、过程及结果
参照下图建立要求的"粮食物资厂库管理系统数据库"及其对应的表,并定义表的完整性约束,要求:


1、使用Create table命令建立该数据库的表,并按照表格要求定义各个表的完整性约束;
2、使用Alter table命令按如下要求修改表结构:
a)为订购单增加一个新的字段"交付日期",类型为日期时间型,默认是空值。
b)为订单明细表的"数量"字段重新定义约束:大于0,小于等于3000的正整数,不允许为空值。
c)将供应商表的供应商名字段的类型修改为varchar(50)。
3、请自行设计SQL语句验证完整性约束是否起作用。
(一)实验前提:明确 "粮食物资厂库管理系统数据库" 表结构
根据实验要求,系统包含以下核心表(字段、类型、约束说明如下):
|------------------|-----------------|--------------|-----------------------------------------------------------|
| 表名 | 字段名 | 数据类型 | 完整性约束要求 |
| 供应商表(Supplier) | 供应商编号(SupID) | CHAR(6) | 主键(实体完整性),非空 |
| | 供应商名称(SupName) | VARCHAR(30) | 非空(用户自定义完整性) |
| | 联系电话(Phone) | CHAR(11) | 无 |
| 粮食品种表(Grain) | 品种编号(GrainID) | CHAR(8) | 主键(实体完整性),非空 |
| | 品种名称(GrainName) | VARCHAR(20) | 非空(用户自定义完整性),唯一(用户自定义完整性) |
| | 单价(Price) | DECIMAL(8,2) | 大于 0(用户自定义完整性) |
| 仓库表(Warehouse) | 仓库编号(WHID) | CHAR(4) | 主键(实体完整性),非空 |
| | 仓库名称(WHName) | VARCHAR(20) | 非空(用户自定义完整性) |
| | 存储容量(Capacity) | INT | 大于 0(用户自定义完整性) |
| 订购单表(Order) | 订单编号(OrderID) | CHAR(10) | 主键(实体完整性),非空 |
| | 供应商编号(SupID) | CHAR(6) | 外键(参照 Supplier 表的 SupID,参照完整性) |
| | 订购日期(OrderDate) | DATE | 非空(用户自定义完整性) |
| 订单明细表(OrderItem) | 明细 ID(ItemID) | INT | 主键(实体完整性),自增(方便插入) |
| | 订单编号(OrderID) | CHAR(10) | 外键(参照 Order 表的 OrderID,参照完整性) |
| | 品种编号(GrainID) | CHAR(8) | 外键(参照 Grain 表的 GrainID,参照完整性) |
| | 数量(Quantity) | INT | 非空,大于 0(用户自定义完整性,后续需用 ALTER TABLE 修改约束为 0<Quantity≤3000) |
(二)实验步骤 1:使用 CREATE TABLE 命令建立表并定义完整性约束
1. 创建数据库
首先创建实验用数据库,避免与其他数据库冲突:
|------------------------------------------------------------------------------------------------------------|
| CREATE DATABASE GrainManagementSystem DEFAULT CHARACTER SET utf8mb4; USE GrainManagementSystem; -- 切换到该数据库 |
2. 按顺序创建表(先创建无外键的表,再创建有外键的表,避免参照错误)
(1)创建供应商表(Supplier)------ 无外键
|------------------------------------------------------------------------------------------------------------------------------------------|
| CREATE TABLE Supplier ( SupID CHAR(6) PRIMARY KEY, -- 实体完整性:主键约束(唯一+非空) SupName VARCHAR(30) NOT NULL, -- 用户自定义完整性:非空约束 Phone CHAR(11) ); |
(2)创建粮食品种表(Grain)------ 无外键
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| CREATE TABLE Grain ( GrainID CHAR(8) PRIMARY KEY, -- 实体完整性:主键约束 GrainName VARCHAR(20) NOT NULL UNIQUE, -- 用户自定义完整性:非空+唯一约束 Price DECIMAL(8,2) CHECK (Price > 0) -- 用户自定义完整性:检查约束(单价>0) ); |
(3)创建仓库表(Warehouse)------ 无外键
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| CREATE TABLE Warehouse ( WHID CHAR(4) PRIMARY KEY, -- 实体完整性:主键约束 WHName VARCHAR(20) NOT NULL, -- 用户自定义完整性:非空约束 Capacity INT CHECK (Capacity > 0) -- 用户自定义完整性:检查约束(容量>0) ); |
(4)创建订购单表(Order)------ 含外键(参照供应商表)
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| CREATE TABLE `Order` ( -- Order是MySQL关键字,需用反引号包裹 OrderID CHAR(10) PRIMARY KEY, -- 实体完整性:主键约束 SupID CHAR(6) NOT NULL, -- 外键依赖字段,非空 OrderDate DATE NOT NULL, -- 用户自定义完整性:非空约束 -- 参照完整性:外键约束(SupID参照Supplier表的SupID) FOREIGN KEY (SupID) REFERENCES Supplier(SupID) ); |
(5)创建订单明细表(OrderItem)------ 含多个外键
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| CREATE TABLE OrderItem ( ItemID INT PRIMARY KEY AUTO_INCREMENT, -- 实体完整性:主键自增(避免手动输入重复) OrderID CHAR(10) NOT NULL, -- 外键依赖字段,非空 GrainID CHAR(8) NOT NULL, -- 外键依赖字段,非空 Quantity INT NOT NULL, -- 临时非空约束,后续需修改检查条件 -- 参照完整性:外键约束(OrderID参照Order表的OrderID) FOREIGN KEY (OrderID) REFERENCES `Order`(OrderID), -- 参照完整性:外键约束(GrainID参照Grain表的GrainID) FOREIGN KEY (GrainID) REFERENCES Grain(GrainID) ); |
(三)实验步骤 2:使用 ALTER TABLE 命令修改表结构
1. 为订购单表(Order)增加 "交付日期" 字段
|-----------------------------------------------------------------------------|
| ALTER TABLE `Order` ADD COLUMN 交付日期 DATE NULL DEFAULT NULL; -- 日期时间型,默认空值 |
2. 为订单明细表(OrderItem)的 "数量" 字段重新定义约束
|-------------------------------------------------------------------------------------------------------------------------|
| ALTER TABLE OrderItem MODIFY COLUMN Quantity INT NOT NULL CHECK (Quantity > 0 AND Quantity <= 3000); -- 0<数量≤3000,非空 |
3. 修改供应商表(Supplier)的 "供应商名称" 字段类型
|--------------------------------------------------------------------------------------|
| ALTER TABLE Supplier MODIFY COLUMN SupName VARCHAR(50); -- 从VARCHAR(30)改为VARCHAR(50) |
(四)实验步骤 3:设计 SQL 语句验证完整性约束是否起作用
1. 验证实体完整性(主键约束)
|----------------------------------------------------------------------------------------------|
| INSERT INTO Supplier (SupID, SupName, Phone) VALUES ('S00001', '河南粮食贸易有限公司', '13800138000'); |
|--------------------------------------------------------------------------------------------|
| INSERT INTO Supplier (SupID, SupName, Phone) VALUES ('S00001', '郑州粮油配送中心', '13900139000'); |
|---------------------------------------------------------------------------------------|
| INSERT INTO Supplier (SupID, SupName, Phone) VALUES (NULL, '洛阳粮食加工厂', '13700137000'); |
2. 验证参照完整性(外键约束)
|---------------------------------------------------------------------------------------------------------------|
| INSERT INTO `Order` (OrderID, SupID, OrderDate, 交付日期) VALUES ('O2025112601', 'S00001', '2025-11-26', NULL); |
|-----------------------------------------------------------------------------------------------------------------------|
| INSERT INTO `Order` (OrderID, SupID, OrderDate, 交付日期) VALUES ('O2025112602', 'S99999', '2025-11-26', '2025-12-01'); |
3. 验证用户自定义完整性(非空、检查约束)
|---------------------------------------------------------------------------------|
| INSERT INTO Grain (GrainID, GrainName, Price) VALUES ('G20250001', '小麦', -2.5); |
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| -- 先插入合法粮食品种 INSERT INTO Grain (GrainID, GrainName, Price) VALUES ('G20250001', '小麦', 2.5); -- 插入非法数量的订单明细 INSERT INTO OrderItem (OrderID, GrainID, Quantity) VALUES ('O2025112601', 'G20250001', 3001); |
|--------------------------------------------------------------------------------------|
| INSERT INTO Supplier (SupID, SupName, Phone) VALUES ('S00002', NULL, '13600136000'); |




(五)最终表结构确认
执行以下 SQL 查看所有表结构,确认约束均已正确定义:
|---------------------------------------------------------------------------------------------------------|
| -- 查看表结构 DESCRIBE Supplier; DESCRIBE Grain; DESCRIBE Warehouse; DESCRIBE `Order`; DESCRIBE OrderItem; |

五、实验中的问题及心得
数据完整性是数据库设计的核心,实体完整性(主键)保证了数据的唯一性,参照完整性(外键)保证了表之间的关联一致性,用户自定义完整性则满足了具体业务需求,三者缺一不可,能有效避免脏数据的产生。
创建表时需注意顺序:必须先创建被参照的表(如 Supplier、Grain),再创建参照表(如 Order、OrderItem),否则外键约束无法建立;同时要避免使用数据库关键字作为表名 / 字段名,如需使用需用反引号包裹。
ALTER TABLE 命令功能强大,但修改表结构时需谨慎,尤其是修改字段类型或删除约束时,可能影响已存储的数据;修改外键或检查约束前,需先确保现有数据符合新约束,否则会修改失败。
通过本次实验,我不仅熟练掌握了 CREATE TABLE 和 ALTER TABLE 的使用方法,更深刻理解了主键和外键的实际意义 ------ 主键是表的 "唯一标识",外键是表之间的 "桥梁",合理设计完整性约束能让数据库更稳定、更可靠。
验证约束的过程很重要,只有通过正反例测试(合法数据插入成功,非法数据插入失败),才能确认约束真正生效,这也培养了我严谨的实验态度。