PostgreSQL 唯一索引(UNIQUE INDEX)技术文档
1. 概述
唯一索引用于强制表中一列或多列组合值的唯一性,是 PostgreSQL 保障数据完整性的重要机制。通过唯一索引,可避免表中出现索引列值(或多列组合值)完全相同的多行数据。
2. 创建语法
CREATE UNIQUE INDEX name ON table (column [, ...]) [ NULLS [ NOT ] DISTINCT ];
3. 核心特性说明
3.1 支持的索引类型
目前,PostgreSQL 中仅 B 树索引可声明为唯一索引,其他索引类型(如哈希、GiST、SP-GiST、GIN 等)不支持唯一性声明。
3.2 唯一性约束规则
- 单列唯一索引:不允许表中存在索引列值相等的多个行;
- 多列唯一索引:仅拒绝“所有索引列值均相等”的多行数据,部分列值相等、部分不同的情况不受限制。
3.3 空值(NULL)处理逻辑
- 默认行为(未指定
NULLS NOT DISTINCT):空值不被视为相等,因此唯一列中允许存在多个空值; NULLS NOT DISTINCT选项:将空值视为相等,此时唯一列中仅允许存在一个空值。
4. 与约束的关联
PostgreSQL 会自动为定义了主键约束(PRIMARY KEY)或唯一约束(UNIQUE)的表创建唯一索引,具体规则如下:
- 自动创建的唯一索引包含主键/唯一约束的所有列(支持多列组合);
- 该索引是数据库强制主键约束/唯一约束生效的底层机制。
5. 重要注意事项
无需手动在已定义唯一约束或主键的列上创建唯一索引。手动创建会重复生成自动索引,造成存储资源浪费和性能冗余。
6. 应用示例
6.1 单列唯一索引(默认空值规则)
-- 为用户表(user_info)的手机号列(phone)创建唯一索引,确保手机号唯一,允许多个空值
CREATE UNIQUE INDEX idx_user_info_phone ON user_info (phone);
6.2 多列唯一索引
-- 为订单表(order_info)的用户ID(user_id)和订单类型(order_type)创建多列唯一索引
-- 确保同一用户的同一类型订单唯一
CREATE UNIQUE INDEX idx_order_info_user_type ON order_info (user_id, order_type);
6.3 唯一索引(空值视为相等)
-- 为商品表(product)的编码列(code)创建唯一索引,仅允许一个空值
CREATE UNIQUE INDEX idx_product_code ON product (code) NULLS NOT DISTINCT;
7. 总结
- 唯一索引仅支持 B 树类型,核心作用是强制列值(或多列组合值)唯一性;
- 空值处理分两种模式,可通过
NULLS NOT DISTINCT选项灵活控制; - 主键/唯一约束会自动生成唯一索引,无需手动重复创建,避免资源浪费。