萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

深入理解 MySQL tinyint(1) 與 zerofill:顯示寬度、儲存空間與零填充機制

核心結論先行

  • 括號內的數字(如 tinyint(1) 中的 1)僅代表「顯示寬度」,不影響實際儲存範圍與佔用空間。
  • zerofill 屬性啟用時,查詢結果會在左側補 0 以滿足顯示寬度;未啟用時,顯示寬度無任何效果。
  • tinyint 固定佔用 1 位元組(8 位元),有號範圍 -128~127,無號範圍 0~255。

一、顯示寬度 ≠ 儲存長度

許多開發者誤以為 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 才會左補零

二、zerofill 的行為細節

  • 自動附帶 UNSIGNED 屬性(無號),負數會被截斷為 0。
  • 僅影響查詢顯示,不改變磁碟儲存格式。
  • 超過顯示寬度的數值正常顯示,不會截斷:TINYINT(2) ZEROFILL 存入 123 → 顯示 123。

三、整數類型儲存空間對照表

類型佔用位元組有號範圍無號範圍
TINYINT1-128 ~ 1270 ~ 255
SMALLINT2-32,768 ~ 32,7670 ~ 65,535
MEDIUMINT3-8,388,608 ~ 8,388,6070 ~ 16,777,215
INT / INTEGER4-2,147,483,648 ~ 2,147,483,6470 ~ 4,294,967,295
BIGINT8-9.22e18 ~ 9.22e180 ~ 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% 空間,且語義明確。

六、避坑指南

  1. 不要依賴顯示寬度做資料驗證,應在應用層或用 CHECK 約束(MySQL 8.0.16+ 支援)。
  2. zerofill 僅適用於展示層需求**(如訂單號、員工編號),不宜用於運算欄位。
  3. 選型原則:夠用就好,優先選佔用空間最小的類型(TINYINT > SMALLINT > MEDIUMINT > INT > BIGINT)。

七、總結速記

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 是字元數上限,與整數類型的顯示寬度本質不同。

copyright © 萬盛學電腦網 all rights reserved