【深入淺出MySQL】之數據類型介紹

【深入淺出MySQL】之數據類型介紹

  • MySQL中常見的數據類型一覽
  • 為什么需要如此多的數據類型
  • 數值類型
    • BIT(M)類型
    • INT類型
    • TINYINT類型
    • BIGINT類型
    • 浮點數類型
      • float類型
      • DECIMAL(M,D)類型
      • 區別總結
  • 字符串類型
    • CHAR類型
    • VARCHAR(M)類型
  • 日期和時間類型
  • enum和set類型

前言:MySQL是一種廣泛使用的關系型數據庫管理系統,它提供了多種數據類型供開發者去選擇,以此來滿足不同的場景。

MySQL中常見的數據類型一覽

類別數據類型描述存儲范圍/長度常見用途
數值類型TINYINT非常小的整數-128 到 127(有符號);0 到 255(無符號)存儲小的整數,如狀態碼(0/1)、年齡等
BITM位類型,M指定位數,默認值1M的范圍(1~64)適用于需要存儲二進制信息的情況,例如標志位、布爾值數組等。通過使用 BIT 類型,可以更有效地存儲和操作位級別的數據。
SMALLINT小整數-32,768 到 32,767(有符號);0 到 65,535(無符號)存儲中等范圍的整數,如計數器、小范圍的ID
MEDIUMINT中等大小的整數-8,388,608 到 8,388,607(有符號);0 到 16,777,215(無符號)存儲中等范圍的整數,較少使用
INT / INTEGER標準整數-2,147,483,648 到 2,147,483,647(有符號);0 到 4,294,967,295(無符號)存儲常用整數,如用戶ID、訂單號等
BIGINT大整數-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807(有符號)存儲大范圍整數,如大型系統的ID、計數器
FLOAT單精度浮點數約 ±3.4E+38(7位有效數字)存儲近似數值,如價格、科學計算數據
DOUBLE雙精度浮點數約 ±1.79E+308(15位有效數字)存儲更高精度的近似數值,如金融數據、科學計算
DECIMAL(M,D)定點數(精確小數)M 是總位數,D 是小數位數,例如 DECIMAL(10,2) 存儲 8位整數+2位小數存儲精確小數,如貨幣金額(避免浮點誤差)
字符串類型CHAR(M)固定長度字符串0 到 255 個字符存儲固定長度的字符串,如狀態碼、性別(‘M’/‘F’)
VARCHAR(M)可變長度字符串0 到 65,535 個字符(取決于字符集和存儲引擎)存儲可變長度的字符串,如用戶名、地址
TINYTEXT短文本字符串最大 255 個字符存儲短文本,如備注、小段描述
TEXT標準文本字符串最大 65,535 個字符存儲較長的文本,如文章內容、評論
MEDIUMTEXT中等長度文本字符串最大 16,777,215 個字符存儲中等長度的文本,如長篇文章
LONGTEXT超長文本字符串最大 4,294,967,295 個字符存儲超長文本,如日志文件、JSON 數據
ENUM('value1', 'value2', ...)枚舉類型,只能從預定義值中選擇一個值最多 65,535 個不同值存儲固定選項,如狀態(‘active’/‘inactive’)、性別(‘male’/‘female’)
SET('value1', 'value2', ...)集合類型,可以選擇多個預定義值(以逗號分隔)最多 64 個不同值存儲多選選項,如興趣(‘reading,swimming’)
日期和時間類型DATE日期1000-01-01 到 9999-12-31存儲日期,如生日、注冊日期
TIME時間-838:59:59 到 838:59:59存儲時間,如一天中的時間點、持續時間
DATETIME日期和時間組合1000-01-01 00:00:00 到 9999-12-31 23:59:59存儲完整的日期和時間,如創建時間、更新時間
TIMESTAMP時間戳(從 1970-01-01 00:00:00 UTC 開始)1970-01-01 00:00:00 到 2038-01-19 03:14:07(UTC)存儲時間戳,常用于記錄數據更新時間(自動更新)
YEAR年份1901 到 2155(4位格式);70 到 69(2位格式,1970-2069)存儲年份,如出生年份、發布年份
其他類型BINARY(M)固定長度的二進制字符串0 到 255 個字節存儲固定長度的二進制數據,如校驗碼
VARBINARY(M)可變長度的二進制字符串0 到 65,535 個字節存儲可變長度的二進制數據,如小型文件
BLOB二進制大對象最大 65,535 個字節存儲二進制數據,如圖片、文件
MEDIUMBLOB中等長度的二進制大對象最大 16,777,215 個字節存儲中等大小的二進制數據,如較大的文件
LONGBLOB超長二進制大對象最大 4,294,967,295 個字節存儲超大二進制數據,如視頻文件
JSONJSON 格式數據(MySQL 5.7+ 支持)最大 1GB(受限于存儲引擎)存儲 JSON 數據,如配置信息、動態字段

