Skip to content

DB2 - 约束

约束是在表列上定义的规则,用于在数据库层面强制执行数据完整性和业务逻辑。它们阻止无效数据进入数据库,确保您的数据保持准确、可靠和一致。约束可以在创建表时定义,也可以稍后使用 ALTER TABLE 语句添加。

让我们探讨 Db2 中最常见的约束类型。

NOT NULL 约束确保列不能包含 NULL 值。这是最基本的数据验证形式,保证每一行中都必须为该列提供一个值。

语法和示例:

-- 创建一个 products 表,其中 ID 和 name 为必填项
CREATE TABLE products (
product_id INT NOT NULL,
product_name VARCHAR(100) NOT NULL,
description VARCHAR(255)
);

尝试插入没有 product_name 的行将导致错误:

-- 这将失败
INSERT INTO products (product_id, description) VALUES (101, 'A new gadget');
-- SQL0407N 不允许将 NULL 值分配给 NOT NULL 列 "...PRODUCT_NAME"。

UNIQUE 约束确保列(或一组列)中的所有值都是唯一的。这对于必须唯一但不是表主标识符的列很有用,例如电子邮件地址或产品 SKU。

语法和示例:

CREATE TABLE users (
user_id INT NOT NULL,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE
);

尝试插入重复的电子邮件将失败:

INSERT INTO users VALUES (1, 'john.doe', 'john.doe@example.com');
-- 这将失败
INSERT INTO users VALUES (2, 'jane.doe', 'john.doe@example.com');
-- SQL0803N INSERT 语句中的一个或多个值无效,因为唯一约束限制了表不能包含重复值。

PRIMARY KEY(主键)是一种特殊的约束,它唯一标识表中的每条记录。它隐式地结合了 NOT NULL 和 UNIQUE。一个表只能有一个主键。它是建立表之间关系的最基本约束。

语法和示例:

-- 创建一个以 dept_id 作为主键的 departments 表
CREATE TABLE departments (
dept_id INT NOT NULL,
dept_name VARCHAR(50) NOT NULL,
location VARCHAR(50),
CONSTRAINT pk_departments PRIMARY KEY (dept_id)
);

FOREIGN KEY(外键)在两个表之间创建链接,强制执行引用完整性。它确保一个表(子表)中列(或多列)的值必须与另一个表(父表)中 PRIMARY KEY 的值匹配。这可以防止“孤立”记录。

语法和示例:让我们创建一个引用 departments 表的 employees 表。

CREATE TABLE employees (
emp_id INT NOT NULL PRIMARY KEY,
emp_name VARCHAR(100) NOT NULL,
department_id INT,
CONSTRAINT fk_emp_dept FOREIGN KEY (department_id)
REFERENCES departments (dept_id)
ON DELETE SET NULL
);

ON DELETE SET NULL 子句指定,如果从 departments 表中删除一个部门,则该部门中所有员工的 department_id 将被设置为 NULL。其他选项包括 ON DELETE RESTRICT(如果存在员工,则阻止删除部门)和 ON DELETE CASCADE(删除部门中的所有员工)。

CHECK 约束用于通过限制列中允许的值来强制执行特定的业务规则。条件必须评估为真或未知,值才会被接受。

语法和示例:

CREATE TABLE products_checked (
product_id INT NOT NULL PRIMARY KEY,
product_name VARCHAR(100) NOT NULL,
unit_price DECIMAL(10, 2) NOT NULL,
units_in_stock INT DEFAULT 0,
CONSTRAINT chk_price CHECK (unit_price > 0),
CONSTRAINT chk_stock CHECK (units_in_stock >= 0)
);

任何尝试插入价格或库存数量为负数的产品都将被数据库拒绝。

您可以使用 ALTER TABLE 命令从现有表中添加或删除约束。最佳实践是始终为您的约束提供明确的名称(例如 pk_departments 或 fk_emp_dept),以便于管理。

-- 向现有表添加约束
ALTER TABLE products ADD CONSTRAINT chk_product_name_not_empty CHECK(product_name <> '');
-- 从表中删除约束
ALTER TABLE products DROP CONSTRAINT chk_product_name_not_empty;

专业提示:约束是一个强大的工具,但它们不能替代应用程序级别的验证。使用它们来强制执行核心数据完整性规则,这些规则绝不能被违反,并在您的应用程序代码中处理用户友好的错误报告和复杂的业务逻辑。