MySQL 數值型態:INT、BIGINT 與 FLOAT
簡介
在資料庫設計的過程中,選擇適當的欄位型別是 效能、儲存空間 以及 資料正確性 的關鍵。
MySQL 提供了多種數值型別,其中最常用的三個是 INT、BIGINT 與 FLOAT。
INT适合儲存一般的整數(如使用者編號、年齡)。BIGINT能處理更大的整數,常用於需要 64 位元 數值的情境(如交易流水號)。FLOAT則是用來存放 浮點數,適合表示科學計算、測量值或金額(若不要求極高精度)等。
本篇文章將從概念、語法、實作範例、常見陷阱與最佳實踐,帶你全面掌握這三種數值型別的使用方式,讓你的 MySQL 資料庫既 節省空間 又 保持正確。
核心概念
1. INT(整數)
| 屬性 | 說明 |
|---|---|
| 位元長度 | 4 位元(32 位元) |
| 取值範圍(有符號) | -2,147,483,648 ~ 2,147,483,647 |
| 取值範圍(無符號) | 0 ~ 4,294,967,295 |
| 預設儲存空間 | 4 Byte |
| 常見用法 | 主鍵、計數器、狀態碼等 |
重點:若欄位不需要負數,可加上 UNSIGNED,可將上限翻倍,且不會產生負值。
2. BIGINT(大整數)
| 屬性 | 說明 |
|---|---|
| 位元長度 | 8 位元(64 位元) |
| 取值範圍(有符號) | -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 |
| 取值範圍(無符號) | 0 ~ 18,446,744,073,709,551,615 |
| 預設儲存空間 | 8 Byte |
| 常見用法 | 超大型流水號、統計累計、時間戳記(UNIX timestamp)等 |
注意:BIGINT 雖然提供更大的範圍,但佔用的磁碟與記憶體空間也會相對較大,僅在確實需要時才使用。
3. FLOAT(單精度浮點數)
| 屬性 | 說明 |
|---|---|
| 位元長度 | 4 Byte(單精度) |
| 有效位數 | 約 7 位十進位數字 |
| 取值範圍 | ±3.402823466E+38(近似) |
| 常見用法 | 科學計算、測量值、非金錢的比例或分數等 |
⚠️ 小提醒:若需要「精確」的金額計算,請改用
DECIMAL,因為FLOAT會因二進位表示方式產生四捨五入誤差。
程式碼範例
以下示範在 MySQL 中建立、插入、查詢與更新 INT、BIGINT、FLOAT 欄位的實務操作。每段程式碼均以 -- 註解說明。
範例 1:建立測試資料表
CREATE TABLE employee (
emp_id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, -- 員工編號,使用 INT,無符號自動遞增
salary BIGINT NOT NULL, -- 年薪,使用 BIGINT,避免超過 INT 範圍
performance FLOAT(5,2) DEFAULT 0.00, -- 績效分數,保留兩位小數
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;
範例 2:插入資料(示範不同型別的限制)
INSERT INTO employee (salary, performance) VALUES
(55000000, 4.75), -- 正常插入
(2147483647, 3.20), -- INT 最大值仍可放入 BIGINT 欄位
(9223372036854775807, 5.00); -- BIGINT 最大值(有符號)示例
說明:
salary欄位使用BIGINT,即使插入 9,223,372,036,854,775,807(有符號上限)仍能正常儲存;若改為INT,則會產生「超出範圍」的錯誤。
範例 3:更新 FLOAT 欄位時的四捨五入
UPDATE employee
SET performance = 4.6789 -- 只保留兩位小數,會自動四捨五入為 4.68
WHERE emp_id = 1;
範例 4:使用 UNSIGNED BIGINT 儲存 UNIX 時間戳記
ALTER TABLE employee
ADD login_ts BIGINT UNSIGNED AFTER created_at; -- 新增欄位儲存登入時間
UPDATE employee
SET login_ts = UNIX_TIMESTAMP()
WHERE emp_id = 2;
範例 5:檢查 INT 欄位的範圍限制
-- 嘗試插入超過 INT UNSIGNED 上限的值,會失敗
INSERT INTO employee (emp_id, salary, performance) VALUES
(4294967296, 1000000, 2.50); -- 4,294,967,296 超過 UNSIGNED INT 最大值
執行結果會回傳類似 ERROR 1264 (22003): Out of range value for column 'emp_id' at row 1 的錯誤訊息,提醒開發者型別不匹配。
常見陷阱與最佳實踐
| 陷阱 | 說明 | 最佳實踐 |
|---|---|---|
使用 FLOAT 計算金額 |
會產生精度誤差,導致帳目不一致。 | 改用 DECIMAL(15,2),確保金額計算的精確度。 |
未加 UNSIGNED 而浪費正負位元 |
INT 預設允許負數,卻只會儲存正整數,浪費 1 位元的正負空間。 |
若欄位永不為負,加上 UNSIGNED,可將上限翻倍。 |
把 BIGINT 用在不需要的大範圍 |
佔用 8 Byte,導致索引變大、IO 成本上升。 | 只在確實需要超過 2^31‑1 的情況下才使用 BIGINT。 |
忽略 FLOAT 的有效位數 |
超過 7 位十進位數的精度會被截斷。 | 設定適當的 FLOAT(M,D),或改用 DOUBLE(15 位)或 DECIMAL。 |
自增主鍵與 BIGINT 混用 |
若自增值超過 INT 上限,會自動失效。 |
事先評估未來資料量,直接使用 BIGINT AUTO_INCREMENT 以免遷移成本。 |
其他實用技巧
檢視欄位實際佔用空間
SHOW CREATE TABLE employee;會顯示每個欄位的型別與屬性,方便檢查是否符合預期。
使用
ZEROFILL讓顯示更統一(僅在顯示層面有用)CREATE TABLE product ( product_id INT UNSIGNED ZEROFILL PRIMARY KEY );查詢時會自動在左側補零,例如
00000123。結合
CHECK約束限制數值範圍(MySQL 8.0+)ALTER TABLE employee ADD CONSTRAINT chk_performance CHECK (performance BETWEEN 0 AND 5);
實際應用場景
| 場景 | 建議型別 | 為什麼 |
|---|---|---|
| 使用者編號 | INT UNSIGNED AUTO_INCREMENT |
大部分系統的使用者量不會超過 4 億,且自增方便管理。 |
| 訂單流水號 | BIGINT UNSIGNED AUTO_INCREMENT |
電商平台一年可能產生上億筆訂單,使用 BIGINT 可避免未來升級麻煩。 |
| 即時感測器數值(溫度、濕度) | FLOAT(6,2) |
只需要兩位小數的精度,且範圍不大,FLOAT 能減少儲存空間。 |
| 金融交易金額 | DECIMAL(18,4)(非 FLOAT) |
必須保證 四捨五入 的正確性,避免浮點誤差。 |
| 日誌時間戳記 | BIGINT UNSIGNED(UNIX timestamp) |
以毫秒或秒為單位的時間戳記,適合跨平台比較與排序。 |
總結
INT:最常用的 4 Byte 整數型別,適合 中小規模 的正負整數;加上UNSIGNED可把上限翻倍。BIGINT:8 Byte 大整數,適合 超大資料量 或需要 64 位元 的唯一識別碼;使用時要留意儲存成本。FLOAT:單精度浮點數,適合 非金額、科學測量 等不要求極高精度的情況;若需精確計算,請改用DECIMAL或DOUBLE。
在設計資料表時,先評估資料的範圍與精度需求,再選擇最合適的型別,能有效降低儲存成本、提升查詢效能,同時避免未來因型別不當而產生的遷移與錯誤。希望本篇文章能幫助你在 MySQL 中正確、有效地使用 INT、BIGINT 與 FLOAT,寫出更穩定、更具可擴充性的資料庫設計。祝開發順利!