為什么需要如此多的數據類型

似乎單一數據類型如字符類型可以存儲所有的數據,但事實上,我們需要如此多的數據類型的原因有以下幾種:

  • 數據的準確性與合法性需求:有時候我們描述某一個列時,如果這個列只能是整數,而不能出現小數點(如id),此時如果只有字符類型就滿足不了需求,而整數類型和浮點數類型的存在就可以有效防止非法的數據進入數據庫中。
  • 性能上
    • 空間上:如果只有單一的INT類型的整數,有時候某些列的大小永遠不會超過某一個整數值,這個時候使用INT就很浪費空間,所以使用 TINYINT 來存儲 0 到 255 范圍內的整數比使用 VARCHAR 更節省空間。
    • 時間上:對于數值運算,直接使用數值類型而不是字符串類型進行計算會更加高效。這是因為數值類型可以直接參與算術運算,而字符串則需要先轉換成數值形式才能進行相應的操作,這增加了額外的處理開銷。
  • 功能上
    • 日期時間處理:專門的日期時間類型(如 DATE, TIME, DATETIME)提供了豐富的函數支持,方便進行日期計算、格式化輸出等操作。如果用字符串表示日期時間,則需要手動編寫代碼來進行這些操作,不僅復雜而且容易出錯。
  • 查詢優化:
    • 索引利用:某些數據類型允許創建特定類型的索引(如全文索引適用于 TEXT 類型),從而提高查詢能力。如果所有數據都以字符串形式存儲,則可能無法充分利用這些高級索引功能。

數值類型

BIT(M)類型

BIT是位類型,其中M是位數,如果你想精確控制該列的位數,可以使用這個類型。

  1. 創建一個表tt1,表中有一個num列,它的類型是BIT(1)

    image-20250323160326121

  2. 表創建成功了:

    image-20250323160352415

  3. 向表中插入數據:

    image-20250323160647744

    • 超過1就插入失敗,因為bit位的位數位1,只能表示01
    • 但是發現一個很奇怪的現象,就算查表,1沒有顯示出來。
  4. 這是因為bit類型是默認是按照ASCII碼,1對應的符號是不可顯示的特殊符號。

    image-20250323161104285

  5. 測試一下bit類型位數的邊界情況:

    create table tt3(num bit(65));
    create table tt4(num bit(0));
    

    image-20250323161255461

[!tip]

如果我們有一些列,只需要0或者1就可以使用bit(1),這樣非常節省空間。

INT類型

INT類型的范圍:-2,147,483,648 到 2,147,483,647(有符號);0 到 4,294,967,295(無符號)

這和我們C語言中的是相符的。

但C語言中溢出后會截斷,數據庫是否會這樣呢?

  1. 首先我們創建表tt4

    create table tt4(num int);
    
  2. 查看表tt4:

    image-20250323162142786

    • int后面的數字的含義:這是表示的默認寬度,通常配合ZEROFILL屬性使用,這個后面我們再談,和C語言中的printf的格式控制符很像。
  3. 插入一個數字,我們測試int的邊界,插入21474836472,147,483,648,-2,147,483,648 -2,147,483,649

    image-20250323215634411

