Types#
1️⃣ What are “Types” in PostgreSQL?#
A Type defines what kind of data a column, variable, or function can hold.
- You already know built-in types like:
integer
text
boolean
timestamp
The Types section in pgAdmin is about user-defined and advanced types, not the basic ones.
2️⃣ Categories of Types you’ll see#
In PostgreSQL, types fall into these groups:
Built-in (system) types
- Provided by PostgreSQL itself:
int, bigint
text, varchar
json, jsonb
uuid
numeric
These don’t usually appear under Types in pgAdmin because they’re global/system-level.
Composite types (custom row structures)
A composite type is like a struct or record.
Example:
CREATE TYPE address_type AS (
street text,
city text,
zip_code text
);
Usage:
CREATE TABLE users (
id serial,
address address_type
);
- Think:
“A reusable row shape”
Enum types (fixed values)
ENUM = limited set of allowed values
Example:
CREATE TYPE order_status AS ENUM (
'pending',
'paid',
'shipped',
'cancelled'
);
Usage:
CREATE TABLE orders (
id serial,
status order_status
);
✔ Enforces correctness
❌ Hard to change later (requires migrations)
Domain types (restricted base types)
- A domain is:
A base type + rules
Example:
CREATE DOMAIN positive_int AS integer
CHECK (VALUE > 0);
Usage:
CREATE TABLE products (
quantity positive_int
);
- Domains:
Centralize validation
Improve schema readability
Are safer than repeating CHECK constraints
Range types
- Used for ranges like:
dates
numbers
timestamps
Example:
CREATE TABLE bookings (
period daterange
);
Query:
SELECT *
FROM bookings
WHERE period @> DATE '2026-01-10';
- Very powerful for:
availability
scheduling
time windows
Array types
Any type can become an array:
CREATE TABLE posts (
tags text[]
);
Usage:
SELECT * FROM posts WHERE 'sql' = ANY(tags);
Pseudo-types (advanced / internal)
- Examples:
record
anyelement
trigger
- Used mainly in:
functions
triggers
system internals
Example:
RETURNS trigger
You don’t store these in tables.
3️⃣ Where “Types” fit in schema design#
Use case |
Best type |
|---|---|
Reusable structure |
Composite type |
Limited states |
ENUM |
Shared validation |
DOMAIN |
Time ranges |
RANGE |
Multiple values |
ARRAY |
Logic plumbing |
Pseudo-types |
4️⃣ Types vs Tables vs Domains#
Feature |
Purpose |
|---|---|
Table |
Stores data |
Type |
Defines shape |
Domain |
Constrained type |
Function |
Behavior |
Trigger |
Automation |
Types are building blocks, not storage.
5️⃣ What pgAdmin shows under “Types”#
- When you expand Types, pgAdmin lists:
ENUMs
Composite types
Domains (sometimes grouped separately)
Custom range types
System types are hidden.
6️⃣ Production best practices#
✔ Use DOMAIN for shared validation
✔ Use ENUM only for stable values
✔ Prefer lookup tables if values change often
✔ Avoid overusing composite types in APIs
✔ Document every custom type clearly
7️⃣ Mental model (remember this)#
Type = shape of data
Table = storage of data
Function = behavior