PostgreSQL 约束

本文介绍了PostgreSQL中的多种约束类型,包括检查约束、非空约束、唯一约束、主键、外键及排他约束等,并详细解释了每种约束的作用及用法。

PostgreSQL 约束

一、约束的含义

        数据类型是一种限制能够储存在表中数据类别的方法。但是产品的价格的列只能接受正值,但是没有任何一种标准的数据类型只接受正值。或是我们可能需要根据其他列或行来约束一个列中的数据。

二、约束的分类

(一)、检查约束

一个检查约束是最普通的约束类型。它允许我们指定一个特定列中的值必须要满足一个布尔表达式。

1、列约束

一个检查约束有关键字 CHECK 以及其后的包围在圆括号中的表达式组成。检查约束表达式应该涉及到被约束的列,否则该约束也没什么实际意义。

我们也可以给与约束一个独立的名称。这会使得错误消息更为清晰,同时也允许我们在需要更改约束时能引用它。语法为:

要指定一个命名的约束,请在约束名称标识符前使用关键词 CONSTRAINT ,然后把约束定义放在标识符之后(如果没有以这种方式指定一个约束名称,系统将会为我们选择一个)。

2、表约束

列约束可以写成表约束,反过来就不行了!

(二)、非空约束

一个非空约束仅仅指定一个列中不会有空值。

(三)、唯一约束

唯一约束保证在一列中或者一组列中保存的数据在表中所有行间是唯一的。

(四)、主键

一个主键约束表示可以用作表中行的唯一标识符的一个列或者一组列。这要求那些值都是唯一的并且非空。

两种方法可选其一:

        增加一个主键将自动在主键中列出的列或列组上创建一个唯一B-tree索引。并且会强制这些列被标记为 NOT NULL 。
        一个表最多只能有一个主键(可以有任意数量的唯一和非空约束,它们可以达到和主键几乎一样的功能,但只能有一个被标识为主键)。关系数据库理论要求每一个表都要有一个主键。

(五)、外键

一个外键约束指定一列(或一组列)中的值必须匹配出现在另一个表中某些行的值。我们说这维持了两个关联表之间的引用完整性。

(六)、排他约束

排他约束保证如果将任何两行的指定列或表达式使用指定操作符进行比较,至少其中一个操作符比较将会返回否或空值。

增加一个排他约束将在约束声明所指定的类型上自动创建索引。

<think>嗯,用户询问的是PostgreSQL中创建约束时是否会自动创建索引的问题。这个问题其实涉及到PostgreSQL约束机制和索引管理的关系。用户提供的站内引用资料挺丰富的,特别是引用【2】明确提到了PRIMARYKEY约束会自动创建唯一索引,引用【1】中关于序列使用的细节其实也侧面支撑了主键自增的场景。需要特别注意的是用户引用的中文资料和PostgreSQL官方文档链接都很专业,看来用户对数据库有相当程度的了解。考虑到用户之前的查询历史中提到过"postgresqlconstraintautocreateindex",用户的核心困惑点应该是:当创建各种约束时,背后到底会不会生成索引?哪些约束会生成?哪些不会?从专业角度需要分几种情况说明:主键约束肯定创建唯一索引,这是PostgreSQL的既定机制;唯一约束同样如此,系统自动创建唯一索引来支撑唯一性检查;外键约束就比较特殊了,它不会自动创建索引,这个细节很多开发者容易忽略;检查约束和NOTNULL约束则完全不会创建索引。用户可能真正关心的是性能问题。外键不自动建索引这个点特别重要,因为在涉及级联删除或更新时,没有索引会导致全表扫描,这点必须提醒用户。可以举删除父表记录的例子说明。在后续问题设计上,应该围绕用户可能遇到的性能优化场景,比如如何验证索引存在、外键索引缺失时的处理方案等。用户既然问到机制层面,大概率是实际遇到了性能瓶颈或者在做数据库优化工作。</think> 在 PostgreSQL 中,为表添加**某些类型的约束会自动创建索引**,但并非所有约束都会自动创建。具体规则如下: ### 1. PRIMARY KEY 约束 ⭐ * **自动创建索引**:为某列添加 `PRIMARY KEY` 约束时,PostgreSQL **会自动创建一个唯一的 B 树索引**,索引名通常为 `<表名>_pkey`。该索引会强制该列(或列组合)值的唯一性并提高基于主键的查询效率。 * **示例**: ```sql CREATE TABLE orders ( order_id SERIAL PRIMARY KEY, -- 自动为主键创建索引 orders_pkey order_date DATE ); ``` * 引用依据:【2】中提到 `ADD CONSTRAINT pk_rtable PRIMARY KEY(c1)` 会创建名为 `pk_rtable` 的索引 [^2]。【1】【4】也隐含主键使用序列,依赖于索引保证唯一性 [^1][^4]。 ### 2. UNIQUE 约束 ⭐ * **自动创建索引**:为某列添加 `UNIQUE` 约束时,PostgreSQL **会自动创建一个唯一的 B 树索引**,索引名通常为 `<表名>_<列名>_key`。该索引保证该列(或列组合)值的唯一性。 * **示例**: ```sql CREATE TABLE users ( user_id SERIAL PRIMARY KEY, email VARCHAR(255) UNIQUE -- 自动为唯一约束创建索引 users_email_key ); ``` ### 3. FOREIGN KEY 约束 (外键) ❌ * **不自动创建索引**:添加 `FOREIGN KEY` 约束 (参考约束 - `REFERENCES`) **不会自动创建索引**。`FOREIGN KEY` 约束仅检查本表(子表)中外键列的值在参考表(父表)的主键或唯一键中是否存在。 * **建议手动索引**:尽管不会被自动创建,但强烈建议**手动在外键列上创建索引**。这对于提高涉及外键约束的查询(如 `JOIN`, `ON DELETE CASCADE`, `ON UPDATE CASCADE`)和避免子表上的全表扫描至关重要。 * **示例**: ```sql CREATE TABLE order_items ( item_id SERIAL PRIMARY KEY, order_id INTEGER REFERENCES orders(order_id), -- 外键,不会自动索引 product_id INTEGER ); -- 建议手动创建索引以提高性能 CREATE INDEX idx_order_items_order_id ON order_items(order_id); ``` ### 4. CHECK 约束 (检查约束) ❌ * **不创建索引**:`CHECK` 约束用于限制列值的范围或条件(如 `price > 0`, `gender IN ('M', 'F')`)。添加 `CHECK` 约束 **不会创建任何索引**。它仅在数据插入或更新时评估条件是否成立 [^1][^4]。 ### 5. NOT NULL 约束 (非空约束) ❌ * **不创建索引**:添加 `NOT NULL` 约束 **不会创建索引**。它仅确保该列不允许 `NULL` 值。 ### 📌 总结 | 约束类型 | 是否自动创建索引 | 原因/目的 | | :-------------- | :--------------- | :----------------------------- | | `PRIMARY KEY` | ✅ **是** | 强制唯一性,加速查找/连接 | | `UNIQUE` | ✅ **是** | 强制唯一性 | | `FOREIGN KEY` | ❌ **否** | 仅强制引用完整性 | | `CHECK` | ❌ **否** | 仅检查值域/条件 | | `NOT NULL` | ❌ **否** | 仅禁止空值 | ### 🔍 验证索引 可通过 `psql` 命令 `\d <表名>` 或查询系统表 `pg_indexes` 查看已存在的索引: ```sql SELECT indexname, indexdef FROM pg_indexes WHERE tablename = 'orders'; ``` *** ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值