LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

SQL约束详解:语法、应用与实战示例

admin
2025年8月30日 12:56 本文热度 156

SQL约束是数据库设计的核心机制,用于强制数据完整性和业务规则。以下按约束类型分类解析,包含基础语法、参数说明、应用场景和实战示例,仅供参考。


一、SQL约束的基础概念

作用:在数据插入/更新时自动校验,防止非法数据破坏完整性
分类

  • 列级约束:直接定义在字段后(CREATE TABLE时)
  • 表级约束:独立声明在所有字段后(支持多字段组合约束)
    共性特征
  • 约束名可自定义(建议约束类型_表名_字段格式)
  • 违反约束时操作被终止,抛出错误代码(如MySQL 1062主键冲突)
  • 支持CREATE TABLEALTER TABLE两种定义方式

数据完整性类型

  • 实体完整性(主键)
  • 参照完整性(外键)
  • 域完整性(非空/检查/默认值)

二、SQL约束类型详解

1. NOT NULL 约束

作用:禁止字段存储NULL值(空值 ≠ 0或空字符串)
语法

-- 创建表时定义
CREATE TABLE 表名 (
    字段名 数据类型 NOT NULL
);

-- 修改表结构
ALTER TABLE 表名 
MODIFY 字段名 数据类型 NOT NULL;  -- MySQL/PostgreSQL
ALTER TABLE 表名 
ALTER COLUMN 字段名 SET NOT NULL; -- SQL Server

重要特性

  • Oracle中NULL与空字符串等价
  • SQL Server严格区分NULL''

实战示例

-- 创建用户表
CREATE TABLE Users (
    UserID INT PRIMARY KEY,
    UserName VARCHAR(50) NOT NULL,  -- 用户名不能为空
    BirthDate DATE NOT NULL         -- 出生日期必填
);

-- 插入非法数据(触发约束)
INSERT INTO Users (UserID, UserName) 
VALUES (1, 'Alice'); 
-- 错误: Column 'BirthDate' cannot be null
2. UNIQUE 约束

