SQL 入门:约束

SQL约束入门教程

SQL约束入门教程

全面学习SQL约束:确保数据完整性和一致性的关键工具

SQL约束简介

SQL约束是应用于表中列的规则,用于限制可以存储在表中的数据类型。约束有助于确保数据库中数据的准确性和可靠性。

为什么需要约束?

  • 数据完整性:确保数据的准确性和一致性
  • 业务规则:强制执行特定的业务逻辑
  • 数据质量:防止无效数据的输入
  • 关系维护:保持表之间的正确关系
PRIMARY KEY
唯一标识每条记录
FOREIGN KEY
维护表间关系
NOT NULL
确保列不能为空
UNIQUE
确保所有值都不同
CHECK
确保列值满足条件
DEFAULT
为列提供默认值
注意: 约束可以在创建表时定义,也可以在创建表后使用ALTER TABLE语句添加。

PRIMARY KEY 主键约束

PK

主键约束

唯一标识表中的每条记录

特点:

  • 主键必须包含唯一值
  • 主键列不能包含NULL值
  • 每个表只能有一个主键
  • 主键可以由单个列或多个列(复合主键)组成

语法示例

-- 创建表时定义主键
CREATE TABLE Students (
  student_id INT PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  email VARCHAR(100)
);

-- 使用复合主键
CREATE TABLE OrderDetails (
  order_id INT,
  product_id INT,
  quantity INT,
  PRIMARY KEY (order_id, product_id)
);

-- 为现有表添加主键
ALTER TABLE Students
ADD PRIMARY KEY (student_id);

主键约束示例

Students 表
student_id (PK)
name
email
最佳实践: 通常使用无意义的自增数字作为主键,而不是业务数据。

FOREIGN KEY 外键约束

FK

外键约束

用于链接两个表,保持引用完整性

特点:

  • 外键是一个表中的字段,它是另一个表的主键
  • 防止破坏表之间关系的操作
  • 确保数据只能插入存在于被引用表中的值

语法示例

-- 创建外键约束
CREATE TABLE Orders (
  order_id INT PRIMARY KEY,
  customer_id INT,
  order_date DATE,
  FOREIGN KEY (customer_id) REFERENCES Customers(customer_id)
);

-- 带有级联操作的外键
CREATE TABLE OrderDetails (
  order_id INT,
  product_id INT,
  FOREIGN KEY (order_id) REFERENCES Orders(order_id)
    ON DELETE CASCADE
    ON UPDATE CASCADE
);

外键关系示例

Customers 表
customer_id (PK)
name
Orders 表
order_id (PK)
customer_id (FK)
order_date

外键操作

操作 描述
NO ACTION 如果存在相关记录,阻止删除或更新操作
CASCADE 删除或更新父表记录时,自动删除或更新子表相关记录
SET NULL 删除或更新父表记录时,将子表相关记录设为NULL
SET DEFAULT 删除或更新父表记录时,将子表相关记录设为默认值

NOT NULL 非空约束

NN

非空约束

确保列不能存储NULL值

特点:

  • 强制字段必须包含值
  • 在插入或更新数据时,该列必须有值
  • 常用于必填字段,如用户名、密码等

语法示例

-- 创建表时定义NOT NULL约束
CREATE TABLE Users (
  user_id INT PRIMARY KEY,
  username VARCHAR(50) NOT NULL,
  email VARCHAR(100) NOT NULL,
  phone VARCHAR(20) -- 可以为NULL
);

-- 为现有表添加NOT NULL约束
ALTER TABLE Users
MODIFY phone VARCHAR(20) NOT NULL;
user_id username email phone
1 john_doe john@example.com 123-456-7890
2 jane_smith jane@example.com NULL
注意: 主键自动具有NOT NULL约束,不需要显式指定。

UNIQUE 唯一约束

UQ

唯一约束

确保列中的所有值都是不同的

特点:

  • 保证列中每个值都是唯一的
  • 与主键不同,唯一约束允许NULL值
  • 一个表可以有多个唯一约束
  • 可以应用于单个列或多个列的组合

语法示例

-- 创建表时定义唯一约束
CREATE TABLE Employees (
  emp_id INT PRIMARY KEY,
  email VARCHAR(100) UNIQUE,
  phone VARCHAR(20) UNIQUE
);

