04.MySQL數據類型詳解

MySQL數據類型詳解


文章目錄

  1. MySQL數據類型
  2. 數據類型分類
  3. 數值類型
    • tinyint類型
    • bit類型
    • float類型
    • decimal類型
  4. 字符串類型
    • char類型
    • varchar類型
    • char和varchar比較
  5. 時間日期類型
  6. enum和set類型
  7. 數據類型選擇的進階技巧
  8. 常見誤區與解決方案
  9. 性能優化與最佳實踐

MySQL數據類型

數據類型的作用

數據類型不僅是存儲數據的容器,更是數據庫設計的基石。它決定了三個核心要素:

  1. 存儲空間:例如,存一個整數和一篇長文顯然需要不同的空間分配策略。
  2. 二進制解析方式:同一串二進制數據,用INT解讀是數字,用CHAR解讀可能變成亂碼。
  3. 取值范圍限制:年齡不可能是負數,性別只能是有限選項,這些都需要數據類型來規范。

此外,數據類型還影響索引效率、查詢優化器的選擇,甚至影響數據庫的擴展性和維護成本。例如,錯誤地使用VARCHAR(255)存儲固定長度的MD5值會導致空間浪費和查詢效率下降。


數據類型分類

MySQL的數據類型大致可分為四類,以下是詳細分類表:

分類數據類型說明
數值類型BIT(M)位類型,M默認1,范圍1-64位
BOOL布爾值(實際是TINYINT(1))
TINYINT/SMALLINT/MEDIUMINT/INT/BIGINT整型家族,字節數從1到8遞增
FLOAT/DOUBLE/DECIMAL浮點數和精確小數
字符串類型CHAR(L)固定長度字符串(最大255)
VARCHAR(L)可變長度字符串(最大65535字節)
BLOB/TEXT大文本/二進制數據
日期時間類型DATE/DATETIME日期格式YYYY-MM-DD,時間戳
TIMESTAMP自動更新的時間戳
集合類型ENUM枚舉(單選)
SET集合(多選)

冷知識:MySQL沒有獨立的布爾類型,用TINYINT(1)代替,0代表FALSE,1代表TRUE。但在某些ORM框架中,會自動將TINYINT(1)映射為布爾值。


數值類型

tinyint類型

有符號 vs 無符號
  • 有符號:范圍-128~127(占1字節)
  • 無符號:范圍0~255(同樣占1字節)

實戰案例
假設設計一個用戶積分表:

CREATE TABLE user_points (user_id INT,points TINYINT UNSIGNED
);

如果積分上限為200,用TINYINT UNSIGNED足夠;但若未來需要支持更高積分(如500),則必須改為SMALLINT UNSIGNED,否則插入500會報錯。

為何慎用無符號?

無符號類型看似能節省空間,但可能埋下隱患:

  • 擴展性差:如年齡字段若用TINYINT UNSIGNED(0-255),當遇到異常值(如輸入300)會直接報錯,而有符號類型可臨時存儲負數用于標記異常。
  • 兼容性問題:某些編程語言或框架對無符號類型支持不佳,可能引發轉換錯誤。

bit類型

位類型的高級應用

BIT類型適合存儲開關狀態或權限位掩碼。例如,一個用戶權限字段:

CREATE TABLE user_permissions (user_id INT,perms BIT(8) -- 每位代表一種權限
);

插入權限:

INSERT INTO user_permissions VALUES (1, b'00000011'); -- 同時有第1和第2位權限

通過位運算查詢權限:

SELECT * FROM user_permissions WHERE perms & b'00000001'; -- 查找有第一位權限的用戶
顯示問題與解決方案

BIT類型顯示時按ASCII碼轉換可能導致混亂。例如:

INSERT INTO user_permissions VALUES (2, 10); -- 10對應ASCII換行符

查詢結果可能顯示為空白或特殊字符。解決方案

  • 應用層處理:將BIT轉換為整數或自定義字符串映射。
  • 使用INT代替BIT:對于不超過32位的權限,直接用INT存儲更直觀。

float類型

精度陷阱與四舍五入

