DevLearningTools

LEARN · SQL

SQL Data Types

Every column has a type that controls what it can store. Learn the common SQL data types, how numeric, text, date, and boolean types differ across databases, and how to pick the right one.

Every column in a table is declared with a data type, and the database enforces it: try to store text in a numeric column and it's rejected or silently converted, depending on the database. Picking the right type up front avoids a surprising amount of pain later, wasted storage, broken sorting, and values that don't compare the way you expect.

Learning Objectives

  • Identify the main categories of SQL data types: numeric, text, date/time, and boolean.
  • Choose an appropriate type for a given column instead of defaulting to text for everything.
  • Recognize where type names genuinely differ between MySQL, PostgreSQL, SQLite, and SQL Server.

Column Defined

e.g. salary DECIMAL(10,2)

Value Submitted

INSERT or UPDATE

Type Checked

Does it fit the column's type?

Stored or Rejected

Valid data saved, bad data errors

The Main Categories

CategoryStoresExample
NumericWhole numbers or decimalsage, salary, quantity
TextCharacters and stringsfirst_name, email, description
Date/TimeCalendar dates and timestampscreated_at, birth_date
BooleanTrue/false valuesis_active, email_verified

Numeric Types

Whole numbers use an integer type, and numbers with decimal places use a fixed-precision type (exact, good for money) or a floating-point type (approximate, good for scientific values where tiny rounding error doesn't matter). The keywords differ slightly by database, but the concepts are identical everywhere.

MySQL
CREATE TABLE employees (
  id INT PRIMARY KEY,
  salary DECIMAL(10,2)
);
PostgreSQL
CREATE TABLE employees (
  id INTEGER PRIMARY KEY,
  salary NUMERIC(10,2)
);
SQL Server
CREATE TABLE employees (
  id INT PRIMARY KEY,
  salary DECIMAL(10,2)
);
SQLite
CREATE TABLE employees (
  id INTEGER PRIMARY KEY,
  salary NUMERIC
);
-- SQLite uses "type affinity" rather than strict types,
-- NUMERIC still stores salary as an exact value here.
NOTE

DECIMAL and NUMERIC are the same thing, exact decimal storage with no rounding error, which is why they're the right choice for money. FLOAT and DOUBLE are approximate and can introduce tiny rounding errors, fine for scientific data, risky for currency.

Text Types

VARCHAR is the default choice for most text columns, names, emails, titles. Reach for TEXT when a column genuinely has no practical size limit, like a blog post body or a product description.

TypeWhat it's for
CHAR(n)Fixed-length text, padded with spaces to exactly n characters
VARCHAR(n)Variable-length text, up to a maximum of n characters
TEXTVariable-length text with no practical length limit
MySQL / PostgreSQL / SQL Server
CREATE TABLE employees (
  first_name VARCHAR(100),
  bio TEXT
);
SQLite
CREATE TABLE employees (
  first_name TEXT,
  bio TEXT
);
-- SQLite stores all text as TEXT regardless of a declared length,
-- VARCHAR(100) is accepted as valid syntax but the 100 isn't enforced.

Date and Time Types

DatabaseDate onlyDate + time
MySQLDATEDATETIME or TIMESTAMP
PostgreSQLDATETIMESTAMP
SQL ServerDATEDATETIME2
SQLiteTEXT (ISO 8601 string)TEXT (ISO 8601 string)
NOTE

SQLite has no dedicated date/time type at all, dates are conventionally stored as ISO 8601 text ('2026-10-13') or as numbers, and SQLite's date functions understand that text format. Every other database here has real DATE and timestamp types that are validated and stored efficiently.

Boolean Values

PostgreSQL and SQL Server have a real boolean type (BOOLEAN in PostgreSQL, BIT in SQL Server, storing 0 or 1). MySQL and SQLite don't, MySQL's BOOLEAN is just an alias for TINYINT(1), and SQLite stores booleans as the integers 0 and 1 with no dedicated type at all. The practical effect is the same everywhere: a two-state column that your application treats as true/false.

Frequently Asked Questions

Should I always use VARCHAR instead of CHAR?

Almost always, yes. CHAR pads shorter values with spaces to a fixed length, which wastes storage and can cause subtle comparison bugs if trailing spaces aren't handled consistently. CHAR is really only worth it for genuinely fixed-length codes, like a two-letter country code.

What happens if I insert text into a numeric column?

It depends on the database. PostgreSQL and SQL Server reject it outright with an error. MySQL, depending on its SQL mode, may either reject it or silently convert/truncate it, strict mode (the modern default) rejects it. SQLite is the most permissive, due to type affinity, and may store it as-is.

Is there a real difference between TEXT and VARCHAR(255) if I never go over 255 characters?

In PostgreSQL, practically no performance difference, VARCHAR(255) just adds a length check. In MySQL, TEXT is stored differently from VARCHAR internally and can't always be indexed the same way, so VARCHAR is still preferred when you know a reasonable max length.

Common Beginner Mistakes

Using FLOAT or DOUBLE for money

Floating-point types are approximate by design, and small rounding errors accumulate. Two values that should be equal can compare as not-equal after arithmetic. Always use DECIMAL/NUMERIC for currency.

Defaulting every column to TEXT or VARCHAR(255) regardless of what it stores

A date stored as text loses date arithmetic, sorting by calendar order, and validation, you lose everything the database would otherwise guarantee for you. Use the type that actually matches the data.

Assuming SQLite enforces column types as strictly as other databases

SQLite's type affinity is lenient by design, it will often accept and store a value of the "wrong" type without complaint. Code that relies on SQLite rejecting bad data can break silently when the same schema runs on MySQL or PostgreSQL, which enforce types strictly.

Best Practices

  • Use DECIMAL/NUMERIC for any value involving money, never FLOAT or DOUBLE.
  • Default to VARCHAR with a sensible length for short text, reserve TEXT for genuinely unbounded content.
  • Use a real date/time type (not text) on every database that offers one, so the database validates and sorts dates correctly.
  • Pick the smallest numeric type that comfortably fits your data's range, it saves storage at scale without any downside.

Interview Questions

Why is DECIMAL preferred over FLOAT for storing prices?

FLOAT and DOUBLE store an approximation of a decimal value in binary, which can introduce small rounding errors, 0.1 + 0.2 famously doesn't equal exactly 0.3 in floating-point arithmetic. DECIMAL/NUMERIC store the exact decimal value, no rounding error, which matters when prices must add up exactly.

What's the practical difference between CHAR(10) and VARCHAR(10)?

CHAR(10) always consumes space for 10 characters, padding shorter values with spaces. VARCHAR(10) only consumes space for the actual value plus a small length prefix, up to a 10-character maximum. CHAR(10) VALUES ('yes') right-pads to 'yes ', which can cause an unexpected comparison mismatch, e.g. in SQL Server, 'yes' = 'yes ' is sometimes true but string length differs, catching developers off guard.

How does SQLite's type affinity differ from strict typing in MySQL or PostgreSQL?

MySQL and PostgreSQL validate a value against its column's declared type and reject a mismatch (in strict mode). SQLite instead assigns each column a "type affinity" (a preference, not a rule), and will still store a value even if it doesn't match that affinity. A column declared INTEGER in SQLite can still technically hold text.

Write a column definition for a product price that must be exact to the cent.

price DECIMAL(10,2) — 10 total digits, 2 of them after the decimal point, giving exact storage up to 99,999,999.99 with no floating-point rounding risk.

Summary

This lesson covered the main SQL data type categories, numeric, text, date/time, and boolean, and where their exact names and behavior genuinely differ between MySQL, PostgreSQL, SQL Server, and SQLite's more lenient type affinity system.

What's Next?

With data types covered, the next lesson starts writing data: INSERT, adding new rows to a table.

</>

Ready to Practice SQL?

Write and run real SQL queries online, right in your browser, no install or signup required. Pick a playground based on which database you want to practice on.

SQLite / PostgreSQL

Fast, no server, no ads.

Open DB Fiddle ↗

MySQL / SQL Server

Switch databases with one dropdown.

Open SQL Fiddle ↗

Both open a third-party SQL playground in a new tab. External site terms and privacy policy apply.