关系完整性约束是数据库设计中非常重要的概念,它们确保了数据的一致性和准确性。以下是关于关系完整性约束的详细介绍:
实体完整性 (Entity Integrity)
实体完整性规定了每个表都必须有一个主键,该主键用来唯一标识表中的每一行记录。这意味着:
- 主键不能为
NULL。 - 主键的值必须是唯一的。
示例
假设我们有一个名为 employees 的表,其中包含以下列:
employee_id(整数) - 主键first_name(字符串)last_name(字符串)department_id(整数)
为了定义 employee_id 作为主键,可以在创建表时使用如下 SQL 语句:
sql
CREATE TABLE employees (
employee_id INT PRIMARY KEY,
first_name VARCHAR(50),
last_name VARCHAR(50),
department_id INT
);
参照完整性 (Referential Integrity)
参照完整性确保了外键与主键之间的关联一致性。当一个表中的外键引用另一个表的主键时,必须遵守以下规则:
- 外键的值必须与另一个表中的主键值匹配。
- 或者外键的值可以是
NULL(如果允许NULL值的话)。
示例
如果我们有另一个名为 departments 的表,其中包含以下列:
department_id(整数) - 主键department_name(字符串)
我们可以定义 employees 表中的 department_id 列为外键,引用 departments 表的 department_id 主键:
sql
CREATE TABLE departments (
department_id INT PRIMARY KEY,
department_name VARCHAR(50)
);
CREATE TABLE employees (
employee_id INT PRIMARY KEY,
first_name VARCHAR(50),
last_name VARCHAR(50),
department_id INT,
FOREIGN KEY (department_id) REFERENCES departments(department_id)
);
在这个例子中,如果尝试插入一个不存在于 departments 表中的 department_id 值到 employees 表中,将会违反参照完整性规则,并导致错误。
域完整性 (Domain Integrity)
域完整性指的是对于表中列的值的约束,包括但不限于:
- 数据类型
- 格式
- 长度
- 取值范围
- 默认值
- 是否允许
NULL值
示例
假设我们想要限制 employees 表中的 first_name 和 last_name 字段只能包含字母,并且长度不超过 50 个字符,可以这样定义:
sql
CREATE TABLE employees (
employee_id INT PRIMARY KEY,
first_name VARCHAR(50) NOT NULL CHECK (first_name ~ '^[A-Za-z ]+$'),
last_name VARCHAR(50) NOT NULL CHECK (last_name ~ '^[A-Za-z ]+$'),
department_id INT,
FOREIGN KEY (department_id) REFERENCES departments(department_id)
);
在这个例子中,CHECK 约束使用正则表达式来验证 first_name 和 last_name 是否只包含字母和空格。
通过这些完整性约束,我们可以确保数据库中的数据保持一致性和有效性,从而避免了许多潜在的数据问题。
这次我们将使用一个新的案例来说明如何在数据库设计中应用关系完整性约束。假设我们正在为一家在线书店设计一个简单的数据库系统。
在线书店数据库案例
目标
- 设计一个能够支持基本书籍销售功能的数据库。
- 确保数据的完整性和一致性。
数据库设计
我们将设计以下表格:
- Books - 存储书籍信息。
- Authors - 存储作者信息。
- Publishers - 存储出版商信息。
- Orders - 存储订单信息。
- Order_Items - 存储订单中的书籍详情。
表格结构
-
Books
book_id(INT, Primary Key, Auto Increment)title(VARCHAR)author_id(INT, Foreign Key referencing Authors(author_id))publisher_id(INT, Foreign Key referencing Publishers(publisher_id))price(DECIMAL)publication_date(DATE)
-
Authors
author_id(INT, Primary Key, Auto Increment)name(VARCHAR)bio(TEXT)
-
Publishers
publisher_id(INT, Primary Key, Auto Increment)name(VARCHAR)location(VARCHAR)
-
Orders
order_id(INT, Primary Key, Auto Increment)customer_name(VARCHAR)order_date(DATE)
-
Order_Items
order_item_id(INT, Primary Key, Auto Increment)order_id(INT, Foreign Key referencing Orders(order_id))book_id(INT, Foreign Key referencing Books(book_id))quantity(INT)price(DECIMAL)
实体完整性 (Entity Integrity)
实体完整性要求每个表都有一个主键来唯一标识每一条记录。
示例
对于 Books 表,book_id 是主键,因此:
- 每本书都有一个唯一的
book_id。 book_id不能为空。
对于 Authors 表,author_id 是主键,因此:
- 每个作者都有一个唯一的
author_id。 author_id不能为空。
对于 Publishers 表,publisher_id 是主键,因此:
- 每个出版商都有一个唯一的
publisher_id。 publisher_id不能为空。
对于 Orders 表,order_id 是主键,因此:
- 每个订单都有一个唯一的
order_id。 order_id不能为空。
对于 Order_Items 表,order_item_id 是主键,因此:
- 每个订单项都有一个唯一的
order_item_id。 order_item_id不能为空。
参照完整性 (Referential Integrity)
参照完整性确保了外键与主键之间的关联一致性。
示例
对于 Books 表,author_id 和 publisher_id 分别是外键,因此:
author_id必须与Authors表中的某个author_id匹配。publisher_id必须与Publishers表中的某个publisher_id匹配。
对于 Order_Items 表,order_id 和 book_id 分别是外键,因此:
order_id必须与Orders表中的某个order_id匹配。book_id必须与Books表中的某个book_id匹配。
域完整性 (Domain Integrity)
域完整性定义了列的有效值范围或格式。
示例
对于 Books 表:
price必须是非负数值。publication_date必须是一个有效的日期。
对于 Authors 表:
name必须是非空字符串。
对于 Publishers 表:
name必须是非空字符串。
对于 Orders 表:
order_date必须是一个有效的日期。
对于 Order_Items 表:
quantity必须是非负整数。price必须是非负数值。
创建表的 SQL 语句示例
以下是创建这些表的 SQL 语句示例:
sql
CREATE TABLE Authors (
author_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
bio TEXT
);
CREATE TABLE Publishers (
publisher_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
location VARCHAR(255)
);
CREATE TABLE Books (
book_id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
author_id INT,
publisher_id INT,
price DECIMAL(10, 2) NOT NULL,
publication_date DATE NOT NULL,
FOREIGN KEY (author_id) REFERENCES Authors(author_id),
FOREIGN KEY (publisher_id) REFERENCES Publishers(publisher_id)
);
CREATE TABLE Orders (
order_id INT AUTO_INCREMENT PRIMARY KEY,
customer_name VARCHAR(255) NOT NULL,
order_date DATE NOT NULL
);
CREATE TABLE Order_Items (
order_item_id INT AUTO_INCREMENT PRIMARY KEY,
order_id INT,
book_id INT,
quantity INT NOT NULL,
price DECIMAL(10, 2) NOT NULL,
FOREIGN KEY (order_id) REFERENCES Orders(order_id),
FOREIGN KEY (book_id) REFERENCES Books(book_id)
);
这些完整性约束确保了数据的一致性和准确性,并有助于防止不一致的数据输入到数据库中。
这次我们将探讨一个关于大学课程管理系统的新案例,这个系统需要处理学生、教师、课程和成绩等信息。我们将重点关注如何在设计数据库时应用关系完整性约束。
大学课程管理系统案例
目标
- 管理学生的注册信息。
- 记录课程和教师的信息。
- 管理学生的成绩记录。
- 确保数据的完整性和一致性。
数据库设计
我们将设计以下表格:
- Students - 存储学生信息。
- Teachers - 存储教师信息。
- Courses - 存储课程信息。
- Enrollments - 存储学生选课信息。
- Grades - 存储学生的成绩记录。
表格结构
-
Students
student_id(INT, Primary Key, Auto Increment)first_name(VARCHAR)last_name(VARCHAR)email(VARCHAR, Unique)
-
Teachers
teacher_id(INT, Primary Key, Auto Increment)first_name(VARCHAR)last_name(VARCHAR)email(VARCHAR, Unique)
-
Courses
course_id(INT, Primary Key, Auto Increment)course_code(VARCHAR, Unique)course_name(VARCHAR)teacher_id(INT, Foreign Key referencing Teachers(teacher_id))
-
Enrollments
enrollment_id(INT, Primary Key, Auto Increment)student_id(INT, Foreign Key referencing Students(student_id))course_id(INT, Foreign Key referencing Courses(course_id))
-
Grades
grade_id(INT, Primary Key, Auto Increment)enrollment_id(INT, Foreign Key referencing Enrollments(enrollment_id))grade(DECIMAL)
实体完整性 (Entity Integrity)
实体完整性要求每个表都有一个主键来唯一标识每一条记录。
示例
-
对于
Students表,student_id是主键,因此:- 每个学生都有一个唯一的
student_id。 student_id不能为空。
- 每个学生都有一个唯一的
-
对于
Teachers表,teacher_id是主键,因此:- 每个教师都有一个唯一的
teacher_id。 teacher_id不能为空。
- 每个教师都有一个唯一的
-
对于
Courses表,course_id是主键,因此:- 每门课程都有一个唯一的
course_id。 course_id不能为空。
- 每门课程都有一个唯一的
-
对于
Enrollments表,enrollment_id是主键,因此:- 每次选课都有一个唯一的
enrollment_id。 enrollment_id不能为空。
- 每次选课都有一个唯一的
-
对于
Grades表,grade_id是主键,因此:- 每个成绩记录都有一个唯一的
grade_id。 grade_id不能为空。
- 每个成绩记录都有一个唯一的
参照完整性 (Referential Integrity)
参照完整性确保了外键与主键之间的关联一致性。
示例
-
对于
Courses表,teacher_id是外键,因此:teacher_id必须与Teachers表中的某个teacher_id匹配。
-
对于
Enrollments表,student_id和course_id分别是外键,因此:student_id必须与Students表中的某个student_id匹配。course_id必须与Courses表中的某个course_id匹配。
-
对于
Grades表,enrollment_id是外键,因此:enrollment_id必须与Enrollments表中的某个enrollment_id匹配。
域完整性 (Domain Integrity)
域完整性定义了列的有效值范围或格式。
示例
-
对于
Students表:email必须是唯一的,并且格式正确。
-
对于
Teachers表:email必须是唯一的,并且格式正确。
-
对于
Courses表:course_code必须是唯一的。
-
对于
Enrollments表:- 无特殊域完整性约束。
-
对于
Grades表:grade必须是非负数值,并且通常在 0 到 100 之间。
创建表的 SQL 语句示例
以下是创建这些表的 SQL 语句示例:
sql
CREATE TABLE Students (
student_id INT AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(255) NOT NULL,
last_name VARCHAR(255) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL
);
CREATE TABLE Teachers (
teacher_id INT AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(255) NOT NULL,
last_name VARCHAR(255) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL
);
CREATE TABLE Courses (
course_id INT AUTO_INCREMENT PRIMARY KEY,
course_code VARCHAR(255) UNIQUE NOT NULL,
course_name VARCHAR(255) NOT NULL,
teacher_id INT,
FOREIGN KEY (teacher_id) REFERENCES Teachers(teacher_id)
);
CREATE TABLE Enrollments (
enrollment_id INT AUTO_INCREMENT PRIMARY KEY,
student_id INT,
course_id INT,
FOREIGN KEY (student_id) REFERENCES Students(student_id),
FOREIGN KEY (course_id) REFERENCES Courses(course_id)
);
CREATE TABLE Grades (
grade_id INT AUTO_INCREMENT PRIMARY KEY,
enrollment_id INT,
grade DECIMAL(4, 2) CHECK (grade BETWEEN 0 AND 100),
FOREIGN KEY (enrollment_id) REFERENCES Enrollments(enrollment_id)
);
这些完整性约束确保了数据的一致性和准确性,并有助于防止不一致的数据输入到数据库中。通过这样的设计,我们可以保证系统能够准确地跟踪学生、教师和课程之间的关系,同时维护数据的完整性和一致性。