TINYINT類型

TINYINT也是整數類型,但是它只能表示-128 到 127(有符號),0 到 255(無符號)當你的列需要一個整數類型來表示,但是不會超過255時就可以使用這個類型。

  1. 創建表tt5

    create table tt5(num tinyint);
    
  2. 越界測試:

    insert into tt5 values(128);
    

    image-20250323220704189

BIGINT類型

大整數類型,它能表示-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807(有符號),適合做大型系統的id列的類型、計數器等。

  1. 創建表tt6

    create table tt6(num bigint);
    
  2. 數據類型邊界測試:

    insert into tt6 values(-9223372036854775808);
    

    image-20250323221222211

浮點數類型

float類型

語法(syntax)

float[(m, d)] [unsigned] : M指定顯示長度,d指定小數位數,占用空間4
  1. 創建表tt7,它有一個num列是float(5,2)類型,長度為5,小數位數為2,它可以表示999.99 ~ -999.99的值:

    create table tt7(float(5,2));
    
  2. 插入一些值觀察現象:

    mysql> insert into tt7 values(999.99999999);
    ERROR 1264 (22003): Out of range value for column 'num' at row 1
    mysql> insert into tt7 values(999.99);
    Query OK, 1 row affected (0.00 sec)mysql> insert into tt7 values(999.93);
    Query OK, 1 row affected (0.00 sec)mysql> insert into tt7 values(-999.999);
    ERROR 1264 (22003): Out of range value for column 'num' at row 1
    mysql> insert into tt7 values(-999.99);
    Query OK, 1 row affected (0.00 sec)mysql> insert into tt7 values(-9999);
    ERROR 1264 (22003): Out of range value for column 'num' at row 1
    mysql> insert into tt7 values(-99);Query OK, 1 row affected (0.00 sec)
    mysql> select * from tt7;
    +---------+
    | num     |
    +---------+
    |  999.99 |
    |  999.93 |
    | -999.99 |
    |  -99.00 |
    +---------+
    • 可以看到依舊會發生越界的情況。
  3. 如果我們插入的值長度超過M,但是范圍又在此時[M,d]所限定的范圍內,就會發生四舍五入的情況:

    image-20250323222356706

DECIMAL(M,D)類型

M 是總位數,D 是小數位數,例如 DECIMAL(10,2) 存儲 8位整數+2位小數

聽上去好像和float沒什么區別呀,我們來建個表插入數據看看:

  1. 創建表tt8,它有一列num,數據類型為decimal(5,2),存儲3位整數+2位小數:

    create table tt8(num decimal(5,2));
    
  2. 插入一些值,然后觀察現象:

    insert into tt8 values(999.976)
    ...
    

    image-20250323223540971

  • 它似乎也和float一樣也會進行越界判斷,也會四舍五入,那它們有什么區別呢?

區別總結

我們從實際的現象來觀察并思考為什么會這樣。

  1. 創建表tt9

    create table tt9(num1 float(10,1),num2 decimal(10,1));
    
  2. 插入下面的值:

    insert into tt9(999999998,999999998);
    
  3. 表中最終的結果:

    mysql> select * from tt9;
    +--------------+-------------+
    | num1         | num2        |
    +--------------+-------------+
    | 1000000000.0 | 999999998.0 |
    +--------------+-------------+
    
    • 居然!,num1被近似成了1000000000.0 ,而且總長度是11位,我們不是規定了總長度嗎?這個num2是正常顯示的。
  4. 我們手動插入一下一行讓num11000000000.0,看能否成功:

    mysql> insert into tt9 values(1000000000.0,999999998);
    ERROR 1264 (22003): Out of range value for column 'num1' at row 1
    
    • 很明顯失敗了,MySQL報錯了。

總結

  • FLOAT 是近似類型:它不保證精確存儲和顯示,可能會對大數值進行近似處理。
  • DECIMAL 是精確類型:它嚴格按照定義的范圍和精度存儲和顯示數據。
  • 顯示寬度不受嚴格限制:FLOAT(M,D) 的定義主要用于限制存儲范圍(也就是限制用戶的),但實際顯示的寬可能會因為近似超出定義的范圍。

