mysql tinyint1 vs tinyint2 vs tinyint3 vs tinyint4
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In MySQL, TINYINT(1), TINYINT(2), TINYINT(3), and TINYINT(4) all use the same underlying numeric storage. The number in parentheses does not change the byte size and does not change the numeric range. Historically, that number represented display width metadata, and even that behavior was mostly relevant only with ZEROFILL.
So if the real question is “does TINYINT(4) hold bigger values than TINYINT(1)?”, the answer is no. They are the same integer type. What changes the range is whether the column is signed or unsigned, not the number in parentheses.
Storage Size and Range Are the Same
A MySQL TINYINT always uses 1 byte of storage.
- signed range:
-128to127 - unsigned range:
0to255
That is true regardless of whether the type is declared as TINYINT(1) or TINYINT(4).
Columns a and b have the same storage size and signed range. Columns c and d have the same storage size and unsigned range.
What the Number Historically Meant
The number in TINYINT(n) was historically the display width, not the value limit. It told some client tools how many digits to use when formatting values, especially alongside ZEROFILL.
A client could display that result as 0007, but the stored value is still just the number 7. The (4) does not create a wider numeric type.
In modern MySQL, display width for integer types has been deprecated and should not be used as though it carries business meaning.
Why TINYINT(1) Often Looks Special
Many developers associate TINYINT(1) with booleans because MySQL treats BOOLEAN and BOOL as aliases for TINYINT(1).
Internally, those columns are still tiny integers. MySQL does not have a separate physical boolean storage type.
That can make TINYINT(1) look different from TINYINT(2) in ORMs or schema viewers, but the difference is mostly conventional. Some tools interpret TINYINT(1) as a boolean hint. The database engine still stores a tiny integer.
Choose the Type by Semantics, Not by Width
If the column stores a flag, declaring it as BOOLEAN can make the schema clearer even though MySQL implements it as TINYINT(1).
If the column stores a small numeric code, use TINYINT and decide signed versus unsigned based on the data domain.
What you should not do is choose TINYINT(4) because you believe it supports four-digit values. It does not.
In current MySQL design, the practical choice is about semantics and range, not cosmetic width hints.
Common Pitfalls
The biggest mistake is assuming the number in parentheses controls storage size or maximum numeric value. It does not.
Another issue is treating TINYINT(1) as a true separate boolean storage type. In MySQL, it is still a tiny integer.
A third problem is relying on display width metadata in modern schemas. It is not a good tool for expressing business constraints.
Summary
- '
TINYINT(1),TINYINT(2),TINYINT(3), andTINYINT(4)have the same 1-byte storage size.' - The number in parentheses does not change the numeric range.
- Signed versus unsigned determines whether the range is
-128..127or0..255. - '
TINYINT(1)is often used for booleans becauseBOOLEANis an alias for it in MySQL.' - Do not use display width as though it were a data-capacity setting.

