实验三 数据完整性实验

河南工业大学实验报告

课程 数据库系统原理及应用_ 实验名称: 实验三 数据完整性实验

院 系____++信息科学与工程学院++ ____ 专业班级__++物联网2303++

姓 名++杜子健 _++ 学 号++231040700302++

指导老师:++张梦雅++ 日 期++2025-11-26++

  • 实验目的
    1. 熟练掌握表的建立和数据完整性速描定义方法,实践DBMS提供的数据完整性功能,加深对数据完整性的理解。
    2. 用CREATE TABLE命令建立表并定义数据完整性约束,并用ALTER TABLE命令修改表结。
    3. 结合具体例子能真正掌握主键和外键的概念。
  • 实验内容
    1. 实体完整性的定义和维护方法。
    2. 参照完整性的定义和维护方法。
    3. 用户自定义完整性的定义和维护方法。
  • 实验要求、过程及结果

参照下图建立要求的"粮食物资厂库管理系统数据库"及其对应的表,并定义表的完整性约束,要求:

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 的使用方法,更深刻理解了主键和外键的实际意义 ------ 主键是表的 "唯一标识",外键是表之间的 "桥梁",合理设计完整性约束能让数据库更稳定、更可靠。

验证约束的过程很重要,只有通过正反例测试(合法数据插入成功,非法数据插入失败),才能确认约束真正生效,这也培养了我严谨的实验态度。

相关推荐
2501_901200531 小时前
Golang如何做Clean Architecture_Golang整洁架构教程【详解】
jvm·数据库·python
韶博雅1 小时前
oracle + parfile(数据泵)
数据库·oracle
weixin_459753941 小时前
Go 中嵌入类型字段在派生结构体字面量中的初始化规则详解
jvm·数据库·python
CLX05051 小时前
HTML5中Mediastream实现摄像头画面实时捕获
jvm·数据库·python
Hello.Reader1 小时前
算法基础(十三)——随机算法为什么有时主动引入随机性
java·数据库·算法
iAm_Ike1 小时前
PHP错误和异常如何处理_PHP错误与异常处理机制详解【详解】
jvm·数据库·python
m0_631529821 小时前
宝塔面板安装后无法修改配置文件_处理chattr锁定属性
jvm·数据库·python
NineData1 小时前
NineData智能数据管理平台新功能发布|2026年4月
数据库·ninedata·玖章算术
dFObBIMmai1 小时前
Go语言怎么用GitHub Actions_Go语言GitHub Actions教程【基础】
jvm·数据库·python