所以如果我們的列對數據的精確性要求很高,且是浮點數,就需要使用DECIMAL類型。

字符串類型

CHAR類型

語法:char(L):固定長度字符串,不管用戶輸入的字符串的長度為多少,MySQL都會拿出L的長度給該列,L的最大值是255

[!caution]

MySQL里面的一個長度就對應一個字符,不管你是中文、英文字符、還是特殊字符都只占一個長度單位,也就是說MySQL對于字符長度有自己的標準。在 MySQL 中,字符長度單位指的是字符的數量,而不是字節數。但是,實際占用的存儲空間取決于字符集。

下面我們創建表,插入一些值來驗證一下:

  1. 創建表tt10

    create table tt10(s char(5));
    
  2. 插入一些字符:

    insert into tt10 values('你好世界呀');
    insert into tt10 values('abcde');
    insert into tt10 values('abcdef');
    

    image-20250323230740596

  • 我們都知道實際上中文字符的存儲字節和英文字符的存儲字節一般是不同的,要看具體的存儲編碼,所以在 MySQL 中,字符長度單位指的是字符的數量,而不是字節數。

[!caution]

如果你插入的字符的長度比L小,MySQL會自動填充空格。

VARCHAR(M)類型

varchar(L): 可變長度字符串,L表示字符長度,最大長度65535個字節

  1. 創建表tt11

    create table tt11(s varchar(10));
    
  2. 插入一些字符串:

    insert into tt11 values("111");
    insert into tt11 values("1111111111");
    

    image-20250324172213459

[!caution]

變長并不是這個類型存儲的字符的長度可以超過用戶指定的長度L,而是當用戶實際存儲的字符長度沒有L時,MySQL不會使用空格填充,這樣節省了空間。

如何選擇charvarchar類型

  1. 如果指定列的字符串長度是固定的,就使用char類型。
  2. 當存儲大量可變長度的字符串時,可以使用varchar來節省存儲空間。
  3. CHAR 因為是定長的,存儲和檢索效率更高,尤其是在頻繁訪問和更新的場景中。
  4. VARCHAR 因為需要額外的長度信息,存儲和檢索效率略低,但在現代數據庫系統中,這種差異通常不明顯。

日期和時間類型

MySQL中日期類型(如 DATEDATETIMETIMESTAMP 等)是非常重要的數據類型。它們的存在是為了更高效地存儲、查詢和操作與時間相關的數據。

日期類型可以表示廣泛的日期范圍,遠超過普通字符串或數字能表達的范圍。例如:

  • DATE 類型支持從 ‘1000-01-01’ 到 ‘9999-12-31’ 的日期。
  • DATETIMETIMESTAMP 支持精確到秒甚至微秒的時間點。

下面我們創建一個表,使用一下日期類型:

  1. 創建表tt12

    create table tt12(d1 date,d2 datetime,t timestamp);
    
  2. 插入一些值:

    insert into tt12 values('1922-01-22','1922-01-22 00:00:00',FROM_UNIXTIME(1));
    
    • TIMESTAMP 不支持直接插入原始的 Unix 時間戳(如 1742947200),需要通過 FROM_UNIXTIME() 函數進行轉換。插入當前時間:可以使用 NOW()CURRENT_TIMESTAMP 來插入當前時間。

    • DATETIME存儲日期和時間。

    • DATE只存儲日期。

      image-20250324174151354

enum和set類型

ENUM(枚舉)類型是一種字符串對象,其值范圍必須來自一個預定義的列表。這些值是按定義順序排列的,并且只能選擇列表中的值之一。

SET 類型是一種字符串對象,它可以包含零個或多個由逗號分隔的值,這些值來自于一個預定義的列表。與 ENUM 不同的是,SET 允許一個字段包含多個值。

