
douglasshuang
High Performance PostgreSQL for Rails: `CHECK` constraint can't stand in for `UNIQUE` constraint (Pages 76–77)
The book states:
How can we safely add
UNIQUE
andNOT NULL
constraints to tables, though, and make sure that all rows are eventually checked for compatibility with the constraint?To do that, we can again use check constraints in a supportive, temporary role for
UNIQUE
andNOT NULL
.Even when the intended final constraint type is
UNIQUE
orNOT NULL
, check constraints can stand in temporarily, to validate changes against new rows in preparation for adding the other constraint types on a permanent basis.
I understand and agree with the statements with regard to NOT NULL
constraints, but I don’t think it’s possible to enforce uniqueness with a CHECK
constraint. The PostgreSQL Glossary states:
Check constraint
A type of constraint defined on a relation which restricts the values allowed in one or more attributes. The check constraint can make reference to any attribute of the same row in the relation, but cannot reference other rows of the same relation or other relations.
If a CHECK
constraint can’t reference other rows, then it can’t ensure that the current row doesn’t contain a value or values that are in another row.
Marked As Solved

andatki
Thanks again Douglass. You’re correct here. This was a mistake in the book. We’re in the process of correcting this now. The correction will primarily involve removing UNIQUE constraints from this section as it was incorrect to involve them in a discussion about check constraints as a transitional mechanism.
For unique constraint enforcement with lighter weight locking, I recommend using the unique index tactic. This adds the unique index concurrently, which avoids the heavy lock. Once added, the unique index is then used as the unique constraint definition.
I don’t think this was covered well in the book, so I’m going to include an example here for the Rideshare database.
Step #1: Add the unique index:
CREATE UNIQUE INDEX CONCURRENTLY
idx_vehicles_name_unique ON vehicles (name);
Step #2: Once that’s added (make sure it was added correctly, and is not in an INVALID
state), then a unique constraint can be added to the column, using the unique index, with the USING INDEX
keywords.
ALTER TABLE vehicles
ADD CONSTRAINT idx_vehicles_name_unique UNIQUE
USING INDEX idx_vehicles_name_unique;
Let me know what you think. Thanks again for noticing that and spending the time to write up this issue!
Popular Pragmatic topics










Other popular topics










Latest in PragProg
Latest (all)
Categories:
Popular Portals
- /elixir
- /rust
- /wasm
- /ruby
- /erlang
- /phoenix
- /keyboards
- /js
- /rails
- /python
- /security
- /go
- /swift
- /vim
- /clojure
- /java
- /haskell
- /emacs
- /svelte
- /onivim
- /typescript
- /crystal
- /c-plus-plus
- /tailwind
- /kotlin
- /gleam
- /react
- /flutter
- /elm
- /ocaml
- /vscode
- /opensuse
- /ash
- /centos
- /php
- /deepseek
- /scala
- /zig
- /html
- /debian
- /nixos
- /lisp
- /agda
- /react-native
- /textmate
- /sublime-text
- /kubuntu
- /arch-linux
- /revery
- /ubuntu
- /manjaro
- /spring
- /django
- /diversity
- /nodejs
- /lua
- /slackware
- /julia
- /c
- /neovim