1. 概念解析:什么是唯一约束和唯一索引?
在PostgreSQL中,唯一约束(UNIQUE CONSTRAINT)和唯一索引(UNIQUE INDEX)都是用于确保表中数据唯一性的机制,但它们的实现方式和应用场景存在本质区别。我们先从基础概念入手。
1.1 唯一约束的本质
唯一约束是表级别的完整性约束,它通过逻辑规则限制列或列组合的值必须唯一。当你在表上创建唯一约束时,PostgreSQL实际上会在后台自动创建一个唯一索引来实现这个约束。这是数据库设计中的声明式方法——你只需要告诉数据库"这些列需要保持唯一",而不需要关心具体如何实现。
例如,创建用户表时要求邮箱必须唯一:
sql复制CREATE TABLE users (
id SERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE, -- 这就是唯一约束
username VARCHAR(50)
);
1.2 唯一索引的实质
唯一索引则是物理层面的数据结构,它直接在存储引擎层创建一个索引结构来加速查询并强制唯一性。创建唯一索引是一种命令式操作,你需要明确指定创建索引的指令:
sql复制CREATE UNIQUE INDEX idx_user_email ON users(email);
虽然两者都能保证数据唯一性,但唯一索引提供了更多底层控制选项,比如可以指定索引类型(B-tree、Hash等)、存储参数和部分索引条件。
注意:在PostgreSQL中,唯一约束本质上是通过唯一索引实现的,这就是为什么很多人容易混淆两者的原因。但它们在语义和使用方式上有重要区别。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 功能对比:核心差异详解
2.1 创建方式的差异
唯一约束只能作为表定义的一部分创建(CREATE TABLE或ALTER TABLE),而唯一索引可以独立创建。这是两者最直观的区别:
唯一约束的创建方式:
sql复制-- 建表时定义
CREATE TABLE products (
product_id SERIAL PRIMARY KEY,
sku VARCHAR(50) UNIQUE,
name VARCHAR(100)
);
-- 通过ALTER TABLE添加
ALTER TABLE products ADD CONSTRAINT uniq_product_sku UNIQUE (sku);
唯一索引的创建方式:
sql复制-- 独立创建
CREATE UNIQUE INDEX idx_product_sku ON products(sku);
-- 可以包含WHERE条件创建部分索引
CREATE UNIQUE INDEX idx_product_active_sku ON products(sku) WHERE is_active = true;
2.2 空值处理的区别
唯一约束和唯一索引对NULL值的处理方式存在微妙但重要的差异:
- 唯一约束:认为所有NULL值都是不相等的,允许多个NULL值存在
- 唯一索引:默认行为与约束相同,但可以通过特殊语法改变
sql复制-- 测试唯一约束
ALTER TABLE users ADD CONSTRAINT uniq_user_phone UNIQUE (phone);
INSERT INTO users (phone) VALUES (NULL); -- 成功
INSERT I