使用介紹:

  1. 創建表tt13

    create table tt13(identity enum('學生','老師','工人'), set permissions('write','read','exec'));
    
  2. 插入一些值:

    mysql> insert into tt13 values('學生','write,res');
    ERROR 1265 (01000): Data truncated for column 'permissions' at row 1
    mysql> insert into tt13 values('學生','write,read');
    Query OK, 1 row affected (0.00 sec)mysql> insert into tt13 values('學生','write');
    Query OK, 1 row affected (0.00 sec)mysql> insert into tt13 values('學生,老師','write');
    ERROR 1265 (01000): Data truncated for column 'identity' at row 1
    mysql> insert into tt13 values('學生1','write');
    ERROR 1265 (01000): Data truncated for column 'identity' at row 1

    image-20250324174923450

應用場景

  • 使用 ENUM
    • 當字段的值是單一選項時。
    • 需要確保數據一致性且選項數量較少。
    • 場景示例:性別、狀態、分類等。
  • 使用 SET
    • 當字段的值是多個選項的組合時。
    • 需要靈活的多選功能且選項數量較少。
    • 場景示例:權限、興趣愛好、標簽等。

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

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

相關文章

數字化時代下,軟件測試中的滲透測試是如何保障安全的?

在如今數字化與信息化的時代,軟件測試中存在滲透測試,其位置十分重要,它借助模擬惡意攻擊的方式,去發現軟件系統所存在的漏洞以及安全問題,這是保障軟件安全的關鍵環節,接下來我會對它的各個方面進行詳細介…

Pytorch - Developer Notes 1/2

文章目錄 自動混合精度示例典型的混合精度訓練處理未縮放梯度梯度裁剪 處理縮放梯度梯度累積梯度懲罰 處理多個模型、損失函數和優化器多 GPU 工作環境下的注意事項單進程中的DataParallel分布式數據并行:每個進程對應一個GPU每個進程使用多塊GPU的DistributedDataP…

RuntimeError: CUDA error: __global__ function call is not configured

表明在 CUDA 設備上調用的核函數 沒有正確配置線程塊和網格維度。 一般體現在: 直接調用 kernel 函數,而不是通過 launch 函數 指定 kernel 函數調用 解決方法(示例): // kernel function __global__ void Idtest_k…

cloudfare+gmail 配置 smtp 郵箱

這里介紹有一個域名后,不需要服務器,就可以實現 cloudfare gmail 的 郵箱收發。 為什么還需要 gmail 的 smtp 功能,因為 cloudfare 默認只是對 email 進行轉發,就是只能收郵件而不能發送郵件,故使用 gmail 的功能來進…

如何在 CentOS 7 命令行連接 Wi-Fi?如何在 Linux 命令行連接 Wi-Fi?

如何在 CentOS 7 命令行連接 Wi-Fi?如何在 Linux 命令行連接 Wi-Fi? 摘要 本教程覆蓋如何在多種 Linux 發行版下通過命令行連接 Wi-Fi,包括: CentOS 7、Ubuntu、Debian、Arch Linux、Fedora、Alpine Linux、Kali Linux、OpenSU…

基于PHP的在線編程課程學習系統

有需要請加文章底部Q哦 可遠程調試 基于PHP在線編程課程學習系統 一 介紹 在線編程課程學習系統基于原生PHP開發,數據庫mysql,前端jquery.js。系統角色分為學生,教師和管理員。(附帶參考設計文檔) 技術棧:phpmysqljquery.jsphps…

PyTorch_張量形狀操作

搭建模型時,數據都是基于張量形式的表示,網絡層與層之間很多都是以不同的shape的方式進行表現和運算。 對張量形狀的操作,以便能夠更好處理網絡各層之間的數據連接。 reshape 函數的用法 reshape 函數可以再保證張量數據不變的前提下改變數…

大模型實踐:圖文解鎖Ollama在個人筆記本上部署llm

使用在線模型服務時,我們常常需要支付API調用費用,這對于個人開發者或小型組織來說可能是一筆不小的開支。那么,有沒有方法可以在本地免費使用這些強大的模型呢?答案是肯定的——Ollama就是這樣一個工具。 當然如果是比較大的組織…

Python基本語法(lambda表達式)