FLOAT(M,D)的M是總位數,D是小數位數。例如FLOAT(4,2)存儲范圍是-99.99到99.99,但實際可插入范圍是-99.994到99.994,超出時會四舍五入或報錯。

CREATE TABLE measurements (val FLOAT(4,2)
);
INSERT INTO measurements VALUES (99.994); -- 存儲為99.99
INSERT INTO measurements VALUES (99.995); -- 存儲為100.0,觸發報錯
何時選擇FLOAT vs DECIMAL?
  • FLOAT:適合科學計算,允許一定誤差(如傳感器數據)。
  • DECIMAL:金融場景必須使用,如存儲賬戶余額,避免浮點誤差。

decimal類型

精確計算的王者

DECIMAL的存儲機制使其成為金融系統的首選。例如:

CREATE TABLE accounts (balance DECIMAL(10,2)
);

存儲100.01時,DECIMAL確保精確到分,而FLOAT可能存儲為100.009999。

存儲開銷對比
DECIMAL每4字節存9個數字,小數點單獨占1字節。例如DECIMAL(10,2)占用5字節(9個數字+1字節小數點),而FLOAT固定占4字節。


字符串類型

char類型

定長存儲的適用場景

CHAR(L)適用于長度固定的字符串,如身份證號(18位)、手機號(11位)。例如:

CREATE TABLE users (id_card CHAR(18)
);

插入不足18位時會自動補空格,查詢時尾部空格被自動去除。

性能優勢

  • 定長存儲便于快速定位,適合頻繁更新的字段。
  • 作為主鍵時,CHAR比VARCHAR更高效(如UUID)。

varchar類型

變長存儲的靈活性

VARCHAR(L)適合長度波動大的字段,如用戶名、地址。例如:

CREATE TABLE addresses (street VARCHAR(100)
);

存儲"Main St"僅占用7字節(數據+1字節長度標識),而CHAR(100)會占用100字節。

編碼對最大長度的影響

  • UTF8MB4下,VARCHAR(21844) ≈ 65532字節(21844 × 3字節/字符 + 2字節長度標識)
  • GBK下,VARCHAR(32766) ≈ 65532字節(32766 × 2字節/字符 + 2字節長度標識)

最佳實踐

  • 定義表時顯式指定字符集:CREATE TABLE example (...) CHARSET=utf8mb4;
  • 避免過度使用VARCHAR(255):根據實際數據長度選擇合適值,節省空間并提高緩存效率。

char和varchar比較

特性CHARVARCHAR
空間占用固定L字符實際長度+1~2字節
速度快(定長)稍慢(需讀長度)
適用場景身份證號、手機號名字、地址等變長字段

選擇建議

  • 長度固定的字段(如MD5值)用CHAR
  • 長度波動大的字段(如文章內容)用VARCHAR

擴展案例
存儲IP地址時,CHAR(15)(如"192.168.1.1")比VARCHAR更高效,因為IPv4地址固定為15字符以內。


時間日期類型

三大時間類型對比

類型格式占用空間特點
DATEYYYY-MM-DD3字節只存日期
DATETIMEYYYY-MM-DD HH:MM:SS8字節范圍1000-9999年
TIMESTAMPYYYY-MM-DD HH:MM:SS4字節自動更新,默認當前時間

實戰案例
設計評論表時,使用TIMESTAMP記錄發布時間:

