The (1) in parentheses for a MySQL integer type has nothing to do with the range of values accepted by the data type, or how it is stored. It's only for display.
See also my answer to Types in MySQL: BigInt(20) vs Int(20) etc.
TINYINT is no different from TINYINT(1) or TINYINT(2) or TINYINT(64). It's an 8-bit signed integer data type, and it accepts any 8-bit integer value from -128 to 127.
mysql> create table b (i tinyint(1));
mysql> insert into b values (42);
mysql> select * from b;
+------+
| i |
+------+
| 42 |
+------+
For convenience, MySQL supports an alias for BOOL, which is replaced immediately by TINYINT(1).
mysql> create table b2 (i bool);
mysql> show create table b2;
CREATE TABLE `b2` (
`i` tinyint(1) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
As I said, the use of (1) means almost nothing, it's only a convention so that if you see TINYINT(1) it's reasonable to assume the column is intended to be used as a boolean. But nothing in MySQL prevents you from storing other integer values in it.
If you want a column to accept only 0 or 1, you can use BIT(1):
mysql> create table b3 (i bit(1));
mysql> insert into b3 values (0), (1);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> insert into b3 values (-1);
ERROR 1406 (22001): Data too long for column 'i' at row 1
mysql> insert into b3 values (2);
ERROR 1406 (22001): Data too long for column 'i' at row 1
This doesn't save any space compared to TINYINT though, because the storage for a given column rounds up to the nearest byte.
PS: Despite answer from @samdy1, TINYINT does not store strings '0'
or '1'
at all, it stores integers 0
or 1
, as well as other integers from -128 to 127. There is no need to quote integers in SQL, and I am often puzzled why so many developers do.