-- 复合唯一约束
CREATE TABLE Enrollments (
  student_id INT,
  course_id INT,
  semester VARCHAR(10),
  UNIQUE (student_id, course_id, semester)
);

-- 为现有表添加唯一约束
ALTER TABLE Employees
ADD CONSTRAINT uc_email UNIQUE (email);
重要: UNIQUE约束允许NULL值,但每个NULL值被认为是唯一的。多个NULL值不会违反约束。

CHECK 检查约束

CHK

检查约束

限制列中值的范围

特点:

  • 确保列值满足特定条件
  • 可以基于逻辑表达式定义约束
  • 在插入或更新时验证数据
  • 可以应用于单个列或整个表

语法示例

-- 创建表时定义CHECK约束
CREATE TABLE Products (
  product_id INT PRIMARY KEY,
  product_name VARCHAR(100),
  price DECIMAL(10,2) CHECK (price > 0),
  stock_quantity INT CHECK (stock_quantity >= 0)
);

-- 多列CHECK约束
CREATE TABLE Employees (
  emp_id INT PRIMARY KEY,
  salary DECIMAL(10,2),
  bonus DECIMAL(10,2),
  CHECK (bonus <= salary * 0.5)
);

-- 为现有表添加CHECK约束
ALTER TABLE Products
ADD CONSTRAINT chk_price CHECK (price > 0);

常见CHECK约束示例

-- 年龄范围检查
age INT CHECK (age >= 0 AND age <= 150)

-- 性别检查
gender VARCHAR(10) CHECK (gender IN ('男', '女', '其他'))

-- 邮箱格式检查(简单版本)
email VARCHAR(100) CHECK (email LIKE '%@%.%')

DEFAULT 默认约束

DEF

默认约束

为列提供默认值

特点:

  • 在插入新记录时,如果未指定值,则使用默认值
  • 可以设置固定值或系统函数
  • 提高数据输入的效率
  • 确保即使没有提供值,列也有合理的值

语法示例

-- 创建表时定义DEFAULT约束
CREATE TABLE Orders (
  order_id INT PRIMARY KEY,
  order_date DATE DEFAULT CURRENT_DATE,
  status VARCHAR(20) DEFAULT 'pending',
  total_amount DECIMAL(10,2) DEFAULT 0.00
);

-- 为现有表添加DEFAULT约束
ALTER TABLE Orders
ALTER COLUMN status SET DEFAULT 'pending';

常用默认值

默认值 描述 示例
固定值 预定义的常量值 DEFAULT 'active'
系统函数 数据库系统函数 DEFAULT CURRENT_TIMESTAMP
数学表达式 简单的计算表达式 DEFAULT 0
注意: 如果插入时显式指定NULL值,将使用NULL而不是默认值。

综合示例

完整的表定义示例

CREATE TABLE Employees (
  -- 主键约束
  employee_id INT PRIMARY KEY,
  
  -- 非空约束
  first_name VARCHAR(50) NOT NULL,
  last_name VARCHAR(50) NOT NULL,
  
  -- 唯一约束
  email VARCHAR(100) UNIQUE NOT NULL,
  
  -- 检查约束
  age INT CHECK (age >= 18 AND age <= 65),
  salary DECIMAL(10,2) CHECK (salary > 0),
  
  -- 默认约束
  hire_date DATE DEFAULT CURRENT_DATE,
  department_id INT DEFAULT 1,
  
  -- 外键约束
  FOREIGN KEY (department_id) REFERENCES Departments(department_id)
);

约束管理操作

-- 删除约束
ALTER TABLE Employees
  DROP CONSTRAINT 约束名;

-- 禁用约束
ALTER TABLE Employees
  NOCHECK CONSTRAINT 约束名;

-- 启用约束
ALTER TABLE Employees
  CHECK CONSTRAINT 约束名;

约束总结表

约束类型 用途 是否允许多个 是否允许NULL
PRIMARY KEY 唯一标识记录
FOREIGN KEY 维护表间关系
NOT NULL 防止NULL值
UNIQUE 确保值唯一
CHECK 验证数据范围
DEFAULT 提供默认值