The Day a “Small” Data Type Choice Slowed Down Everything
A production-focused deep dive into MySQL data types, covering numeric types, DECIMAL vs FLOAT, CHAR vs VARCHAR, and DATETIME vs TIMESTAMP with real-world debugging insights.

I am a full-stack developer (currently working with cognizant) who is passionate about web development and creating digital products with innovative solutions.
I hold 6+ years of experience in development, understanding clients' unique needs, and delivering quality code. I've honed my coding skills over these years through both my professional exposure and self-study. Have worked with teams that have used agile development methodology.
I am someone who likes to keep acquiring new skills and capabilities. And when I am not a web developer, I enjoy reading, writing and running.
My interests include:
- Exploring new ideas
- Learning about future tech & products
- Finding user-friendly solutions to tech-related problems
- Sharing my knowledge with close acquaintances
We didn’t change the business logic.
We didn’t deploy a new feature.
We didn’t add traffic.
But suddenly:
Queries were slower.
Backups were heavier.
Replication lag increased.
Financial totals were “slightly off.”
Nothing obvious was broken.
But something felt wrong.
After hours of profiling and EXPLAIN plans, we found it.
Not a bug.
Not a missing index.
A schema mistake.
We had chosen the wrong data types months ago.
And now the database was charging us interest.
That was the day I stopped thinking of MySQL data types as “basic SQL.”
Because data types are not syntax.
They are architecture.
In this guide, we are going to explore 4 key concepts to help you master MySQL data types in real production systems:
Numeric types — INT, TINYINT, BIGINT
DECIMAL vs FLOAT vs DOUBLE
CHAR vs VARCHAR
DATE, DATETIME, and TIMESTAMP
This isn’t about memorizing ranges.
This is about avoiding performance debt and financial bugs.
1️⃣ Data Types: The Containers That Define Your System
Data types define how MySQL stores data internally.
But internally is where scale lives.
They determine:
Storage size
Index size
Memory usage
Accuracy
Query performance
The Container Analogy (Expanded)
Imagine your database as a warehouse.
Each column is a storage shelf.
Data types are the box sizes.
If you store tiny items in giant boxes:
You waste space.
You reduce efficiency.
You slow down movement.
If you store large items in tiny boxes:
They overflow.
They break.
They get rejected.
Choosing the right type is choosing the right container.
And warehouses don’t forgive bad logistics.
🔢 Numeric Types — INT, TINYINT, BIGINT
What They Are
Whole number types with different ranges and storage sizes:
| Type | Range (Signed) | Storage |
|---|---|---|
| TINYINT | -128 to 127 | 1 byte |
| INT | ~2 billion | 4 bytes |
| BIGINT | Very large | 8 bytes |
Looks harmless.
It’s not.
Production Scenario: Inventory System
You’re building an inventory platform.
You need:
Product ID
Stock quantity
is_active flag
CREATE TABLE inventory (
id INT AUTO_INCREMENT PRIMARY KEY,
product_name VARCHAR(100),
quantity INT,
is_active TINYINT
);
Clean.
Efficient.
Correct.
What Happens If You Use BIGINT Everywhere?
I’ve seen this mindset:
“Storage is cheap. Let’s future-proof.”
Here’s what actually happens at scale:
BIGINT doubles storage compared to INT.
Indexes double in size.
Cache efficiency drops.
Joins become heavier.
Backup size increases.
Replication takes longer.
Multiply 4 extra bytes × 50 million rows.
That’s 200MB — just for one column.
Now multiply that across multiple indexes.
Suddenly “just in case” becomes infrastructure cost.
Senior Dev Perspective
Use BIGINT when:
You expect extremely high row counts.
You use distributed ID generators.
You design global-scale systems.
Otherwise?
INT is enough for most applications.
Smaller types → smaller indexes → faster joins.
That’s not theory.
That’s physics.
💰 DECIMAL vs FLOAT vs DOUBLE — The Finance Trap
This is where junior mistakes become executive-level problems.
DECIMAL — Exact Precision
price DECIMAL(8,2)
8 total digits
2 digits after decimal
Stored exactly.
Perfect for:
Prices
Banking balances
Invoices
Accounting
FLOAT and DOUBLE — Approximate Precision
| Type | Approximate Precision |
|---|---|
| FLOAT | ~7 digits |
| DOUBLE | ~15 digits |
Stored in binary floating-point format.
Which means:
0.1 + 0.2 may not equal exactly 0.3.
Debugging Scenario: The Rounding Ghost
Imagine:
You calculate monthly totals using FLOAT.
Individually, everything looks fine.
But when aggregated:
Total revenue = 9999.99999997
Now finance flags discrepancies.
Auditors ask questions.
Customers notice invoice mismatches.
All because of binary approximation.
Senior Dev Perspective
Rule:
Money → DECIMAL
Analytics → DOUBLE
Never FLOAT for finance
Rounding errors in financial systems are not “bugs.”
They’re liability.
🔤 CHAR vs VARCHAR — The Silent Storage Leak
This looks small.
But small schema decisions compound.
VARCHAR — Flexible Storage
name VARCHAR(100)
Stores only actual length.
Ideal for user input.
Efficient.
If name is 5 characters, it stores 5 characters.
CHAR — Fixed Length
country_code CHAR(2)
Always uses full length.
Predictable storage.
Faster for fixed-size values.
Perfect for:
Country codes
State abbreviations
ISO codes
Fixed-length hashes
What Happens If You Use CHAR Wrong?
Let’s say:
You store usernames as CHAR(100).
Every row uses 100 characters — even if the name is 6 letters.
Multiply that across millions of users.
Your disk grows.
Backups grow.
Replication slows.
I/O increases.
All because of one column.
Senior Dev Perspective
Use CHAR when:
Length is guaranteed fixed.
You want predictable storage.
Use VARCHAR otherwise.
Don’t guess.
📅 DATE vs DATETIME vs TIMESTAMP — Where Time Gets Dangerous
Time is easy.
Timezones are not.
Example Table
CREATE TABLE people (
name VARCHAR(100),
birthdate DATE,
birthtime TIME,
birthdt DATETIME
);
What They Store
| Type | Stores |
|---|---|
| DATE | Date only |
| TIME | Time only |
| DATETIME | Full date & time |
| TIMESTAMP | Date & time (smaller range) |
The difference isn’t cosmetic.
It’s operational.
DATETIME vs TIMESTAMP — The Critical Differences
| Feature | DATETIME | TIMESTAMP |
|---|---|---|
| Storage | 8 bytes | 4 bytes |
| Timezone | No auto conversion | Timezone-aware |
| Use case | Historical records | Metadata |
TIMESTAMP auto-adjusts based on timezone.
DATETIME does not.
Debugging Scenario: The Timezone Nightmare
You deploy globally.
App servers run in different regions.
You store audit logs as DATETIME.
Suddenly:
Logs appear out of order.
Reports shift by hours.
Analytics dashboards look wrong.
Support says, “User created account at 10:00 PM.”
Logs say 4:30 AM.
You lose trust in your own system.
Correct Usage
Use TIMESTAMP for:
created_at
updated_at
log metadata
CREATE TABLE captions (
text VARCHAR(150),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE captions2 (
text VARCHAR(150),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
Always standardize to UTC.
Timezones are optional for users.
They are not optional for engineers.
📆 Date & Time Functions — Power for Reporting
SELECT DAY(birthdate), MONTHNAME(birthdate), YEAR(birthdate) FROM people;
SELECT DATE_FORMAT(birthdate, '%a %b %D') FROM people;
Used for:
Monthly reports
Time-based analytics
Business dashboards
Correct data types make this efficient.
Wrong ones make this painful.
❌ Common Pitfalls (We’ve All Done One)
Using FLOAT for money
Using BIGINT everywhere
Using CHAR for user input
Ignoring timezone handling
Storing dates as VARCHAR
Storing dates as VARCHAR deserves a special mention.
That’s not technical debt.
That’s schema sabotage.
🛠 DevOps & SRE View
Data types affect:
Backup size
Replication speed
Query performance
Disk I/O
Index efficiency
Schema mistakes multiply at scale.
Fixing them later requires:
Migrations
Downtime
Risk
Choosing correctly early costs nothing.
Choosing incorrectly costs everything later.
🧠 The Mental Model That Changes Everything
Data types are not academic.
They are:
Performance decisions
Cost decisions
Reliability decisions
Legal decisions
Choosing correctly separates:
Developers who write features
from
Engineers who design systems
The Bridge Back
Remember the slow queries?
We didn’t rewrite business logic.
We didn’t optimize algorithms.
We changed:
BIGINT → INT where appropriate
FLOAT → DECIMAL for pricing
DATETIME → TIMESTAMP for metadata
CHAR → VARCHAR for user input
Storage dropped.
Query speed improved.
Finance stopped complaining.
Sometimes the biggest performance wins are hidden in the schema.
And the database never forgets your early shortcuts.




