Skip to content
gohacks.dev
Databases

MySQL Data Types

Every MySQL data type with its storage size, range and the practical notes: integers, DECIMAL for money, VARCHAR and TEXT limits, DATETIME versus TIMESTAMP and the 2038 problem, JSON and VECTOR.

Free · No sign-up · Your inputs stay in your browser

Reference

MySQL data types

TypeStorageRange and notes
TINYINT1 byte-128 to 127, or 0 to 255 UNSIGNED. BOOLEAN is an alias for TINYINT(1).
SMALLINT2 bytes-32,768 to 32,767, or 0 to 65,535 UNSIGNED.
MEDIUMINT3 bytes-8,388,608 to 8,388,607, or 0 to 16,777,215 UNSIGNED.
INT4 bytes-2,147,483,648 to 2,147,483,647, or up to 4,294,967,295 UNSIGNED. The (11) display width is deprecated and ignored.
BIGINT8 bytes±9.2 × 10^18, or up to 1.8 × 10^19 UNSIGNED. Laravel's id() is BIGINT UNSIGNED.
DECIMAL(M,D)about 4 bytes per 9 digitsExact. Up to 65 digits. Use for money: DECIMAL(19,4) or integer cents.
FLOAT / DOUBLE4 / 8 bytesApproximate binary floating point; never for money.
BIT(M)(M+7)/8 bytes1 to 64 bits.
CHAR(N)N × max bytes per charFixed length, padded; N up to 255 characters.
VARCHAR(N)length + 1 or 2 bytesN in characters; the whole row is limited to 65,535 bytes. With utf8mb4 an indexed VARCHAR(255) uses up to 1,020 bytes.
TINYTEXT / TEXT / MEDIUMTEXT / LONGTEXT+1 / 2 / 3 / 4 bytesUp to 255 B, 64 KiB, 16 MiB, 4 GiB. Cannot have a default before MySQL 8.0.13; indexes need a prefix length.
BINARY(N) / VARBINARY(N)like CHAR / VARCHARBytes, compared byte by byte. BINARY(16) stores a UUID in 16 bytes.
TINYBLOB ... LONGBLOBas the TEXT typesBinary data; usually better kept in object storage.
DATE3 bytes1000-01-01 to 9999-12-31.
DATETIME(fsp)5 bytes + fractional1000-01-01 to 9999-12-31 23:59:59, no time zone. fsp 0-6 for fractions of a second.
TIMESTAMP(fsp)4 bytes + fractional1970-01-01 00:00:01 to 2038-01-19 03:14:07 UTC, stored in UTC and converted to the session time zone. The 2038 limit is real.
TIME(fsp)3 bytes + fractional-838:59:59 to 838:59:59: a duration as much as a time of day.
YEAR1 byte1901 to 2155.
JSONlike LONGBLOBValidated and stored in a binary format; index a field through a generated column or a functional index.
ENUM('a','b')1 or 2 bytesUp to 65,535 values; adding one at the end is cheap, reordering rewrites the table.
SET('a','b')1 to 8 bytesUp to 64 members, several at once.
GEOMETRY / POINTvariableSpatial types with SPATIAL indexes; POINT with SRID 4326 for latitude and longitude.
VECTOR(N)4 × N bytesMySQL 9.0+: N single-precision floats for embeddings.

For MySQL 8.0 and 8.4 LTS with InnoDB; MariaDB matches for everything but JSON (an alias of LONGTEXT there) and VECTOR. Choose the smallest type that fits for good reason: every secondary index repeats the primary key, so a BIGINT key costs 4 bytes more in every index than an INT one.

Choices that matter later

TIMESTAMP stores UTC and converts to the session time zone, but ends on 19 January 2038; DATETIME has no zone and lasts until 9999. DECIMAL is exact and FLOAT is not, so money belongs in DECIMAL or integer cents. The INT(11) display width is deprecated and means nothing. The data type storage requirements page is the reference.

Smaller keys, smaller indexes

In InnoDB every secondary index stores the primary key, so a key type four bytes larger costs four bytes in every index entry. Choose BIGINT where you need its range, not by default everywhere.

Share

Frequently asked questions

What is the maximum length of VARCHAR in MySQL?
65,535 bytes for the whole row, shared by all columns. With utf8mb4 (up to 4 bytes per character) a single VARCHAR can hold at most about 16,383 characters.
Should I use DATETIME or TIMESTAMP?
DATETIME for most application dates, especially beyond 2038; store UTC and convert in the application. TIMESTAMP suits automatic created and updated columns within its range.
Is what I paste sent anywhere?
No. The tool runs entirely in your browser with JavaScript. Nothing you type or paste is sent to our server or stored.

Keep planning

Similar tools