CREATE TABLE comments (id INT,content TEXT,create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

插入數據時無需指定create_time,自動填充當前時間。更新記錄時,可設置TIMESTAMP自動更新:

ALTER TABLE comments ADD update_time TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;

時區問題

  • DATETIME不存儲時區信息,顯示依賴客戶端設置。
  • TIMESTAMP存儲UTC時間,查詢時自動轉換為當前時區。

enum和set類型

枚舉類型(ENUM)

單選場景優化

ENUM適合選項固定的單選字段,如訂單狀態:

CREATE TABLE orders (status ENUM('pending', 'processing', 'shipped', 'canceled')
);

插入非枚舉值會報錯,確保數據一致性。

內部存儲機制
ENUM存儲為數字索引(1-based),如ENUM('a','b','c')中,a=1,b=2,c=3。可通過數字訪問:

SELECT * FROM orders WHERE status = 3; -- 查找所有已取消訂單

不推薦此方式,可讀性差。


集合類型(SET)

多選場景優化

SET適合多選字段,如用戶興趣標簽:

CREATE TABLE users (interests SET('sports', 'music', 'reading')
);

插入多選值:

INSERT INTO users VALUES ('sports,music');

位運算原理
SET用位圖存儲,每個選項對應一個二進制位:

  • sports = 1 (0b0001)
  • music = 2 (0b0010)
  • reading = 4 (0b0100)

查詢包含"music"的用戶:

SELECT * FROM users WHERE interests & 2;

局限性

  • 最多64個選項。
  • 修改枚舉/集合列表需ALTER TABLE,不適合動態選項。

數據類型選擇的技巧

1. 空間與性能的權衡

  • 數值類型:優先使用最小能滿足需求的類型。例如,年齡字段用TINYINT而非INT。
  • 字符串類型:避免濫用VARCHAR(255),根據實際數據長度選擇,減少內存占用。
  • 日期類型:若只需日期(如生日),用DATE而非DATETIME,節省5字節存儲。

2. 金融場景的必殺技

涉及金額字段必須使用DECIMAL,避免FLOAT/DOUBLE的精度問題。例如:

CREATE TABLE transactions (amount DECIMAL(15,4) -- 精確到分,保留4位小數
);

3. JSON類型的應用

MySQL 5.7+支持JSON類型,適合存儲半結構化數據:

CREATE TABLE settings (user_id INT,preferences JSON
);
INSERT INTO settings VALUES (1, '{"theme": "dark", "notifications": true}');

查詢JSON字段:

SELECT * FROM settings WHERE JSON_EXTRACT(preferences, '$.theme') = 'dark';

常見誤區與解決方案

誤區1:盲目使用INT存儲一切數值

  • 問題:用INT存儲IP地址(如192.168.1.1轉為3232235779),查詢時需轉換回字符串。
  • 解決方案:使用INET_ATON()和INET_NTOA()函數,或直接用CHAR(15)存儲。

誤區2:過度依賴ENUM/SET

  • 問題:ENUM選項頻繁變動時需頻繁執行ALTER TABLE。
  • 解決方案:用外鍵關聯獨立的狀態表,如:
CREATE TABLE order_statuses (id TINYINT PRIMARY KEY,name VARCHAR(20)
);
CREATE TABLE orders (status_id TINYINT,FOREIGN KEY (status_id) REFERENCES order_statuses(id)
);

誤區3:忽略字符集影響

  • 問題:VARCHAR(255)在UTF8MB4下占用255×4=1020字節,可能超過行大小限制(65535字節)。
  • 解決方案:合理規劃字段長度,或使用TEXT/BLOB類型。

性能優化與最佳實踐

1. 索引字段的選擇

  • 優先選擇短字段:如CHAR(2)的省份代碼比VARCHAR(50)更適合索引。
  • 避免在TEXT/BLOB上創建全列索引:使用前綴索引,如INDEX (content(100))

2. 自增主鍵的陷阱

  • 問題:BIGINT占用8字節,若數據量不大可用INT UNSIGNED(上限42億)。
  • 優化:中小型表使用INT即可,節省空間并提高緩存命中率。

3. 分區表的類型適配

  • 按時間分區:使用DATE/DATETIME字段,避免使用INT存儲時間戳。
  • 按范圍分區:確保分區鍵類型支持所需范圍(如DECIMAL不適合作為分區鍵)。

4. 批量插入的類型優化

  • 問題:插入大量DECIMAL數據時,字符串轉換可能成為瓶頸。
  • 優化:在應用層預處理為數值格式,或使用LOAD DATA INFILE。

個人建議

  1. 數值類型:優先INT/FLOAT,除非有特殊空間需求。
  2. 字符串:短文本用CHAR,長文本用VARCHAR。
  3. 時間:需要自動更新用TIMESTAMP,否則用DATETIME。
  4. 枚舉:選項少且固定用ENUM,多選用SET。
  5. 避免陷阱
    • BIT類型慎用,顯示容易混亂。
    • ENUM/SET用數字訪問可讀性差。
    • VARCHAR長度要根據編碼計算實際字節。

最后提醒:數據類型選擇直接影響性能和存儲,設計表結構時務必結合業務場景仔細考量。例如,電商系統中商品ID用BIGINT,而內部系統用INT即可。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/83300.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/83300.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/83300.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Spring AI 之對話記憶(Chat Memory)

大型語言模型(LLMs)是無狀態的,這意味著它們不會保留關于之前交互的信息。當想在多次交互中保持上下文或狀態時,這可能會成為一個限制。為了解決這一問題,Spring AI 提供了對話記憶功能,允許你在與大型語言…

H?lder Statistical Pseudo Divergence Proper H?lder Divergence

目錄 Hlder Statistical Pseudo DivergenceProper Hlder Divergence Hlder Statistical Pseudo Divergence Hlder Statistical Pseudo Divergence是一種度量兩個概率分布 p p p 和 q q q差異的方法,它基于Hlder不等式。定義如下: D α H ( p : q ) 1 …

時序數據庫IoTDB基于云原生的創新與實踐

概述 Apache IoTDB 是一款獨立自研的物聯網時序數據庫,作為 Apache 基金會的頂級項目,它融合了產學研的優勢,擁有深厚的科研基底。IoTDB 采用了端邊云協同的架構,專為物聯網設計,致力于提供極致的性能。 數據模型 I…

git 如何解決分支合并沖突(VS code可視化解決+gitLab網頁解決)

1、定義:兩個分支修改了同一文件的同一行代碼,無法自動決定如何合并代碼,需要人工干預的情況。(假設A提交了文件a,此時B在未拉取代碼的情況下,直接提交是會報錯的,此時需要拉取之后再提交才會成功&#xff…

系統架構設計師(一):計算機系統基礎知識

系統架構設計師(一):計算機系統基礎知識 引言計算機系統概述計算機硬件處理器處理器指令集常見處理器 存儲器總線總線性能指標總線分類按照總線在計算機中所處的位置劃分按照連接方式分類按照功能分類 接口接口分類 計算機軟件文件系統文件類…

聊一聊接口測試中緩存處理策略

目錄 一、強制繞過緩存 添加時間戳參數 修改請求頭 二、主動清除緩存 清除本地緩存 清除服務端緩存(需權限) 清除CDN緩存 三、測試緩存邏輯 首次請求獲取數據 記錄響應頭中的緩存標識????? 驗證緩存生效 測試緩存過期??????? 四…

機器學習算法-邏輯回歸

今天我們用 「預測考試是否及格」 的例子來講解邏輯回歸,從原理到實現一步步拆解,保證零基礎也能懂! 🎯 例子背景 假設你是班主任,要根據學生的「學習時間」預測「是否及格」,手上有以下數據:…

【論文解讀】CVPR2023 PoseFormerV2:3D人體姿態估計(附論文地址)

論文鏈接:https://arxiv.org/pdf/2303.17472 源碼鏈接:https://github.com/QitaoZhao/PoseFormerV2 Abstract 本文提出了 PoseFormerV2,通過探索頻率域來提高 3D 人體姿態估計的效率和魯棒性。PoseFormerV2 利用離散余弦變換(DC…

DRW - 加密市場預測

1.數據集描述 在本次比賽中,數據集包含加密市場的分鐘級歷史數據。您的挑戰是預測未來的加密貨幣市場價格走勢。這是一項kaggle社區預測競賽,您可以以 CSV 文件的形式或通過 Kaggle Notebooks 提交您的預測。有關使用 Kaggle Notebooks 的更多詳細信息&a…

嵌入式Linux系統中的啟動分區架構

在嵌入式Linux系統架構中,Linux內核、設備樹(Device Tree)與引導配置文件構成了系統啟動的基礎核心。如何安全、高效地管理這些關鍵文件,直接影響到系統的穩定性與可維護性。近年來,越來越多的嵌入式Linux開發者選擇將啟動相關文件從傳統的“混合存放”方式,轉向采用獨立…

用戶資產化視角下開源AI智能名片鏈動2+1模式S2B2C商城小程序的應用研究

摘要:在數字化時代,平臺流量用戶尚未完全轉化為企業的數字資產,唯有將其沉淀至私域流量池并實現可控、隨時觸達,方能成為企業重要的數字資產。本文從用戶資產化視角出發,探討開源AI智能名片鏈動21模式S2B2C商城小程序在…

Spring是如何實現屬性占位符解析

Spring屬性占位符解析 核心實現思路1?? 定義占位符處理器類2?? 處理 BeanDefinition 中的屬性3?? 替換具體的占位符4?? 加載配置文件5?? Getter / Setter 方法 源碼見:mini-spring 在使用 Spring 框架開發過程中,為了實現配置的靈活性&#xf…

【大模型面試每日一題】Day 31:LoRA微調方法中低秩矩陣的秩r如何選取?

【大模型面試每日一題】Day 31:LoRA微調方法中低秩矩陣的秩r如何選取? 📌 題目重現 🌟🌟 面試官:LoRA微調方法中低秩矩陣的秩r如何選取?: #mermaid-svg-g5hxSxV8epzWyP98 {font-family:"…

字節golang后端二面

前端接口使用restful格式,post與get的區別是什么? HTTP網絡返回的狀態碼有哪些? go語言切片與數組的區別是什么? MySQL實現并發安全避免兩個事務同時對一個記錄寫操作的手段有哪些? 如何實現業務的冪等性(在…

Spring Security安全實踐指南

安全性的核心價值 用戶視角的數據敏感性認知 從終端用戶角度出發,每個應用程序都涉及不同級別的數據敏感度。以電子郵件服務與網上銀行為例:前者內容泄露可能僅造成隱私困擾,而后者賬戶若被操控將直接導致財產損失。這種差異體現了安全防護需要分級實施的基本原則: // 偽…

Leetcode第451場周賽分析總結

題目鏈接 競賽 - 力扣&#xff08;LeetCode&#xff09;全球極客摯愛的技術成長平臺 題目解析 A. 3560. 木材運輸的最小成本 AC代碼 class Solution { public:long long minCuttingCost(int n, int m, int k) {if (n > m) swap(n, m); // n < m;using ll long lon…

Linux中的shell腳本

什么是shell腳本 shell腳本是文本的一種shell腳本是可以運行的文本shell腳本的內容是由邏輯和數據組成shell腳本是解釋型語言 用file命令可以查看文件是否是一個腳本文件 file filename 腳本書寫規范 注釋 單行注釋 使用#號來進行單行注釋 多行注釋 使用 : " 注釋內容…

PHP與MYSQL結合中中的一些常用函數,HTTP協議定義,PHP進行文件編程,會話技術

MYSQL&#xff1a; 查詢函數: 執行查詢語句: 1.mysql_query("SQL語法"); 凡是執行操作希望拿到數據庫返回的數據進行展示的(結果返回: 數據結果); 2.執行結果的處理:成功為結果集&#xff0c;失敗為false; 成功返回結果:SQL指令沒有錯誤&#xff0c;但是查詢結果…

數學分析——一致性(均勻性)和收斂

目錄 1. 連續函數 1.1 連續函數的定義 1.2 連續函數的性質 1.2.1 性質一 1.2.2 性質二 1.2.3 性質三 1.2.4 性質四 2. 一致連續函數 2.1 一致連續函數的定義 2.2 一致連續性定理(小間距定理)(一致連續函數的另一種定義) 2.3 一致連續性判定法 2.4 連…

湖北理元理律師事務所:企業債務優化的科學路徑與人文關懷

湖北理元理律師事務所&#xff1a;企業債務優化的科學路徑與人文關懷 在中小企業經營壓力增大的背景下&#xff0c;如何平衡債務清償與員工生計成為關鍵課題。湖北理元理律師事務所聯合計劃集團公司&#xff0c;為服務企業設計了一套兼顧法律合規性與民生保障的債務解決方案&a…