引言
從第一次學習mysql開始,不知道爲什麼MySQL的數據類型始終沒有像Java 一樣深入腦海,對某些數據類型的定義和用法,也並不清晰,這篇文章,就好好總結一番,將MySQL中幾個常用的數據類型歸納一下。
一、類型選擇的原則
在設計表的時候,首先就是要考慮存儲的數據與MySQL的哪種類型相吻合,比如,金額,就要用數字類型,最差也要用字符串類型,日期可以是date 類型,或者也可以是字符串類型,考慮這類問題,其實只需要考慮某個數據類型能否正確的表示將要存儲的數據即可。
第二點非常重要原則是:
所選擇的類型越簡單越好,能保存數值的類型越小越好。
這點不難理解,數據類型描述了物理硬件存儲數據的方式,簡單的類型更快,小的類型更省空間,因此,在選擇數據類型的時候就要儘可能的越小越簡單越好,避免存儲或性能上的浪費。
二、MySQL常見數據類型
與 Java 不同的是,MySQL的數據類型描述的更爲抽象化一些。它們總共分爲三類:
數值型、字符型、日期型
2.1 數值型
MySQL支持所有標準SQL數值數據類型。數值型可以分爲兩大類:整數和小數。
2.1.1 整數
整型共有 5 種:
Type | Storage (Bytes) | Minimum Value Signed | Minimum Value Unsigned | Maximum Value Signed | Maximum Value Unsigned |
---|---|---|---|---|---|
TINYINT |
1 | -128 |
0 |
127 |
255 |
SMALLINT |
2 | -32768 |
0 |
32767 |
65535 |
MEDIUMINT |
3 | -8388608 |
0 |
8388607 |
16777215 |
INT |
4 | -2147483648 |
0 |
2147483647 |
4294967295 |
BIGINT |
8 | -263 |
0 |
263-1 |
264-1 |
從官方文檔上來看,INTEGER 和 INT 貌似沒有什麼太大的區別,可以理解爲同義詞。從MySQL官網中的說明,我們可以得知,SQL標準的整數類型只有 INTEGER(或 INT)和 SMALLINT,而剩下三種,則是MySQL對標準的一種擴展。
符號的定義是值得注意的點,如果不指定 unsigned 關鍵字,那麼默認是有符號類型。如果插入的數據大於整型的範圍,那麼就會報 out of range 異常,同時插入臨界值。
整型一般可以不設置 Length,這個屬性代表了該類型的顯示長度。
2.1.2 定點數(Fixed-Point)
定點數屬於小數的一種,是一種可以存儲精確小數的數據類型。
DECIMAL 和 NUMERIC
這兩個類型用於存儲確切精度的數據,例如貨幣數據,當然,個人認爲在不同的場景下,可以採用最小貨幣單位存儲方式,比如,在數據庫中以整型存儲金額,以分作爲單位,並在整個系統中保持統一。
MySQL中,NUMERIC 是用 DECIMAL 來實現的,因此兩者在本質上是無區別的。
salary DECIMAL(5, 2)
薪資可以使用上面的方式進行定義,那麼它所表示的範圍就是:-999.99 到 999.99 。前一個參數是總位數,後一個參數代表小數保留的位數。
另外,還有一種特殊的形式 DECIMAL(M) ,它等同於 DECIMAL(M, 0) ,它的意思是沒有小數部分。或者乾脆不指定任何參數,如果不指定 M 則默認爲 10。
這樣定義的字段,如果插入的數據超過了限定範圍,那麼就會插入臨界值。
2.1.3 浮點數(Floating-Point)
FLOAT 和 DOUBLE 是兩個浮點數類型,前者是單精度佔4個字節,後者是雙精度佔8個字節。它們都是不精確的數據類型。
2.2 字符型
2.2.1 短文本 CHAR 和 VARCHAR
MySQL最常用的字符型是 CHAR 和 VARCHAR ,他們有相似處,同時存取卻也存在差異。
CHAR和 VARCHAR 都需要指定一個長度,這個長度描述了需要存儲的最大字符個數,如CHAR(30) 可以存儲最多 30 個字符,注意,所有單個漢字都算一個字符。
CHAR 類型以定長存儲,長度的範圍可以是 0 到 255 之間任意值。如果存儲的字符不夠,那麼 MySQL會爲其自動以空格填補空間,當取出時,又會爲其自動去除。
VARCHAR 類型以變長存儲,而且長度範圍可以是 0 到 65535 之間任意值。但其有效最大長度取決於最大行大小以及字符集。
Value | CHAR(4) |
Storage Required | VARCHAR(4) |
Storage Required |
---|---|---|---|---|
'' |
' ' |
4 bytes | '' |
1 byte |
'ab' |
'ab ' |
4 bytes | 'ab' |
3 bytes |
'abcd' |
'abcd' |
4 bytes | 'abcd' |
5 bytes |
'abcdefgh' |
'abcd' |
4 bytes | 'abcd' |
5 bytes |
2.2.2 長文本 TEXT 和 BLOB
BLOB是一個二進制大對象,可以容納可變數量的數據,TEXT 可以存儲較大的文本。
參考官網:https://dev.mysql.com/doc/refman/5.7/en/blob.html
2.2.3 ENUM 類型
在 MySQL中,枚舉類型也屬於字符型,枚舉的值必須是字符串,不區分大小寫。如:
CREATE TABLE enum_t(
state ENUM('1', '2', '4')
)
枚舉類型非常適合定義一些記錄狀態變化的字段,比如訂單狀態,這樣,可以極好的提升數據的可維護性。在官方給出的說明中,有如下兩方面。
優勢:
1、壓縮了數據出現的情況,同時,MySQL會自動將存儲的字符串編碼爲數字,即進行了一些優化。
2、可讀性的查詢和輸出。MySQL會結果集中自動將底層存儲的數字轉化回原來定義的字符串。
需要考慮的問題:
1、enum 類型內部維護着從 1 開始的索引值,每個字符串枚舉值都對應着一個正整數序號 1、2、3... ,這也是爲什麼enum 裏的枚舉值必須是字符串的原因,而且官方也不建議枚舉值的字符串和數字看起來很像,這樣很容易和索引值混淆,因爲我們同樣可以直接使用索引值對字段進行插入操作:
2、對枚舉字段使用 order by 子句,會按照索引順序排序。這和Java 中的枚舉排序基本一致(Java 中是按照枚舉值定義的位置順序來默認排序的)。另外,空字符串排在所有非空字符串前面,NULL 排在其他所有值前面。
2.2.4 SET 類型
SET 類型可以保存最多64個成員。與 ENUM 最大的區別在 SET 類型一次可以選取多個成員,而 ENUM 只能選取一個。
存儲的值用一個引號包裹起來,每個值中間用逗號隔開注意中間不允許有空格:
''
'one'
'two'
'one,two'
2.3 日期型
參考之前的總結《MySQL日期類型的處理總結》
值得一提的是,日期類型需要用引號(單雙都可)引起來,換句話說,我們可以直接將日期類型理解爲符合日期格式規範的字符串。在Java 中,我們甚至可以直接以字符串的形式與MySQL進行日期類型的交互而不會有任何問題。
綜上,就是關於MySQL常用數據類型的簡單總結,參考了尚硅谷的MySQL基礎視頻,以及MySQL官網對數據類型的解釋:
https://dev.mysql.com/doc/refman/5.7/en/data-types.html