sql-server

11 Пост

oracle

14 Пост

postgresql

13 Пост

my-sql

2 Пост

common-sql

3 Пост

News

5 Новости

PostgreSQL Exclusion Constraints

PostgreSQL exclusion constraints are a native database feature that let you define rules such as “these rows must not conflict”, by blocking INSERTs or UPDATEs where specified comparisons between rows would all evaluate to TRUE.

Equivalently

An exclusion constraint specifies that for every pair of rows in a table, at least one of the defined operator comparisons between corresponding columns must return FALSE.

If all specified operator comparisons return TRUE for a pair of rows, the constraint is violated.

Unlike UNIQUE constraints, which only prevent duplicate values based on equality, exclusion constraints prevent logical conflicts between rows.

They are:

✔ declarative
✔ index-backed
✔ enforced by the PostgreSQL engine
✔ safe under concurrent inserts and updates (MVCC-aware)


What Problem Exclusion Constraints Solve

Traditional constraints (UNIQUE, PRIMARY KEY, CHECK) can reason only about:

• equality
• a single row at a time

Exclusion constraints can reason about:

• relationships between rows
• overlaps, intersections, conditional uniqueness
• business rules such as “only one active row” or “no overlapping periods”

➜ This allows the database itself to guarantee correctness for rules that would otherwise require triggers or application logic.

General Syntax

ALTER TABLE table_name

ADD CONSTRAINT constraint_name

EXCLUDE USING index_method (

    column1 WITH operator1,

    column2 WITH operator2,

    ...

)

[ WHERE (predicate) ];


How the Constraint Is Evaluated

For any two rows R1 and R2, PostgreSQL evaluates:

operator1(R1.column1, R2.column1)

AND

operator2(R1.column2, R2.column2)

AND ...

• If all comparisons return TRUE ➜ ❌ constraint is violated
• If at least one comparison returns FALSE
➜ ✔ rows may coexist


The Role of WHERE (predicate)

In a PostgreSQL exclusion constraint, the optional:

WHERE (predicate)

defines which rows participate in conflict checking.

✔ Only rows where the predicate evaluates to TRUE are checked
✖ Rows where the predicate is FALSE or NULL are ignored

➜ This makes the exclusion constraint partial.

This is especially useful for rules like:

• only ACTIVE rows must not conflict
• ignore historical or cancelled records
• enforce rules only for current data

Index Requirements

Exclusion constraints require an index method that supports non-equality operators.

✔ Most commonly: GiST
✔ In specific cases: SP-GiST

btree_gist Extension

When equality (=) is used on standard scalar types (INT, TEXT, DATE, etc.) inside a GiST exclusion constraint, PostgreSQL requires:

CREATE EXTENSION IF NOT EXISTS btree_gist;

This extension allows GiST indexes to support B-tree-style operators:

• =
•
<, <=, >, >=

⚠ The extension is installed once per database, not per table or index.


Performance and Concurrency Characteristics

✔ conflict detection is index-based
✔ no full table scans
✔ no trigger execution
✔ safe under high concurrency
✔ race conditions are prevented automatically

➜ This is a major advantage over application-level checks or trigger-based logic.


When Exclusion Constraints Are Useful

Exclusion constraints are ideal for:

• scheduling and reservations
• validity periods (contracts, prices, tariffs)
• “only one active row” rules
• IP or network allocation
• spatial or geometric conflicts
• enforcing business rules that must never be violated


Feature Comparison Summary

Capability

PostgreSQL

Oracle

SQL Server

MySQL

Exclusion constraints

✔ YES

✖ NO

✖ NO

✖ NO

Native overlap prevention

✔ YES

✖ NO

✖ NO

✖ NO

Conditional conflict rules

✔ YES

⚠ LIMITED

⚠ PARTIAL

✖ NO

Index-backed conflict logic

✔ YES

✖ NO

⚠ PARTIAL

✖ NO

Concurrency-safe by design

✔ YES

✖ NO

✖ NO

✖ NO


Final Summary

Exclusion constraints allow PostgreSQL to enforce real business rules declaratively:

✔ rules are expressed as data relationships
✔ enforcement is done by the engine
✔ correctness is guaranteed under concurrency
✔ no triggers or application logic are required