Numeric data type

Numerical data are divided into exact and approximate, integer and real. Bit values are a separate category.

Exact integers

TypeMemory sizeRange
TINYINT1 bytefrom -128 to 127 (from -27 to 27-1)
from 0 to 255 (from 0 to 28-1)
SMALLINT2 bytesfrom -32768 to 32767 (from -215 to 215-1)
from 0 to 65535 (from 0 to 216-1)
MEDIUMINT3 bytesfrom -223 to 223-1
from 0 to 224-1
INT
INTEGER
(aliases)
4 bytesfrom -231 to 231-1
from 0 to 232-1
BIGINT8 bytesfrom -263 to 263-1
from 0 to 264-1

Integers can be declared with the UNSIGNED keyword. In that case the column can no longer hold negative values, and its valid range doubles. So TINYINT accepts values from -128 to 127, while TINYINT UNSIGNED accepts values from 0 to 255.

Exact real numbers

TypeRange
DEC[(M,D)]
DECIMAL[(M,D)]
(aliases)
Depends on M and D parameters

The DECIMAL type stores exact real numbers. It is used when accuracy is critical — for example, when storing financial data.

Usage example:

MySQL 8.1
CREATE TABLE Users (
    ...
    salary DECIMAL(5,2)
);

This example declares that the salary column stores numbers with a maximum of 5 digits, 2 of which are reserved for the decimal part. So the column holds values in the range from -999.99 to 999.99.

The DECIMAL syntax is equivalent to DECIMAL(M) and DECIMAL(M,0). By default, the M parameter is 10.

The integer part and the fractional part are stored as two separate integers, which makes the memory footprint easy to calculate. For DECIMAL(5,2), the integer part has 3 digits and takes 2 bytes, while the fractional part has 2 digits and needs just 1 byte — 3 bytes in total.

Bit numbers

TypeMemory sizeRange
BIT[(M)]M bitFrom 1 to 64 bits, depending on the M parameter
BOOL
BOOLEAN
(aliases)
1 bitEither 0 or 1

The BIT(M) type stores a bit sequence of a given length. By default, the length is 8 bits. If the value assigned to such a column uses fewer than M bits, it is padded with zeros on the left. For example, writing b'101' to a BIT(6) column ends up stored as b'000101'.

Approximate numbers

TypeMemory sizeRange
FLOAT[(M, D)]4 bytesMinimum value ±1.17·10-39
Maximum value ±3.4·1038
REAL[(M, D)]
DOUBLE[(M, D)]
(aliases)
8 bytesMinimum value ±2.22·10-308
Maximum value ±1.79·10308

Floating-point numeric types can also take the UNSIGNED attribute. As with integer types, it prevents negative values in the column, but — unlike integer types — the maximum range of column values stays the same.

Integer numbers

TypeMemory sizeRange
SMALLINT2 bytesfrom -32768 to 32767
INT
INTEGER
(aliases)
4 bytesfrom -2147483648 to 2147483647
BIGINT8 bytesfrom -9223372036854775808 to 9223372036854775807

Auto-increment types

TypeMemory sizeRange
SMALLSERIAL2 bytesfrom 1 to 32767
SERIAL4 bytesfrom 1 to 2147483647
BIGSERIAL8 bytesfrom 1 to 9223372036854775807

The SERIAL types are pseudo-types for creating auto-incrementing columns. SERIAL is equivalent to INTEGER with an automatically created sequence.

Exact real numbers

TypePrecisionRange
DECIMAL[(precision, scale)]
NUMERIC[(precision, scale)]
(aliases)
User-definedUp to 131072 digits before decimal point and up to 16383 digits after

The NUMERIC type stores exact real numbers. It is used when accuracy is critical — for example, when storing financial data.

Usage example:

MySQL 8.1
CREATE TABLE Users (
    ...
    salary NUMERIC(10,2)
);

This example declares that the salary column stores numbers with a maximum of 10 digits, 2 of which are reserved for the decimal part. So the column holds values in the range from -99999999.99 to 99999999.99.

Approximate numbers

TypeMemory sizePrecisionRange
REAL4 bytes6 digitsfrom 1E-37 to 1E+37
DOUBLE PRECISION8 bytes15 digitsfrom 1E-307 to 1E+308

Floating point types are used for approximate calculations. PostgreSQL also supports special values: Infinity, -Infinity and NaN (not a number).