天天看點

mysql資料類型

優化資料類型提高性能的主要原理在于以下幾個方面:

1. 通過選用更“小”的資料類型減少存儲空間,使查詢相同資料需要的 IO 資源降低;

2. 通過合适的資料類型加速資料的比較;

下面我們還是通過分析一些常用資料類型的資料存儲格式和長度來看看哪些資料類型可以在優化中

利用上吧。

數字日期類型

我們先來看看存放長度基本固定的一些資料類型的存儲長度和取值範圍。

對于數字類型,這裡分别列出了整數類型和小數類型,也就是浮點數類型。實際上,還有一類通過

二進制格式以字元串來存放的數字類型如 DECIMAL(DEC)[(M[,D])],NUMERIC[(M[,D])],由于其存放長度

主要通過其定義時候的的 M 所決定,M 定義為多大,則實際存放就有多長。M 代表整個位數長度,而 D 則

表示小數點後的位數,預設 M 為 10,D 為 0。一般來說,主要用在固定精度的場合,由于其存放長度較

大,而且考慮到這種資料完全可以變化形式以整數存放,是以筆者個人并不是特别推薦。

mysql資料類型

對于數字的存儲,一般使用到浮點型資料的場合也不應該太多。主要出于兩個原因,一個是浮點型

資料本身實際上是一個并不精确的數字,隻是一個近似值,另一個原因就是完全可以通過乘以一個固定

的系數轉換為整型資料來存放。這樣不僅可以解決資料不精确的問題,同時也讓資料的處理更為高效。

時間存儲格式總類并不是太多,我們常用的主要就是 DATETIME,DATE 和 TIMESTAMP 這三種了。從存

儲空間來看 TIMESTAMP 最少,四個位元組,而其他兩種資料類型都是八個位元組,多了一倍。而 TIMESTAMP 的

缺點在于他隻能存儲從 1970 年之後的時間,而另外兩種時間類型可以存放最早從 1001 年開始的時間。如

果有需要存放早于 1970 年之前的時間的需求,我們必須放棄 TIMESTAMP 類型,但是隻要我們不需要使用

1970 年之前的時間,最好盡量使用 TIMESTAMP 來減少存儲空間的占用。

上面所列出的主要是一些存放固定長度,且我們平時可能常用到的一些類型。通過這個對照表格,

我們可以很直覺的看出哪種類型占用的存儲空間大,哪種占用的空間小。這樣,在資料類型選擇的時

候,我們就可以結合各種類型的存儲範圍以及業務中可能存在的資料作出對應,然後選擇存儲空間最先

的類型來使用。

字元存儲類型

我們再來看看存放字元的資料類型。

CHAR[(M)]類型屬于靜态長度類型,存放長度完全以字元數來計算,是以最終的存儲長度是基于字元

集的,如 latin1 則最大存儲長度為 255 位元組,但是如果使用 gbk 則最大存儲長度為 510 位元組。CHAR 類型

的存儲特點是不管我們實際存放多長資料,在資料庫中都會存放 M 個字元,不夠的通過空格補上,M 預設

為 1。雖然 CHAR 會通過空格補齊存放的空間,但是在通路資料的時候,MySQL 會忽略最後的所有空格,所

以如果我們的實際資料中如果在最後确實需要空格,則不能使用 CHAR 類型來存放。在 MySQL5.0.3 之前的

版本中,如果我們定義 CHAR 的時候 M 值超過 255,MySQL 會自動将 CHAR 類型進行轉換為可以存入對應數

據量的 TEXT 類型,如 CHAR(1000) 會自動轉換為 TEXT , CHAR(10000) 則會轉為 MEDIUMTEXT 。而從

MySQL5.0.3 開始,所有超過 255 的定義 MySQL 都會直接拒絕并給出錯誤資訊,不再自動轉換。

VARCHAR[(M)]屬于動态存儲長度類型,僅存占用實際存儲資料的長度。其存放的最大長度與 MySQL

版本有關,在 5.0.3 之前的版本 VARCHAR 以字元數控制最存儲的最大長度,最大隻能存放 255 個字元,占

用存儲空間的實際大小與字元集有關。但是從 5.0.3 開始,VARCHAR 的最大存儲限制已經更改為位元組數限

制了,擴充到可以存放 65535 bytes 的資料,不同的字元集可能存放的字元數并不一樣。也就是說,在

