MySQL TINYINT 取值範圍完整解析:有號/無號、補碼原理與儲存機制
TINYINT 是 MySQL 最小的整數型別,佔用 1 位元組 (8 bits)。理解其有號/無號範圍、補碼表示法與顯示寬度設定,對資料庫設計與避免溢位錯誤至關重要。
官方範圍定義
| 屬性 | 最小值 | 最大值 | 適用場景 |
| 有號 (SIGNED,預設) | -128 | 127 | 可能為負的數值、布林邏輯 (0/1) |
| 無號 (UNSIGNED) | 0 | 255 | 純正數計數、狀態碼、小範圍枚舉 |
無號範圍推導 (0~255)
- 8 bits 全為 0:
00000000 = 0 (最小值)
- 8 bits 全為 1:
11111111 = 255 (最大值)
有號範圍推導 (-128~127) — 補碼機制
電腦以補碼表示有號整數:最高位為符號位 (0=正, 1=負),其餘為數值位。
| 二進位 | 原碼 | 反碼 | 補碼 (儲存值) | 十進位 |
| 0 0000000 | +0 | +0 | 00000000 | 0 |
| 0 1111111 | +127 | +127 | 01111111 | 127 (最大正數) |
| 1 0000000 | -0 (不存在) | -0 | 10000000 | -128 (最小負數) ⭐ |
| 1 1111111 | -127 | 10000000 | 11111111 | -1 |
為什麼最小值是 -128 而非 -127?
在補碼體系中,10000000 本應代表「-0」,但「-0」與「+0」數值相同,會造成一個數值對應兩個編碼的浪費。為了編碼與數值一一對應,規定「0」統一用 00000000 表示,將 10000000 釋出給 -128。這樣負數範圍比正數多 1 個,充分利用 256 個編碼空間。
顯示寬度誤區:TINYINT(1) vs TINYINT(4)
括號內的數字僅為「顯示寬度」,不影響儲存範圍與空間。
TINYINT(1)、TINYINT(4) 範圍完全相同:-128~127 (或 0~255 UNSIGNED)
- 搭配
ZEROFILL 時,輸出會左補零至指定寬度
- 不同於
CHAR/VARCHAR 的長度限制,整數型別的 M 值純粹是顯示提示
IP 地址儲存最佳實踐
IPv4 可轉為 32 位無號整數 (INT UNSIGNED) 儲存:
-- MySQL 內建函數
INSERT INTO ip_log (ip_int) VALUES (INET_ATON('192.168.1.1')); -- 3232235777
SELECT INET_NTOA(ip_int) FROM ip_log; -- 還原為 '192.168.1.1'
-- PHP 對應
$ipLong = sprintf("%u", ip2long('192.168.1.1')); // 格式化為無號
$ip = long2ip($ipLong);
總結速查
- 儲存空間:固定 1 Byte
- 有號範圍:-128 ~ 127
- 無號範圍:0 ~ 255
- 顯示寬度 (M) 不影響範圍,僅影響 ZEROFILL 輸出格式
- 布林值建議用
TINYINT(1) UNSIGNED (0/1)
- 需負數時用 SIGNED,純計數用 UNSIGNED 獲得雙倍正數空間
深入理解整數型別的位元級表示,能幫你做出更精準的型別選擇,避免資料截斷與溢位 Bug。
- 上一篇文章: MySQL SUM() 聚合查詢陷阱:多表 JOIN 導致重複計算的正確解法
- 下一篇文章: 慎用 MySQL ENUM 型別:PHP 弱型別陷阱、儲存原理與最佳替代方案
Copyright ©
程式碼之家 All Rights Reserved