Choosing the right data type is one of the most important decisions you make when designing a database. It's the foundation of data integrity, query performance, and storage efficiency. Pick one that's too "small," and your application crashes when data overflows. Pick one that's too "large," and you waste disk space and slow down your indexes.

In this deep dive, we’ll explore the core categories of SQL data types and learn exactly when to use each one to build lean, mean, and high-performance databases.
A Real Business Scenario: Picking Types Before a Table Becomes Expensive to Change
Data type decisions feel small when a table is new. They become painful once millions of rows, indexes, and downstream integrations depend on them.
Imagine designing tables for:
- order amounts that must never lose cents
- user IDs that may outgrow an
INT - status fields that should accept only a small set of values
- timestamps that need to align across services in different timezones
The type choice affects correctness first, then performance, then migration cost. That is why type selection is not a cosmetic schema detail.
1. Numeric Types: The Building Blocks
Numbers are the bread and butter of most databases. But not all numbers are created equal.
Integers (Whole Numbers)
Most SQL databases offer several sizes of integers. Choosing the smallest one that safely covers your range can save significant space in large tables.
| Type | Storage | Range | Best For |
|---|---|---|---|
TINYINT | 1 byte | -128 to 127 | Status flags, ages, ratings |
INT | 4 bytes | ±2.1 billion | Most IDs, quantities |
BIGINT | 8 bytes | ±9 quintillion | Global IDs, social media likes |
Decimals and Floating Point
When you need to store parts of a whole (like money or scientific measurements), things get more interesting.
DECIMAL/NUMERIC: Exact numbers. Always use this for money.FLOAT/REAL: Approximate numbers. Great for scientific data, but dangerous for financial calculations due to rounding errors.
Tip: In many databases, 0.1 + 0.1 + ... (10 times) might not equal exactly 1.0 when using FLOAT!
A Common Mistake: Choosing Types Based on the Current Sample Data
Schemas often get designed around the first import file or the first few rows of seed data.
That leads to classic problems:
INTchosen for identifiers that later needBIGINTVARCHAR(20)chosen for values that eventually exceed the guessFLOATused for money because the early demo "looked fine"- text columns used everywhere because they are convenient during ingestion
The better question is not "What fits today's data?" It is "What values should this column be allowed to represent over time?"
2. String Types: Handling Text
Strings are flexible, but they come with specific trade-offs.
CHAR vs VARCHAR
CHAR(n): Fixed length. If you store "SQL" in aCHAR(10)column, it will be padded with spaces to 10 characters. Best for fixed-length codes like ISO country codes (US, CN, UK) or MD5 hashes.VARCHAR(n): Variable length. Only uses as much space as the text plus a small overhead. This is your go-to for names, emails, and descriptions.
TEXT and CLOB
When you need to store long-form content like blog posts or logs, use TEXT. Unlike VARCHAR, TEXT columns are often stored "off-page," which keeps your main table scans fast.
3. Date and Time: Temporal Data
Handling time correctly is notoriously difficult. SQL provides specialized types to help.
DATE: Just the date (YYYY-MM-DD). Use for birthdays or holidays.TIME: Just the time (HH:MM:SS). Use for store opening hours.TIMESTAMP/DATETIME: Both date and time. Pro Tip: Always store these in UTC to avoid time zone headaches!
4. Special Types: JSON and Booleans
Modern SQL is evolving. Many databases now support:
BOOLEAN: True or False. (SQLite uses 0 and 1).JSON/JSONB: For semi-structured data. Great for flexible user settings or API responses.
Best Practices for Choosing Types
- Be Specific, Not Generous: Don't use
VARCHAR(2000)for a username that will never exceed 50 characters. - Standardize on UTC: Never store "local time" in a database. Convert it in the application layer.
- Use the Smallest Int Possible: If you're storing a list of 50 countries, use a small code or a small integer ID.
- Avoid FLOAT for Money: Use
DECIMALorNUMERICto avoid "lost pennies" in rounding.
Boundary and Performance Notes
Data types affect more than storage size:
- wider keys and indexes consume more memory and I/O
- implicit casts can stop indexes from being used efficiently
- mixing types across related tables creates awkward joins and migration risk
- changing a type later may require table rewrites, application changes, and backfills
In other words, the cost of a weak type decision compounds as the schema grows.
When NOT to Over-Optimize Type Size
Being precise is good. Premature micro-optimization is not always worth it.
Avoid obsessing over the smallest possible type when:
- the safer larger type avoids a risky future migration
- the difference is negligible relative to row width and workload
- cross-service interoperability matters more than shaving a few bytes
- the semantic clarity of the type matters more than squeezing storage
The goal is not "smallest possible." The goal is "small enough, correct enough, and stable enough."
Official References
- PostgreSQL numeric types documentation for integer, decimal, and floating-point tradeoffs.
- PostgreSQL character types documentation for
CHAR,VARCHAR, andTEXTbehavior. - SQLite type system documentation for SQLite's dynamic typing model and affinity rules.
Tool Workflow
Use tools when type choices should turn into a concrete schema instead of staying theoretical
Data types become real decisions when you start writing table definitions, importing messy source data, or generating seed data that should match production expectations.
Excel / Sheets to SQL
Paste spreadsheet columns and see quickly where imported values will force weak type inference or unexpected TEXT columns.
Mock Data Generator
Generate schema-aware sample rows once you know what each column type should represent in practice.
Schema Diff
Review the migration impact when a type decision changes from one schema version to the next.
Schema Design Workflow Hub
Use the broader schema workflow when column types, relationships, and migration review all need to stay aligned.
Related Articles
- Designing Your First Database Schema for the broader table-design decisions that sit above individual column types.
- Database Normalization Explained for the next layer of deciding which facts belong in the same table at all.
- Data Cleaning with SQL for the downstream cleanup work when imported values do not fit the types you really want.
Conclusion
Data types are part of the contract of the schema. Choosing them well protects correctness, reduces surprise in queries, and keeps future migrations under control. The right type is the one that matches the business meaning of the column, not just the first value you happened to load.
Next time you write a CREATE TABLE statement, take a moment to ask: "Is this really the best type for this data?"
Join the Conversation
What's your biggest data type "face-palm" moment? Have you ever run out of IDs in an INT column? Let us know in the comments!