許多開發者誤以為 tinyint(1) 只能存 1 位數字,tinyint(3) 只能存 3 位。實際上:
CREATE TABLE test (
c1 TINYINT(1),
c2 TINYINT(3),
c3 TINYINT(3) ZEROFILL
);
INSERT INTO test VALUES (12, 12, 12);
SELECT * FROM test;
-- 結果:
-- c1: 12
-- c2: 12
-- c3: 012 ← 僅有 ZEROFILL 才會左補零
UNSIGNED 屬性(無號),負數會被截斷為 0。TINYINT(2) ZEROFILL 存入 123 → 顯示 123。| 類型 | 佔用位元組 | 有號範圍 | 無號範圍 |
|---|---|---|---|
| TINYINT | 1 | -128 ~ 127 | 0 ~ 255 |
| SMALLINT | 2 | -32,768 ~ 32,767 | 0 ~ 65,535 |
| MEDIUMINT | 3 | -8,388,608 ~ 8,388,607 | 0 ~ 16,777,215 |
| INT / INTEGER | 4 | -2,147,483,648 ~ 2,147,483,647 | 0 ~ 4,294,967,295 |
| BIGINT | 8 | -9.22e18 ~ 9.22e18 | 0 ~ 1.84e19 |
CREATE TABLE t (a INT(1), b TINYINT(1));
INSERT INTO t VALUES (256, 257); -- 觸發 Warning
SELECT * FROM t;
-- 結果:
-- a: 256
-- b: 127 ← TINYINT 有號上限為 127,超出部分被截斷
關鍵點:Warning 提示「Data truncated」,但語句仍執行成功,這正是 MySQL 非嚴格模式下的預設行為。
MySQL 無原生 Boolean 類型,慣用 TINYINT(1) 表示真/假(0/1)。因為佔用 1 位元組,比 INT(1) 節省 75% 空間,且語義明確。
CHECK 約束(MySQL 8.0.16+ 支援)。tinyint(1) vs tinyint(3):儲存完全相同,佔 1 字節,範圍 0~255(無號)。
zerofill 生效條件:需同時指定顯示寬度與 ZEROFILL,如 TINYINT(3) ZEROFILL,值 8 → 顯示 008。
int(1) vs tinyint(1):前者 4 字節,後者 1 字節,儲存範圍差異巨大,能用 tinyint 絕不浪費 int。
varchar(n) 的 n 是字元數上限,與整數類型的顯示寬度本質不同。