MySQL5.0.3 之前的版本,M 所代表的是字元數,而從 5.0.3 版本開始,M 的代表意思已經是位元組數了。

VARCHAR 的存儲特點是不管我們設定 M 為多大的值,真正占用的存儲空間都隻有我們所存入的實際資料的

大小,和 CHAR 不同的是 VARCHAR 會保留我們存入資料最後的空格,也就是說我們存入是什麼樣,MySQL

傳回給我們的也會是什麼樣。在 VARCHAR 類型字段的資料中,MySQL 會在每個 VARCHAR 資料中使用 1 個或

者 2 個位元組用來存放 VARCHAR 資料的實際長度,當我們的實際資料在 255 位元組之内的時候,會使用 1 位元組

來存放實際長度,而大于 255 位元組的時候,則需要使用 2 位元組來存放。

TINYTEXT,TEXT,MEDIUMTEXT 和 LONGTEXT 這四種類型同屬于一種存儲方式,都是動态存儲長度類

mysql資料類型

型,不同的僅僅是最大長度的限制。四種類型的定義都是通過最大字元數來限制,但是他們的字元數限

制實際上是可以了解為位元組數限制的,因為當我們使用多位元組字元集的時候,實際能存放的字元書并沒

最大字元數那麼多,而是以單位元組字元來計算的字元數。此外,由于是動态存儲長度類型,是以和

VARCHAR 一樣,每個字段資料之前都需要一個存放實際長度的空間。TINYTEXT 需要 1 個位元組來存放,TEXT

需要 2 個位元組,MEDIUMTEXT 和 LONGTEXT 則分别需要 3 個和 4 個位元組來存放實際資料長度。實際上,出了

MySQL 内嵌的最大長度限 制之外,他們還受到用戶端與伺服器端的網絡通信緩沖區最大值

(max_allowed_packet)的限制。

這四種 TEXT 類型和 CHAR 及 VARCHAR 在實際使用中存在幾個不一樣的地方:

◆ 不能設定預設值;

◆ 隻有 TEXT 可以使用 TEXT[(M)]這樣的方式通過 M 設定大小;

◆ 基于這四種類型的索引必須指定字首長度;

其他常用類型

除了上面這些字段類型之外會被我們經常使用到之外,我們還會使用到的資料類型主要有以下這

些。

mysql資料類型

對于 BIT 類型,M 表示每個值的 bits 數目,預設為 1,最大為 64 bits。對于 MySQL 來說這是一個新

的類型,因為從 MySQL5.0.3 才開始真正實作(在之前實際上是 TINYINT(1)),而且僅僅支援 MyISAM

存儲引擎,但是從 MySQL5.0.5 開始 Memory,Innodb 和 NDB Cluster 存儲引擎也開始“支援”了。在

MyISAM 中,BIT 的存儲空間很小,是真正的實作了通過 bit 來存儲,但是在其他的一些存儲引擎中就不一

樣了,因為他們是轉換為最小的 INT 類型存儲的,是以占用的空間也沒有節省,還不如直接使用 INT 類的

資料類型存放來得直覺。

對于 SET 和 ENUM 類型,主要内容基本處于較少變化狀态且值比較少的字段。雖然這兩個字段所占用

的存儲空間都較少,但是由于在使用方面較其他的資料類型要略為複雜一些,是以在實際環境中一般使

用還是較少。

誰都知道,資料量(這裡主要指資料記錄條數)的增加肯定會讓資料庫的檢索查詢效率降低。是以

很多時候人們大都希望通過減少資料庫中關鍵表的記錄條數來獲得資料庫性能的提升。實際上,除了這

種通過控制資料記錄條數來控制資料總量的辦法之外,我們還可以通過選擇更小的資料類型來讓資料庫

通過更小的空間存放相同的資料量,這對于檢索同樣的資料所帶來的 IO 消耗自然會降低,性能也就很自

然得到了提升。

此外,由于 CPU 對不同資料的處理方式不一樣,就會造成不同類型的資料在各種運算處理如比較,

排序等方面的處理效率存在差異。是以,對于我們需要經常進行比較計算以及排序等消耗 CPU 資源的字

段,應該盡量選擇處理更為迅速的字段類型。如通過整數類型代替浮點數或者字元類型。