Domains
CREATE DOMAIN ... with a constraint
CREATE DOMAIN order_status_domain AS text CHECK (VALUE IN ('pending','paid')); What this does
Creating the domain itself is cheap and takes only ACCESS SHARE, but domains with constraints have poor support for online migrations later: every future column that uses the domain inherits the constrained-domain risk (see ADD COLUMN using a constrained domain type above), and there is no built-in expand/contract path for changing the constraint once tables depend on it.
Safe rewrite
Prefer table-level CHECK constraints, which can be added, validated, and dropped per table
ALTER TABLE orders ADD CONSTRAINT orders_status_check CHECK (status IN ('pending','paid')) NOT VALID;
ALTER TABLE orders VALIDATE CONSTRAINT orders_status_check;