Columns
What Are Columns in PostgreSQL?
A column in a relational database is a named and typed collection of data intersecting with unnamed and untyped row or rows.
An intersection of a column and a row is called a cell. The cell stores a piece of data with the type imposed by the column type.
Column Data Types
What is a Column Data Type?
A column data type is a limitation of manner in which a data piece can be stored in a given column.
For example a column with integer
data type can store whole numbers (e.g. 42
) but not floating point numbers (e.g. 42.42
) nor words (e.g. forty two
).
Built-In Data Types
There are tens of built-in data types in Postgres.
The most widely used data types are:
-
integer
- a 16-bit signed integer, -
double precision float
, -
varchar
(akatext
) - variable-length strings, -
boolean
, -
date
, -
time
, -
timestamp
, -
uuid
.
Other commonly used data types are
-
smallint
- a 8-bit signed integer, -
bigint
- a 64-bit signed integer, -
numeric
- a selectable precision decimal, -
real
- a single precision float, -
char
- a fixed-length string, -
json
, -
jsonb
- decomposed JSON -
xml
.
There are also datatypes dedicated to storing byte data.
Custom Data Types
Postgres allows for creating new custom data types.
serial & bigserial
serial
and bigserial
are not actual Postgres data types but a shorthand for creating a column with auto-incrementing integer
(serial
) or bigint
(bigserial
) data types with NOT NULL
constraint applied.
serial
& bigserial
do not apply UNIQUE
, nor PRIMARY KEY
constraints automatically.
Using serial
& bigserial
is not the only way of applying auto-incrementation. Auto-incrementation can also be applied manually using DEFAULT nextval('tablename_colname_seq')
.
Column Constraints
What is a Column Constraint?
A column constraint is a limitation of acceptable data values that can be stored in the column cells.
A column can be constrained with more than one constraint at the same time.
Built-in Column Constrains
PostgreSQL features the following built-in column constraints:
-
check,
-
primary key,
-
foreign key,
-
not null, and
-
unique.
Check Constraint
The check constraint is a limitation of acceptable data values that can be stored in the column cells through verifying whether a value - before it is stored - satisfies a provided boolean expression.
For example, to ensure that a user age
is always positive the CHECK (age > 0)
constraint can be used.
CREATE TABLE users (
age integer CHECK (age > 0)
);
Primary Key Constraint
The primary key constraint is a limitation of acceptable data values that can be stored in column cells through allowing:
-
only unique values, and
-
only not null values.
A given table can have only one primary key.
CREATE TABLE users (
id serial PRIMARY KEY
);
A primary key constraint can constrain multiple columns at the same time creating a multi‑column primary key.
Foreign Key Constraint
The foreign key constraint is a limitation of acceptable data values that can be stored in column cells through allowing only values that have their counterparts as primary keys of other tables to which they reference. This ensures a so called referential integrity
.
CREATE TABLE orders (
user_id integer REFERENCES users (id)
);
The orders
table is the referencing table and the users
table is the referenced table.
The referenced column name (in the above case (id)
) can be omitted if the id
column is the primary key of the referenced table.
A given table can have many foreign keys.
A foreign key constraint can constrain multiple columns at the same time if it references a multi‑column primary key.
It is allowed for a table to reference itself.
Not Null Constraint
The not null constraint is a limitation of acceptable data values that can be stored in column cells through allowing only not null values.
CREATE TABLE users (
email VARCHAR (256) NOT NULL
);
Unique Constraint
The unique constraint is a limitation of acceptable data values that can be stored in column cells through allowing only unique values.
CREATE TABLE users (
token VARCHAR (256) UNIQUE
);
A unique constraint automatically applies a B-tree index on the relevant column or columns.
Table Constraints
It is possible to apply a constraint to more than one column using a table constraint.
A table constraint is a constraint applied on a table as a whole instead of a specific one column.
For example, it is possible apply a unique constraint to two columns to ensure that no two same combinations of values are present in the table. However, such a two-column unique constraint does not disallow from duplicated values in each column separately as only the combinations have to be unique. Further, combinations with null
values in any of the columns count as unique.
CREATE TABLE users (
first_name VARCHAR (256),
last_name VARCHAR (256),
UNIQUE (first_name, last_name)
);
A table constraint can compare values from two columns before allowing them to be saved.
CREATE TABLE users (
price numeric,
discount numeric,
CHECK (price > discount)
);
A multi-column check constraint is satisfied if its boolean expression evaluates to true
or null
. Therefore, caution is advised as some expressions evaluate to null
when any of their operands are null
.
Naming Constraints
For easier referencing it is possible to name constraints.
Both, column and table, constraints can be named.
If no constraint name is provided Postgres chooses one automatically.
Adding Constraints to Existing Tables & Columns
It is possible add both table and column constraints associated with already existing columns using the ALTER TABLE
and ALTER COLUMN
commands.
ALTER TABLE users ADD UNIQUE (first_name, last_name);
ALTER TABLE users ALTER COLUMN first_name SET NOT NULL;
Dropping Constraints
To drop a constraint - other than a not null constraint which does not have a name - it is required to know its name. The constraint name could have been granted to it explicitly or automatically.
ALTER TABLE users DROP CONSTRAINT users_email_key;
ALTER TABLE users ALTER COLUMN first_name DROP NOT NULL;
To get constraint names for a given table use the \d
internal command appended with the table name.
\d users
Column Defaults
A column default value is a piece of data that is stored in the column cell when creating a new row when:
-
no value is provided for that cell, or
-
the command creating the row explicitly calls for the default column value for that cell.
When no default value is explicitly set for a given column the default value is NULL
.
To create a column with a default value use the DEFAULT
key word appended with the default value.
CREATE TABLE users (
occupation VARCHAR(256) DEFAULT 'Database Engineer'
);
ALTER TABLE users ALTER COLUMN occupation SET DEFAULT 'Full-Stack Engineer';
To drop an explicit column default value and restore the implicit NULL
default value use the DROP DEFAULT
command..
ALTER TABLE users ALTER COLUMN occupation DROP DEFAULT;
Adding Columns
To add a column to an existing table use the ALTER TABLE ... ADD COLUMN
command appended with the column name, type and optional constraints.
ALTER TABLE users
ADD COLUMN last_name VARCHAR(256) NOT NULL;
Renaming Columns
To rename a column use the ALTER TABLE ... RENAME COLUMN
command.
ALTER TABLE users
RENAME COLUMN email TO email_address;
Listing Columns
Listing Columns with psql
To list columns in a given table with psql use the \d+
internal command appended with the table name.
=> \d+ users
Listing Columns with SQL
To list columns in a given table with SQL select all rows from information_schema.columns
where table_name
equals the contemplated table name.
SELECT *
FROM information_schema.columns
WHERE table_name = 'users';
Dropping Columns
To drop a column use the ALTER TABLE ... DROP COLUMN
command appended with the column name.
ALTER TABLE users DROP COLUMN last_name;