MySQL Data Types Reference

All MySQL column types with storage, range, and STRICT mode behavior.

Searchable MySQL and MariaDB data type reference covering integer, fixed and floating point, string, binary, date/time and JSON types — with storage size, value range and STRICT-mode notes. It runs free in your browser on Gera Tools, with nothing uploaded.

Last updated Source: Gera Tools

What is the difference between DATETIME and TIMESTAMP?

DATETIME stores the literal value you give it, independent of time zone, with a wide range up to year 9999. TIMESTAMP is converted to UTC on write and back to the session time zone on read, but only spans 1970 to 2038.

Choose the right MySQL column type

MySQL and MariaDB provide integer, fixed and floating-point, string, binary, date/time and JSON types, each with its own storage cost and range. This reference lets you search those types by name or range and filter by category, so you can size each column correctly. It runs entirely in your browser.

Integer types: size and range at a glance

TypeStorageSigned rangeUnsigned range
TINYINT1 byte-128 to 1270 to 255
SMALLINT2 bytes-32,768 to 32,7670 to 65,535
MEDIUMINT3 bytes-8,388,608 to 8,388,6070 to 16,777,215
INT4 bytes~-2.1B to ~2.1B0 to ~4.3B
BIGINT8 bytes~-9.2 quintillion0 to ~18.4 quintillion

Choose the smallest type that comfortably fits your expected values. A TINYINT column holding a status flag (0-4) saves 3 bytes per row compared to INT, which multiplies across millions of rows and every index entry.

String types: inline vs off-page

TypeMax lengthStorage locationFull-index support
CHAR(n)255 charsInline in rowYes
VARCHAR(n)65,535 bytesInline in rowYes (within prefix limit)
TINYTEXT255 bytesOff-pagePrefix only
TEXT65,535 bytesOff-pagePrefix only
MEDIUMTEXT~16MBOff-pagePrefix only
LONGTEXT~4GBOff-pagePrefix only

VARCHAR stores only the characters used plus a 1 or 2 byte length prefix, while CHAR(n) always occupies exactly n characters. Use VARCHAR for variable-length strings you may index fully; use TEXT family for long content you do not need to index beyond a prefix.

Date and time types: key differences

DATETIME stores an absolute value with no time zone conversion, from 1000-01-01 to 9999-12-31. It is the right choice when the stored value is a wall-clock time that should not change across time zone settings.

TIMESTAMP converts to UTC on write and back to the session time zone on read. Range is only 1970-01-01 to 2038-01-19 (the 32-bit Unix timestamp limit). It is useful for “record when this row was last modified” columns but problematic for historical or future dates outside its range.

DATE stores a date without a time component (3 bytes). TIME stores a duration or time-of-day without a date (3-4 bytes depending on precision).

A typical well-typed table

CREATE TABLE orders (
  id        BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  user_id   INT UNSIGNED NOT NULL,
  total     DECIMAL(12,2) NOT NULL,
  status    ENUM('new','paid','shipped','refunded') NOT NULL,
  created   DATETIME NOT NULL,
  updated   TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  notes     TEXT,
  payload   JSON
);

Common mistakes

  • Using FLOAT or DOUBLE for currency. Binary floating point cannot represent most decimal fractions exactly, causing rounding errors in sums. Always use DECIMAL(M,D) for money.
  • Using DATETIME when you need time zone awareness. If users are in multiple time zones and you need to store a UTC timestamp, TIMESTAMP auto-converts. If you need a wider date range with time zone handling, store DATETIME with a separate timezone column.
  • Forgetting UNSIGNED on auto-increment primary keys. A plain INT runs out at ~2.1 billion rows; INT UNSIGNED doubles that to ~4.3 billion; BIGINT UNSIGNED is effectively unlimited for practical purposes.