Data Types (PostgreSQL)
Schemas
Numbers
Integers
SMALLINT(also aliased toINT2)INTEGER(aliased asINT4)+BIGINT(aliased asINT8)
Numeric
NUMERIC(precision, scale)
- Can hold values bigger than
BIGINT
Floating Point
REALDOUBLE PRECISION
NaN
Infinity
Constraints
Check Constraint
A check constraint is the most generic constraint type. It allows you to specify that the value in a certain column must satisfy a Boolean (truth-value) expression.
CREATE TABLE purchase_item (
price INTEGER CONSTRAINT positive_price CHECK (price > 0),
discount INTEGER CONSTRAINT non_negative_discount CHECK (discount >= 0),
description TEXT (LENGTH(description) < 2048)
);
You can also apply a CHECK constraint to the entire table and can involve multiple columns.
CREATE TABLE purchase_item (
price INTEGER CONSTRAINT positive_price CHECK (price > 0),
discount INTEGER CONSTRAINT non_negative_discount CHECK (discount >= 0),
description TEXT (LENGTH(description) < 2048),
CHECK (price > discount)
);
Unique Constraints
Ensures that the data contained in a column (or in a group of columns) is unique.
CREATE TABLE products (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
brand TEXT UNIQUE NOT NULL,
product_no TEXT UNIQUE NOT NULL,
name TEXT NOT NULL,
);
-- or
CREATE TABLE products (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
brand TEXT NOT NULL,
product_no TEXT NOT NULL,
name TEXT NOT NULL,
UNIQUE (brand, product_no)
);
Exclude Constraints
CREATE EXTENSION IF NOT EXISTS btree_gist;
CREATE TABLE bookings (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
-- TODO: use proper enums for this in real life
status TEXT NOT NULL;
-- The time the resource will be allocated to someone else
reservation_period TSRANGE;
-- For a given booking, there can be no overlaps, unless
-- the current booking status is set to 'cancelled'.
EXCLUDE USING gist (id WITH =, reservation_period WITH &&) WHERE (reservation_status != 'cancelled')
);
Primary Key Constraint
Foreign Key Constraints
A foreign key constraint specifies that the values in a column (or a group of columns) must match the values appearing in some row of another table. We say this maintains the referential integrity between two related tables.
CREATE TABLE products (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
brand TEXT NOT NULL,
product_no TEXT NOT NULL,
name TEXT NOT NULL,
UNIQUE (brand, product_no)
);
CREATE TABLE orders (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
product_id BIGINT REFERENCES products(id),
quantity INTEGER order_must_be_positive CHECK (quantity > 0)
);
Domain Types
CREATE DOMAIN us_postal_code AS TEXT
CHECK(VALUE ~ '^\d{5}$' OR VALUE ~ '^\d{5}-\d{4}$'
);
Binary Data
UUIDs
Booleans
Enums
CREATE TYPE mood AS ENUM ('sad', 'neutral', 'happy');
-- You can also add another value later, and set its position
ALTER TYPE mood ADD VALUE 'afraid' AFTER 'sad';
Removing a value from an ENUM is tricky, you need to drop the old type and
recreate a new one, making sure all tables default the old value to something else.
-- Always do it inside a transaction
BEGIN;
-- Rename old type
ALTER TYPE mood RENAME TO mood_old;
-- Create a new type
CREATE TYPE mood AS ENUM ('sad', 'neutral', 'happy');
-- Update any tables that use this type, default old
-- removed value to something else.
UPDATE
<table_with_enum>
SET
current_mood = 'neutral'
WHERE
current_mood NOT IN ('sad', 'neutral', 'happy');
-- Switch to the new type
ALTER TABLE <table_with_enum>
ALTER COLUMN current_mood
TYPE mood USING mood_old::text::status_enum;
COMMIT;
Timestamps
Built-In Functions
to_timestap
Setting a DB Timezone
SET TIME ZONE 'UTC';
Dates & Time
Magic Constants
CURRENT_DATECURRENT_TIMECURRRENT_TIMESTAMPLOCALTIMELOCALTIMESTAMP
Intervals
Serial
Sequences
CREATE SEQUENCE IF NOT EXISTS some_seq
AS BIGINT
START WITH 1
INCREMENT BY 1
MINVALUE 1;
SELECT NEXTVAL('some_seq');SELECT CURRVAL('some_seq');Outputs the current value of the session, not the global sequence value.
SELECT SETVAL('some_seq', 1000);
Identity
CREATE TABLE user (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
...,
);
-- To find out the internal name of the sequence
-- being used.
SELECT pg_get_serial_sequence('user', 'id');
Network Types
JSON
Arrays
PostgreSQL allows columns of a table to be defined as variable-length multidimensional arrays. Arrays of any built-in or user-defined base type, enum type, composite type, range type, or domain can be created.
Declaration
CREATE TABLE tictactoe (
squares INTEGER[3][3]
);
- Arrays indexes start at 1, not 0.
Generated Columns
A generated column is a special column that is always computed from other columns. Thus, it is for columns what a view is for tables.
CREATE TABLE people (
...,
height_cm numeric,
-- The keyword STORED must be specified to choose the
-- stored kind of generated column.
height_in numeric GENERATED ALWAYS AS (height_cm / 2.54) STORED
);
Text Search Types
Bit String
Ranges
PostgreSQL comes with the following built-in range types:
| Type | Data Type |
|---|---|
int4range |
INTEGER |
int8range |
BIGINT |
numrange |
NUMERIC |
tsrange |
TIMESTAMP |
tstzrange |
TIMESTAMP WITH TIMEZONE |
daterange |
DATE |
CREATE TABLE reservation (room int, during tsrange);
INSERT INTO reservation VALUES
(1108, '[2010-01-01 14:30, 2010-01-01 15:30)');
-- Containment
SELECT int4range(10, 20) @> 3;
-- Overlaps
SELECT numrange(11.1, 22.2) && numrange(20.0, 30.0);
-- Extract the upper bound
SELECT upper(int8range(15, 25));
-- Compute the intersection
SELECT int4range(10, 20) * int4range(15, 25);
-- Is the range empty?
SELECT isempty(numrange(1, 5));