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
REAL
DOUBLE 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_DATE
CURRENT_TIME
CURRRENT_TIMESTAMP
LOCALTIME
LOCALTIMESTAMP
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));