lambda表達式 lambda的一般形式是在關鍵字lambda后面跟一個或多個參數,之后再緊跟一個 冒號,接下來是一個表達式。lambda是一個表達式,而不是一個語句,它能夠出現 在Python語法不允許def出現的地方。作為表達式,lambd…

【MySQL數據庫】用戶管理

目錄 1,用戶信息 2,創建/刪除/修改用戶 3,數據庫的權限 MySQL數據庫安裝完之后,我們最開始時使用的都是 root 用戶,其它用戶通常無法進行操作。因此,MySQL數據庫需要對用戶進行管理。 1,用戶…

Python的ArcPy基于Excel表格對大量遙感影像批量重分類

本文介紹基于Python中的ArcPy模塊,以Excel表格內的信息,對遙感影像加以重分類的方法。 首先,明確一下本文的需求。現有按照文章ArcPy批量將柵格文件的屬性表導出為Excel表格的方法(https://blog.csdn.net/zhebushibiaoshifu/artic…

LabVIEW 中VI Server導出 VI 配置

該 LabVIEW VI 展示了在 VI Server 中配置和執行 Exported VIs 的過程,實現對服務器端導出 VI 的遠程調用與操作。 ? 具體過程及模塊說明 前期配置:需確保在 LabVIEW 的 “Tools> Options > VI Server > Protocols” 路徑下,啟用 …

論文閱讀:2024 ACM SIGSAC Membership inference attacks against in-context learning

總目錄 大模型安全相關研究:https://blog.csdn.net/WhiffeYF/article/details/142132328 Membership inference attacks against in-context learning https://arxiv.org/pdf/2409.01380 https://www.doubao.com/chat/4030440311895554 速覽 這篇論文主要研究了…

從 Python 基礎到 Django 實戰 —— 數據類型驅動的 Web 開發之旅

主題簡介: 本主題以 Python 基礎數據類型為核心,結合 Django 框架的開發流程,系統講解如何通過掌握數字、字符串、列表、元組、字典等基礎類型,快速構建功能完善的 Web 應用。通過理論與實踐結合,幫助學員從零基礎 Py…

軟考 系統架構設計師系列知識點之雜項集萃(53)

接前一篇文章:軟考 系統架構設計師系列知識點之雜項集萃(52) 第85題 在靜態測試中,主要是對程序代碼進行靜態分析。“數據初始化、賦值或引用過程中的異常”屬于靜態分析中的()。 A. 控制流分析 B. 數據…

Raycaster光線投射

Raycaster光線投射 3D虛擬工廠在線體驗 描述 光線投射Raycaster,用于進行raycasting(光線投射)。 光線投射用于進行鼠標拾取(在三維空間中計算出鼠標移過了什么物體)。 構造器 Raycaster( origin : Vector3, dire…

初識Linux —— git三板斧

版本控制器git 為了我們方便管理不同版本的文件,就有了版本控制器; 所謂的版本控制器,就是能夠了解到一個文件的歷史記錄(修改記錄);簡單來說就是記錄每一次的改動和版本迭代的一個管理系統,同…

用哈希表封裝出unordered_set/_map

前提: ①:本博客是對哈希表(開散列)進行封裝,因為閉散列不優秀(與庫保持一致) ②:哈希表封裝出unordered_set/_map和紅黑樹封裝出ste/map是大同小異的,可以先看下:用紅黑樹封裝出set和map -CSDN博客 ③&…

情緒ABC——AI與思維模型【93】

一、定義 情緒ABC思維模型是一種心理學上的理論,它認為人們的情緒和行為反應(C,Consequence)并非直接由激發事件(A,Activating event)引起,而是由個體對激發事件的認知和評價所產生…

Unity URP RenderTexture優化(二):深度圖優化

目錄 前言: 一、定位深度信息 1.1:k_DepthStencilFormat 1.2:k_DepthBufferBits 1.3:_CameraDepthTexture精度與大小 1.4:_CameraDepthAttachment數量 二、全代碼 前言: 在上一篇文章:Un…