
1. MySQL數據類型概述作為關系型數據庫的基石MySQL的數據類型系統直接影響著數據存儲效率、查詢性能和系統穩定性。我在實際項目中見過太多因為數據類型選擇不當導致的性能問題一個本該用TINYINT的字段被定義成INT導致百萬級數據表體積膨脹30%用VARCHAR(255)存儲固定長度的MD5值白白浪費了20%存儲空間...MySQL的數據類型主要分為三大類數值類型包括整數和浮點數字符串類型包含文本和二進制數據日期時間類型處理各種時間格式每種類型都有其特定的存儲需求和適用場景。比如同樣是存儲年齡TINYINT UNSIGNED就比INT更適合因為人類年齡不可能超過255歲更不可能是負數。關鍵原則選擇能滿足需求的最小數據類型。這不僅節省存儲空間更能提升索引效率。2. 數值類型深度解析2.1 整數類型實戰選擇MySQL提供5種整數類型它們的區別主要體現在存儲空間和取值范圍上類型字節有符號范圍無符號范圍TINYINT1-128 ~ 1270 ~ 255SMALLINT2-32768 ~ 327670 ~ 65535MEDIUMINT3-8388608 ~ 83886070 ~ 16777215INT/INTEGER4-2147483648 ~ 21474836470 ~ 4294967295BIGINT8-2^63 ~ 2^63-10 ~ 2^64-1實際項目中的經驗法則狀態字段用TINYINT比如訂單狀態(0未支付,1已支付)外鍵ID用INT足夠除非是超大型系統自增主鍵建議用UNSIGNED避免負數浪費一半空間-- 典型錯誤示例用BIGINT存儲用戶年齡 CREATE TABLE user ( age BIGINT -- 浪費7個字節 ); -- 正確做法 CREATE TABLE user ( age TINYINT UNSIGNED -- 只需1字節 );2.2 浮點數精準陷阱FLOAT和DOUBLE作為近似值類型在進行等值比較時會出現精度問題-- 會產生意想不到的結果 SELECT 0.1 0.2 0.3; -- 返回0(false)金融類數據必須使用DECIMALCREATE TABLE account ( balance DECIMAL(10,2) -- 10位精度2位小數 );血淚教訓曾經有個電商項目因為用FLOAT存儲金額導致對賬時出現0.01元的差額排查了整整兩天3. 字符串類型實戰指南3.1 CHAR與VARCHAR的抉擇特性CHARVARCHAR存儲方式固定長度可變長度空格處理自動補足空格保留原樣適用場景定長數據(如MD5)變長數據(如地址)實測對比存儲100萬個MD5值(固定32字符)CHAR(32)占用32MBVARCHAR(32)占用約38MB(有額外長度標識)3.2 文本類型使用場景TEXT系列存儲大段文本分TINYTEXT(255B)、TEXT(64KB)、MEDIUMTEXT(16MB)、LONGTEXT(4GB)BLOB系列存儲二進制數據分類與TEXT對應重要限制TEXT/BLOB列不能有默認值也不能用作索引的全部內容4. 時間類型的精妙運用4.1 各時間類型對比類型格式范圍存儲需求DATEYYYY-MM-DD1000-01-01~9999-12-313字節TIMEHH:MM:SS-838:59:59~838:59:593字節DATETIMEYYYY-MM-DD HH:MM:SS1000-01-01 00:00:00~9999-12-31 23:59:598字節TIMESTAMPYYYY-MM-DD HH:MM:SS1970-01-01 00:00:01~2038-01-19 03:14:074字節4.2 時區陷阱與解決方案TIMESTAMP會轉換為UTC存儲檢索時再轉回當前時區而DATETIME不會-- 假設服務器時區為UTC8 CREATE TABLE events ( dt DATETIME, ts TIMESTAMP ); INSERT INTO events VALUES (2023-01-01 08:00:00, 2023-01-01 08:00:00); -- 修改時區后查詢 SET time_zone 00:00; SELECT * FROM events; -- 結果dt顯示08:00:00ts顯示00:00:00跨時區系統建議統一使用DATETIME存儲前端負責時區轉換。5. 類型選擇性能優化實戰5.1 索引效率對比測試在100萬數據的用戶表上測試-- 方案1手機號存為VARCHAR(20) ALTER TABLE users ADD INDEX idx_phone(phone); -- 查詢耗時約120ms -- 方案2手機號存為CHAR(11) ALTER TABLE users ADD INDEX idx_phone(phone); -- 查詢耗時約85ms定長字段的索引效率通常更高但需權衡存儲空間。5.2 隱式類型轉換陷阱-- 假設mobile字段是VARCHAR EXPLAIN SELECT * FROM users WHERE mobile 13800138000; -- 會發現使用了全表掃描而不是索引必須保持查詢條件與字段類型一致這是最常見的性能殺手之一。6. 特殊類型與應用場景6.1 ENUM與SET類型ENUM適合固定選項-- 節省存儲空間 CREATE TABLE shirts ( size ENUM(x-small, small, medium, large, x-large) );SET適合多選場景CREATE TABLE permissions ( flags SET(read, write, delete, admin) );6.2 JSON類型實戰MySQL 5.7支持原生JSON類型CREATE TABLE products ( attributes JSON, INDEX idx_attrs ((CAST(attributes-$.color AS CHAR(20)))) ); -- 查詢紅色商品 SELECT * FROM products WHERE JSON_EXTRACT(attributes, $.color) red;JSON類型的索引需要通過生成列實現這是NoSQL特性在關系型數據庫中的巧妙融合。