作用:确保字段值全表唯一(允许多个NULL
语法

-- 单字段列级约束
CREATE TABLE 表名 (
    字段名 数据类型 UNIQUE
);

-- 多字段表级约束
CREATE TABLE 表名 (
    字段1 数据类型,
    字段2 数据类型,
    CONSTRAINT 约束名 UNIQUE (字段1, 字段2)
);

-- 修改表添加约束
ALTER TABLE 表名 
ADD CONSTRAINT 约束名 UNIQUE (字段);

跨数据库差异

数据库
NULL处理规则
SQL Server
唯一索引中NULL视为相等(仅1个)
Oracle
全空字段组合允许重复
MySQL
允许多个NULL(不视为相等)

实战示例

-- 创建员工邮箱表
CREATE TABLE Employees (
    EmpID INT PRIMARY KEY,
    Email VARCHAR(100) UNIQUE,  -- 邮箱唯一
    Phone VARCHAR(20)
);

-- 添加复合唯一约束(部门+工号)
ALTER TABLE Employees 
ADD CONSTRAINT uniq_dept_emp 
UNIQUE (DeptID, EmpCode);

-- 插入冲突数据
INSERT INTO Employees (EmpID, Email) 
VALUES (1, 'alice@company.com');
INSERT INTO Employees (EmpID, Email) 
VALUES (2, 'alice@company.com'); 
-- 错误: Duplicate entry 'alice@company.com'
3. PRIMARY KEY 约束

作用:唯一标识行数据(NOT NULL + UNIQUE)
语法

-- 单字段主键
CREATE TABLE 表名 (
    字段名 数据类型 PRIMARY KEY  -- 列级
);

-- 多字段主键(表级)
CREATE TABLE 表名 (
    字段1 数据类型,
    字段2 数据类型,
    CONSTRAINT pk_name PRIMARY KEY (字段1, 字段2)
);

-- 添加主键
ALTER TABLE 表名 
ADD PRIMARY KEY (字段);  -- 匿名约束
ALTER TABLE 表名 
ADD CONSTRAINT pk_name PRIMARY KEY (字段);

核心规则

  • 每表仅一个主键(可多字段组合)
  • 主键字段自动创建唯一索引
  • MySQL中主键约束名固定为PRIMARY

实战示例

-- 创建订单表
CREATE TABLE Orders (
    OrderID INT PRIMARY KEY,     -- 列级主键
    OrderDate DATE NOT NULL
);

-- 创建订单详情(复合主键)
CREATE TABLE OrderDetails (
    OrderID INT,
    ProductID INT,
    Quantity INT,
    CONSTRAINT pk_order_product 
    PRIMARY KEY (OrderID, ProductID)  -- 表级
);

-- 非法数据插入
INSERT INTO Orders (OrderID, OrderDate) 
VALUES (1, '2023-01-01');
INSERT INTO Orders (OrderID, OrderDate) 
VALUES (1, '2023-02-01'); 
-- 错误: Duplicate entry '1'for key 'PRIMARY'
4. FOREIGN KEY 约束

作用:强制表间引用完整性(子表引用父表主键)
语法

-- 创建表时定义
CREATE TABLE 子表 (
    子表字段 数据类型,
    CONSTRAINT fk_name 
    FOREIGN KEY (子表字段) 
    REFERENCES 父表(父表字段)
    [ON DELETE 动作]  -- 级联操作
    [ON UPDATE 动作]
);

-- 添加外键
ALTER TABLE 子表 
ADD CONSTRAINT fk_name 
FOREIGN KEY (子表字段) 
REFERENCES 父表(父表字段);

级联操作(可选)

动作
效果
NO ACTION
禁止删除/更新被引数据(默认)
CASCADE
级联删除/更新子表数据
SET NULL
子表字段置为NULL
SET DEFAULT
子表字段置为默认值

实战示例

-- 父表:部门
CREATE TABLE Departments (
    DeptID INT PRIMARY KEY,
    DeptName VARCHAR(50)
);

-- 子表:员工(带级联删除)
CREATE TABLE Employees (
    EmpID INT PRIMARY KEY,
    DeptID INT,
    CONSTRAINT fk_emp_dept 
    FOREIGN KEY (DeptID) 
    REFERENCES Departments(DeptID)
    ON DELETE CASCADE  -- 部门删除时员工自动删除
);

-- 插入关联数据
INSERT INTO Departments VALUES (1, 'IT');
INSERT INTO Employees VALUES (101, 1);

-- 测试级联删除
DELETE FROM Departments WHERE DeptID = 1;
-- 结果:Employees中EmpID=101的记录自动删除
5. CHECK 约束

作用:定义字段值的业务规则(类似WHERE条件)
语法

-- 列级约束
CREATE TABLE 表名 (
    字段名 数据类型 CHECK (条件)
);

-- 表级多字段约束
CREATE TABLE 表名 (
    字段1 数据类型,
    字段2 数据类型,
    CONSTRAINT chk_name CHECK (字段1 > 字段2)
);

-- 添加约束
ALTER TABLE 表名 
ADD CONSTRAINT chk_name CHECK (条件);

特殊规则

  • 检查结果为NULL时视为通过
  • 条件中可调用函数(如GETDATE()
  • SQLite仅支持CREATE TABLE时定义

实战示例

-- 创建账户表
CREATE TABLE Accounts (
    AccountID INT PRIMARY KEY,
    Balance DECIMAL(10,2) CHECK (Balance >= 0),  -- 余额不可负
    Status VARCHAR(10) CHECK (Status IN ('ACTIVE''CLOSED'))
);

-- 添加自定义规则(开户日期早于今日)
ALTER TABLE Accounts 
ADD CONSTRAINT chk_open_date 
CHECK (OpenDate < GETDATE());

-- 违反约束测试
INSERT INTO Accounts 
VALUES (1, -100.00, 'ACTIVE'); 
-- 错误: Check constraint 'Balance>=0' violated
6. DEFAULT 约束

作用:字段未赋值时自动填充默认值
语法

-- 创建表时定义
CREATE TABLE 表名 (
    字段名 数据类型 DEFAULT 默认值
);

-- 修改默认值
ALTER TABLE 表名 
ALTER COLUMN 字段名 SET DEFAULT 值;  -- MySQL/PostgreSQL
ALTER TABLE 表名 
ADD CONSTRAINT 约束名 DEFAULT 值 FOR 字段;  -- SQL Server

常用默认值

  • 固定值:DEFAULT 0
  • 系统函数:DEFAULT GETDATE()(当前时间)
  • 表达式:DEFAULT (UUID())(生成唯一ID)

实战示例

-- 创建用户注册表
CREATE TABLE Registrations (
    UserID INT PRIMARY KEY,
    RegDate DATE DEFAULT GETDATE(),  -- 自动填充注册日期
    Status VARCHAR(10) DEFAULT 'PENDING'
);

-- 插入数据(忽略默认字段)
INSERT INTO Registrations (UserID) VALUES (1001);

-- 查询结果
SELECT * FROM Registrations;
/*
UserID | RegDate     | Status
1001   | 2023-10-05  | PENDING
*/
7. INDEX(索引)

严格说索引非约束,但用于加速唯一性校验
作用:快速定位数据(UNIQUE/PRIMARY KEY自动创建)
语法

CREATE INDEX 索引名 ON 表名 (字段);
CREATE UNIQUE INDEX 索引名 ON 表名 (字段); -- 唯一索引

与约束关系

  • 主键/唯一约束自动生成唯一索引
  • 索引可独立于约束存在(如加速查询)

三、SQL约束管理技巧

1. 查看约束

-- SQL Server
SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS;

-- MySQL
SHOW CREATE TABLE 表名;

2. 删除约束

ALTER TABLE 表名 DROP CONSTRAINT 约束名;  -- 通用
ALTER TABLE 表名 DROP PRIMARY KEY;       -- 主键
ALTER TABLE 表名 DROP INDEX 索引名;       -- 索引

3. 临时禁用约束

-- MySQL外键开关
SET FOREIGN_KEY_CHECKS = 0;  -- 关闭
SET FOREIGN_KEY_CHECKS = 1;  -- 开启

-- SQL Server
ALTER TABLE 表名 NOCHECK CONSTRAINT ALL;

4. 约束设计建议

  • 主键用无意义数字(自增ID/UUID),避免业务字段
  • 外键字段需加索引(提升JOIN性能)
  • 慎用ON DELETE CASCADE(避免误删连锁反应)
  • CHECK约束优先于应用层校验(保证数据纯净性)

综合实战:学生管理系统

-- 学院表(父表)
CREATE TABLE Colleges (
    CollegeID INT PRIMARY KEY,
    Name VARCHAR(50) NOT NULL UNIQUE
);

-- 学生表(子表)
CREATE TABLE Students (
    StudentID INT PRIMARY KEY,
    Name VARCHAR(50) NOT NULL,
    IDCard CHAR(18) UNIQUE,  -- 身份证唯一
    CollegeID INT NOT NULL,
    EnrollmentDate DATE DEFAULT GETDATE(),
    GPA DECIMAL(3,2) CHECK (GPA BETWEEN 0 AND 4.0),
    
    -- 表级外键(级联更新)
    CONSTRAINT fk_student_college 
    FOREIGN KEY (CollegeID) 
    REFERENCES Colleges(CollegeID)
    ON UPDATE CASCADE
);

-- 课程表
CREATE TABLE Courses (
    CourseID INT PRIMARY KEY,
    Credit INT CHECK (Credit > 0)  -- 学分需正数
);

-- 插入测试数据
INSERT INTO Colleges VALUES (1, '计算机学院');
INSERT INTO Students (StudentID, Name, CollegeID) 
VALUES (1001, '张三', 1);  -- 自动填充注册日期

-- 错误测试:无效学院
INSERT INTO Students VALUES (1002, '李四''310101...', 99, '2023-09-01', 3.8);
-- 报错: Foreign key constraint violation

系统约束清单

  • 学院名称全局唯一
  • 学生身份证号唯一
  • GPA范围0~4.0
  • 学院更新时自动同步到学生表
  • 注册日期自动生成

总结

SQL约束是数据库的“守门员”,通过七类机制保障数据质量:

  1. NOT NULL:强制关键字段必填
  2. UNIQUE:防止重复数据(如身份证)
  3. PRIMARY KEY:确立数据唯一标识
  4. FOREIGN KEY:维护表间引用关系
  5. CHECK:实现业务规则(如GPA范围)
  6. DEFAULT:智能填充缺失值
  7. INDEX:幕后支持约束性能

我们要合理使用SQL约束减少应用层校验代码,从根本上杜绝脏数据。


阅读原文:原文链接


该文章在 2025/9/1 12:06:37 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved