首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 數據類型與常用字段屬性深度解析

     編輯:MySQL 資料庫相關知識

前言

恰當的數據類型選型是高性能 Schema 設計的基石。本文系統梳理 MySQL 8.0 主流數據類型的存儲特性、適用場景與避坑指南,並詳解 9 大常用字段屬性的實戰意義。

一、日期時間類型

類型存儲範圍精度推薦場景
DATE3 bytes1000-01-01 ~ 9999-12-31天生日、紀念日、無時區業務
TIME3 bytes-838:59:59 ~ 838:59:59秒每日定時任務、工時統計
DATETIME8 bytes1000-01-01 00:00:00 ~ 9999-12-31 23:59:59秒通用業務時間,不受時區影響
TIMESTAMP4 bytes1970-01-01 00:00:01 UTC ~ 2038-01-19 03:14:07 UTC秒自動記錄創建/更新時間,受時區影響
YEAR1 byte1901 ~ 2155年年份維度統計

最佳實踐:
• created_at 用 TIMESTAMP DEFAULT CURRENT_TIMESTAMP
• updated_at 用 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
• 歷史/未來日期業務用 DATETIME 避免 2038 年問題

二、數值類型

整數族

類型存儲有符號範圍無符號範圍
TINYINT1B-128 ~ 1270 ~ 255
SMALLINT2B-32,768 ~ 32,7670 ~ 65,535
MEDIUMINT3B-8,388,608 ~ 8,388,6070 ~ 16,777,215
INT4B-2,147,483,648 ~ 2,147,483,6470 ~ 4,294,967,295
BIGINT8B-9.22E18 ~ 9.22E180 ~ 1.84E19

選型原則:
• 主鍵 ID 必用 BIGINT UNSIGNED
• 狀態/枚舉類用 TINYINT UNSIGNED
• 計數器預估 < 42億 用 INT UNSIGNED
• INT(11) 中的 11 僅為顯示寬度,不影響存儲範圍

小數族

類型存儲精度適用場景
FLOAT(M,D)4B單精度 ~7 位有效數字科學計算、非精確業務
DOUBLE(M,D)8B雙精度 ~15 位有效數字高精度科學計算
DECIMAL(M,D)M/2+2 B精確定點數,最多 65 位數字金額、價格、比率、任何財務數據

血淚教訓:FLOAT(5,3) 插入 123.45678 實際存 99.999 (溢出截斷)。財務字段嚴禁使用浮點類型。

三、字符串類型

類型最大長度存儲特點適用場景
CHAR(N)255 字符定長,右側空格填充,讀取時去除尾部空格MD5、UUID、身份證、固定長度代碼
VARCHAR(N)65,535 字符 (受行大小 65,535B 限制)變長,1-2B 存長度,實際佔用 L+1/2B通用變長文本:名稱、郵箱、地址
TINYTEXT255 字符不需指定長度,離頁存儲極短文本
TEXT64KB離頁存儲,不支持 DEFAULT文章內容、日志
MEDIUMTEXT16MB同上長文本
LONGTEXT4GB同上超長文本

CHAR vs VARCHAR 核心差異

  • 存儲:CHAR 固定佔用 N 字符空間;VARCHAR 按實際長度 + 1-2B 長度前綴。
  • 性能:CHAR 定長利於固定偏移量快速定位,無碎片;VARCHAR 更新長度變化產生碎片,需定期 OPTIMIZE TABLE。
  • 排序/比較:CHAR 尾部空格被忽略;VARCHAR 保留尾部空格。
  • 內存臨時表:MEMORY 引擎將 VARCHAR 轉為定長 CHAR,過大定義會浪費內存。

編碼影響

utf8mb4 下:
• CHAR(32) 固定佔 32×4=128B
• VARCHAR(255) 最大佔 255×4+2=1022B
• 行大小限制 65,535B 含所有列開銷

四、枚舉與集合

類型成員上限存儲特點
ENUM65,5351-2B (smallint)單選,內部按定義順序存 1,2,3... NULL 索引為 NULL,空串索引 0
SET641-8B (bigint 位掩碼)多選,位運算,尾部空格自動去除

慎用:修改成員需 ALTER TABLE 鎖表,不利擴展。推薦用 TINYINT + 應用層字典或查表。

五、IP 地址存儲方案

-- 方案一:無符號 INT (4B) + MySQL 內建函數
INSERT INTO t(ip) VALUES (INET_ATON('192.168.1.1'));  -- 3232235777
SELECT INET_NTOA(ip) FROM t;  -- '192.168.1.1'

-- 方案二:VARBINARY(16) 支持 IPv6
INSERT INTO t(ip) VALUES (INET6_ATON('2001:db8::1'));
SELECT INET6_NTOA(ip) FROM t;

-- PHP 端轉換
sprintf("%u", ip2long('192.168.1.1'));  -- 无符号整型
long2ip($int);

六、九大常用字段屬性詳解

屬性核心作用關鍵限制/注意點
AUTO_INCREMENT自增主鍵,插入時自動分配唯一整數必須為索引 (PK/UK);每表僅一列;ALTER TABLE t AUTO_INCREMENT=1000 設起始值
BINARYCHAR/VARCHAR 大小寫敏感比較/排序僅影響該列排序規則,不改變存儲
DEFAULT缺省值,INSERT 不指定列時自動填充必須為常量/函數 (如 CURRENT_TIMESTAMP);BLOB/TEXT 不支持
INDEX / KEY創建普通索引,加速查詢前綴索引 idx_name(name(10)) 節省空間;覆蓋索引避免回表
NOT NULL禁止 NULL,插入 NULL 報錯配合 DEFAULT 確保數據完整性;COUNT(col) 不統計 NULL
NULL允許 NULL (默認)NULL ≠ 空串 ≠ 0;索引中 NULL 不計入唯一性約束
PRIMARY KEY主鍵:唯一 + 非空 + 聚簇索引單表唯一;可多列組合;業務無關字段宜用自增 BIGINT
UNIQUE唯一約束,允許多個 NULL本質是唯一索引;業務鍵 (手機、郵箱、身份證) 必加
ZEROFILL數值左側補 0 至顯示寬度,隱含 UNSIGNEDINT(5) ZEROFILL 插入 4 存為 00004;僅顯示效果,不改存儲

七、外鍵約束

-- 僅 InnoDB 支持
ALTER TABLE `order` 
ADD CONSTRAINT fk_order_user 
FOREIGN KEY (user_id) REFERENCES `user`(id)
ON UPDATE CASCADE ON DELETE RESTRICT;
  • CASCADE:級聯更新/刪除
  • SET NULL:置空 (需列允許 NULL)
  • RESTRICT/NO ACTION:拒絕父表操作

高併發系統常業務層維護引用完整性,避免外鍵鎖爭用與死鎖風險。

八、建表規範速查

  1. 每表必有 BIGINT UNSIGNED AUTO_INCREMENT PK
  2. 所有列 NOT NULL DEFAULT 'xxx',業務無特殊含義禁用 NULL
  3. 字符集統一 utf8mb4,校對 utf8mb4_unicode_ci 或 _0900_ai_ci
  4. 引擎統一 InnoDB
  5. 冗余字段:created_at, updated_at, deleted_at (軟刪除)
  6. 命名:小寫 + 下劃線,tbl_ 前綴可選,索引 idx_/uk_
  7. 單表行數超 2000 萬或體積超 10GB 考慮分表/分區

合理的類型選型與屬性約束,能從源頭避免 80% 的數據質量與性能問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved