MySQL字段類型

MySQL 字段類型

一、數值

MySQL 的數值數據類型能夠大體劃分爲兩個類別,一個是整數,另外一個是浮點數或小數。
許多不一樣的子類型對這些類別中的每個都是可用的,每一個子類型支持不一樣大小的數據,而且 MySQL 容許咱們指定數值字段中的值是否有正負之分(UNSIGNED)或者用零填補(ZEROFILL)。

在 MySQL 中支持的 5 個主要整數類型是 TINYINT,SMALLINT,MEDIUMINT,INT 和 BIGINT。這些類型在很大程度上是相同的,只有它們存儲的值的大小是不相同的。html

MySQL 以一個可選的顯示寬度指示器的形式對 SQL 標準進行擴展(如 INT(6),6便是其寬度指示器,該寬度指示器並不會影響int列存儲字段的大小,也就是說,超過6位它不會自動截取,依然會存儲,只有超過它自己的存儲範圍纔會截取;此處寬度指示器的做用在於該字段是否有zerofill,若是有就未知足6位的部分就會用0來填充),這樣當從數據庫檢索一個值時,能夠把這個值加長到指定的長度。例如,指定一個字段的類型爲 INT(6),就能夠保證所包含數字少於 6 個的值從數據庫中檢索出來時可以自動地用空格填充。須要注意的是,使用一個寬度指示器不會影響字段的大小和它能夠存儲的值的範圍。mysql

萬一咱們須要對一個字段存儲一個超出許可範圍的數字,MySQL 會根據容許範圍最接近它的一端截短後再進行存儲。還有一個比較特別的地方是,MySQL 會在不合規定的值插入表前自動修改成 0。sql

unsigned 和 zerofill
UNSIGNED 修飾符規定字段只保存正值,即無符號,而mysql字段默認是有符號的。由於不須要保存數字的正、負符號,能夠在儲時節約一個"位"的空間(即翻一倍)。從而增大這個字段能夠存儲的值的範圍。注意這個修飾符要緊跟在數值類型後面;
ZEROFILL 修飾符規定 0(不是空格)能夠用來真補輸出的值。使用這個修飾符能夠阻止 MySQL 數據庫存儲負值,若是某列設置爲zerofill,那它自動就unsigned。這個值要配合int,tinyint,smallint,midiumint等字段的寬度指示器來用;XXint(M),若是沒有zerofill,這個M的寬度指示器是沒有意義的.(注意,測試前導0的時候,仍是去黑窗口測試;)數據庫

爲何mysql存儲的值要分有符號和無符號呢?由於一個字節,佔8bit;也就1個bit有0和1兩種可能,8個bit就是2^8 = 256種可能,也就是0~255;但若是是有符號的話,就得拿一個1bit來存儲這個負號,原本8bit只剩7bit,2^7 = 128,也就是-128~127(正數部分包含一個0);函數

FLOAT、DOUBLE 和 DECIMAL 類型
MySQL 支持的三個浮點類型是 FLOAT、DOUBLE 和 DECIMAL 類型。FLOAT 數值類型用於表示單精度浮點數值,而 DOUBLE 數值類型用於表示雙精度浮點數值。
與整數同樣,這些類型也帶有附加參數:一個顯示寬度指示器和一個小數點指示器(必需要帶有指示器,要否則會查不到結果,而且寬度指示器和XXint類型的寬度指示器不一樣,這裏是有實際限制寬度的)。好比語句 FLOAT(7,3) 規定顯示的值不會超過 7 位數字(包括小數位),小數點後面帶有 3 位數字。對於小數點後面的位數超過容許範圍的值,MySQL 會自動將它四捨五入爲最接近它的值,再插入它。
DECIMAL 數據類型用於精度要求很是高的計算中,這種類型容許指定數值的精度和計數方法做爲選擇參數。精度在這裏指爲這個值保存的有效數字的總個數,而計數方法表示小數點後數字的位數。好比語句 DECIMAL(7,3) 規定了存儲的值不會超過 7 位數字,而且小數點後不超過 3 位。
FLOAT 類型在長度比較高好比 float(10,2)和 decimal(10,2)同時插入一個符合(10,2)寬度的數值,float 就會出現最後小數點出現一些出入;
UNSIGNED 和 ZEROFILL 修飾符也能夠被 FLOAT、DOUBLE 和 DECIMAL 數據類型使用。而且效果與 INT 數據類型相同。性能

關於flaot和double
在這裏我建議,乾脆忘記mysql有double這個數據類型。至於why?就不要管它了測試

 

二、字符串類型

MySQL 提供了 8 個基本的字符串類型,能夠存儲的範圍從簡單的一個字符到巨大的文本塊或二進制字符串數據。
優化

BINARY
BINARY不是函數,是類型轉換運算符,它用來強制它後面的字符串爲一個二進制字符串,能夠理解爲在字符串比較的時候區分大小寫加密

SELECT BINARY 'ABCD' = 'abcd' as COM1,'ABCD' = 'abcd' as COM2; -- COM1輸出爲0,COM2輸出爲1;

CHAR 和 VARCHAR 類型
CHAR 類型用於定長字符串,而且必須在圓括號內用一個大小修飾符來定義。這個大小修飾符的範圍從 0-255。比指定長度大的值將被截短,而比指定長度小的值將會用空格做填補spa

CHAR 類型可使用 BINARY 修飾符。當用於比較運算時,這個修飾符使 CHAR 以二進制方式參於運算,而不是以傳統的區分大小寫的方式。

CHAR 類型的一個變體是 VARCHAR 類型。它是一種可變長度的字符串類型,而且也必須帶有一個範圍在 0-255 之間的指示器。

CHAR 和 VARCHGAR 不一樣之處在於 MYSQL 數據庫處理這個指示器的方式:CHAR 把這個大小視爲值的大小,不長度不足的狀況下就用空格補足。而 VARCHAR 類型把它視爲最大值而且只使用存儲字符串實際須要的長度(增長一個額外字節來存儲字符串自己的長度)來存儲值。因此短於指示器長度的 VARCHAR 類型不會被空格填補,但長於指示器的值仍然會被截短。

由於 VARCHAR 類型能夠根據實際內容動態改變存儲值的長度,因此在不能肯定字段須要多少字符時使用 VARCHAR 類型能夠大大地節約磁盤空間、提升存儲效率。但若是確切知道字符串長度,好比就在50~55之間,那就用 CHAR 由於 CHAR 類型因爲自己定長的特性使其性能要高於 VARCHAR;

VARCHAR 類型在使用 BINARY 修飾符時與 CHAR 類型徹底相同。

TEXT 和 BLOB 類型
對於字段長度要求超過 255 個的狀況下,MySQL 提供了 TEXT 和 BLOB 兩種類型。根據存儲數據的大小,它們都有不一樣的子類型。這些大型的數據用於存儲文本塊或圖像、聲音文件等二進制數據類型。

TEXT 和 BLOB 類型在分類和比較上存在區別。BLOB 類型區分大小寫,而 TEXT 不區分大小寫。大小修飾符不用於各類 BLOB 和 TEXT 子類型。比指定類型支持的最大範圍大的值將被自動截短。

 

三、時間類型

在處理日期和時間類型的值時,MySQL 帶有 5 個不一樣的數據類型可供選擇。

DATE、TIME 和 YEAR 類型
MySQL 用 DATE 和 YEAR 類型存儲簡單的日期值,使用 TIME 類型存儲時間值。這些類型能夠描述爲字符串或不帶分隔符的整數序列。若是描述爲字符串,DATE 類型的值應該使用連字號做爲分隔符分開,而 TIME 類型的值應該使用冒號做爲分隔符分開。

須要注意的是,沒有冒號分隔符的 TIME 類型值,將會被 MySQL 理解爲持續的時間,而不是時間戳。

MySQL 還對日期的年份中的兩個數字的值,或是 SQL 語句中爲 YEAR 類型輸入的兩個數字進行最大限度的通譯。由於全部 YEAR 類型的值必須用 4 個數字存儲。MySQL 試圖將 2 個數字的年份轉換爲 4 個數字的值。把在 00-69 範圍內的值轉換到 2000-2069 範圍內。把 70-99 範圍內的值轉換到 1970-1979 以內。若是 MySQL 自動轉換後的值並不符合咱們的須要,請輸入 4 個數字表示的年份。

DATETIME 和 TIMESTAMP 類型
除了日期和時間數據類型,MySQL 還支持 DATETIME 和 TIMESTAMP 這兩種混合類型。它們能夠把日期和時間做爲單個的值進行存儲。這兩種類型一般用於自動存儲包含當前日期和時間的時間戳,並可在須要執行大量數據庫事務和須要創建一個調試和審查用途的審計跟蹤的應用程序中發揮良好做用。若是咱們對 TIMESTAMP 類型的字段沒有明確賦值,或是被賦與了 null 值。MySQL 會自動使用系統當前的日期和時間來填充它。

 

四、複合類型

MySQL 還支持兩種複合數據類型 ENUM 和 SET,它們擴展了 SQL 規範。雖然這些類型在技術上是字符串類型,可是能夠被視爲不一樣的數據類型。一個 ENUM 類型只容許從一個集合中取得一個值;而 SET 類型容許從一個集合中取得任意多個值。

ENUM 類型
ENUM 類型由於只容許在集合中取得一個值,有點相似於單選項。在處理相互排拆的數據時容易讓人理解,好比人類的性別。ENUM 類型字段能夠從集合中取得一個值或使用 null 值,除此以外的輸入將會使 MySQL 在這個字段中插入一個空字符串。另外若是插入值的大小寫與集合中值的大小寫不匹配,MySQL 會自動使用插入值的大小寫轉換成與集合中大小寫一致的值。

ENUM 類型在系統內部能夠存儲爲數字,而且從 1 開始用數字作索引。一個 ENUM 類型最多能夠包含 65536 個元素,其中一個元素被 MySQL 保留,用來存儲錯誤信息,這個錯誤值用索引 0 或者一個空字符串表示。

MySQL 認爲 ENUM 類型集合中出現的值是合法輸入,除此以外其它任何輸入都將失敗。這說明經過搜索包含空字符串或對應數字索引爲 0 的行就能夠很容易地找到錯誤記錄的位置。

SET 類型
SET 類型與 ENUM 類型類似但不相同。SET 類型能夠從預約義的集合中取得任意數量的值。而且與 ENUM 類型相同的是任何試圖在 SET 類型字段中插入非預約義的值都會使 MySQL 插入一個空字符串。若是插入一個即有合法的元素又有非法的元素的記錄,MySQL 將會保留合法的元素,除去非法的元素。 一個 SET 類型最多能夠包含 64 項元素。還去除了重複的元素,因此 SET 類型中不可能包含兩個相同的元素。
但願從 SET 類型字段中找出非法的記錄只需查找包含空字符串或二進制值爲 0 的行。

五、字段類型總結

雖然上面列出了不少字段類型,但最經常使用也就是 varchar(255),char(255),text,tinyint(4),smallint(6),mediumint,int(11)幾種。

複合類型咱們通常用tinyint,更快的時間更省的空間以及更容易擴展

關於手機號,推薦用char(11),char(11)在查詢上更有效率,由於手機號是一個活躍字段參與邏輯會不少。

一些經常使用字段舉例
姓名:char(20)
價格:DECIMAL(7, 3)
產品序列號:SMALLINT(5) unsigned
文章內容: TEXT
MD5: CHAR(32)
ip: char(15)
time: int(10)
email char(32)

六、合理的選擇數據類型

選擇合理範圍內最小的
咱們應該選擇最小的數據範圍,由於這樣能夠大大減小磁盤空間及磁盤I/0讀寫開銷,減小內存佔用,減小CPU的佔用率。

選擇相對簡單的數據類型
數字類型相對字符串類型要簡單的多,尤爲是在比較運算時,因此咱們應該選擇最簡單的數據類型,好比說在保存時間時,由於PHP能夠良好的處理LINUX時間戳因此咱們能夠將日期存爲int(10)要方便、合適、快速的多

可是,工做中隨着項目越作越多,業務邏輯的處理愈來愈難之後,我發現時間類型仍是用時間類型自己的字段類型要好一些,由於mysql有着豐富的時間函數供我使用,方便我完成不少與時間相關的邏輯,好比月排行榜,周排行榜,當日熱門,生日多少天等等邏輯

 

不要使用null

爲何這麼說呢,由於MYSQL對NULL字段索引優化不佳,增長更多的計算難度,同時在保存與處理NULL類形時,也會作更多的工做,因此從效率上來講,不建議用過多的NULL。有些值他確實有可能沒有值,怎麼辦呢?解決方法是數值弄用整數0,字符串用空來定義默認值便可。

 

字符串類型的使用

字符串數據類型是一個萬能數據類型,能夠儲存數值、字符串、日期等。

保存數值類型最好不要用字符串數據類型,這樣存儲的空間顯然是會更大,並且在排序時字符串的9是大於22的,其實若是進行運算時mysql會將字符串轉換爲數值類型,大大下降效果,並且這種轉換是不會走原有的索引的。

若是明確數據在一個完整的集合中如男,女,那麼可使用set或enum數據類型,這種數據類型在運算及儲存時以數值方式操做,因此效率要比字符串更好,同時空間佔用更少。

VARCHAR與CHAR

VARCHAR是可變長度字符串類型,那麼即然長度是可變的就會使用1,2個字節來保存字符的長度,若是長度在255內使用1個字節來保存字符長度,不然使用2個字符來保存長度。因爲varchar是根據儲存的值來保存數據,因此能夠大大節約磁盤空間。

若是數據常常被執行更新操做,因爲VARCHAR是根據內容來進行儲存的,因此mysql將作更多的工做來完成更新操做,若是新數據長度大於老數據長度一些存儲引擎會進行拆分操做處理。同時varchar會徹底保留內部全部數據,最典型的說明就是尾部的空格。

CHAR固定長度的字符串保存類型,CHAR會去掉尾部的空格。在數據長度相近時使用char類型比較合適,好比md5加密的密碼用戶名等。

若是數據常常進行更新修改操做,那麼CHAR更好些,由於char長度固定,性能上要快。

數值類型的選擇

數值數據類型要比字符串執行更快,區間小的數據類型佔用空間更少,處理速度更快,如tinyint可比bigint要快的多

選擇數據類型時要考慮內容長度,好比是保存毫米單位仍是米而選擇不一樣的數值類型

整數

整數類型不少好比tinyint、int、smallint、bigint等,那麼咱們要根據本身須要存儲的數據長度決定使用的類型,同時tinyint(10)與tinyint(100)在儲存與計算上並沒有任何差異,區別只是顯示層面上,可是咱們也要選擇適合合適的數據類型長度。能夠經過指定zerofill屬性查看顯示時區別。

浮點數與精度數值

浮點數float在儲存空間及運行效率上要優於精度數值類型decimal,但float與double會有舍入錯誤而decimal則能夠提供更加準確的小數級精確運算不會有錯誤產生計算更精確,適用於金融類型數據的存儲。

相關文章
相關標籤/搜索