- 數據表由多列字段構成,每個字段指定了不一樣的數據類型,指定了數據類型以後,也就決定了向字段插入的數據內容;
- 不一樣的數據類型也決定了 MySQL 在存儲它們的時候使用的方式,以及在使用它們的時候選擇什麼運算符號進行運算;
- 數值數據類型:TINYINT 、SMALINT 、MEDIUMINT 、INT 、BIGINT 、FLOAT 、DOUBLE 、DECIMAL;
- 日期/時間類型:YEAR 、TIME 、DATE 、DATETIME 、TIMESTAMP;
- 字符串類型:CHAR 、VARCHAR 、BINARY 、VARBINARY 、BLOB 、TEXT 、ENUM 、SET。
數值類型主要用來存儲數字,不一樣的數值類型提供不一樣的取值範圍,能夠存儲的值範圍越大,所須要的存儲空間也越大;
數值類型分爲:①整數類型 ②浮點數類型 ③定點數類型。mysql
一、整數類型以下:
sql
示例:數據庫
mysql> create table t1( -> m tinyint, -> n smallint, -> x mediumint, -> y int, -> z bigint unsigned # 默認是有符號的列,unsigned表示無符號列 -> );
查看錶的詳細信息以下(在建立表的時候沒有指定其長度,可是每一列都有本身默認的長度):
二、浮點數類型和定點數類型ide
- MySQL 中使用浮點數和定點數來表示小數,浮點數有兩種類型:單精度浮點數(FLOAT)和雙精度浮點數(DOUBLE),定點數只有 DECIMAL;
- 浮點數和定點數均可以用 (M,N) 來表示,其中 M 是精度,表示總共的位數,N 是標度,表示小數的位數,如:3.145,用M/N來表示就是4,3;
- DECIMAL 實際是以字符串形式存放的,在對精度要求比較高的時候(如貨幣、科學數據等)使用 DECIMAL 類型會比較好;
- 浮點數相對於定點數的優勢是在長度必定的狀況下,浮點數可以表示更大的數據範圍,它的缺點是會引發精度問題。
優化建議:函數
- 建議使用 TINYINT 代替 ENUM、BITENUM、SET;
- 避免使用整數的顯示寬度,也就是說,不要用INT(10)相似的方法指定字段顯示寬度,直接用INT;
- DECIMAL最適合保存準確度要求高,並且用於計算的數據,好比價格。可是在使用DECIMAL類型的時候,注意長度設置;
- 建議使用整型來運算和存儲實數,方法是,實數乘以相應的倍數後再操做;
- 整數一般是最佳的數據類型,由於它速度快,而且能使用AUTO_INCREMENT。
示例1:測試
#新建一個表,值的長度都爲5,小數點後都是兩位 mysql> create table tab2( -> x float(5,2), -> y double(5,2), -> z decimal(5,2) -> ); #插入一些正常符合要求的數據,並沒有報錯 mysql> insert into tab2 values(123.45,123.45,123.45); #插入一些不符合規定的數據,會返回1個warning信息 mysql> insert into tab2 values(123.456,123.456,123.456); Query OK, 1 row affected, 1 warning (0.01 sec) mysql> show warnings; # 查看warning信息,提示z列有截斷的數據 +-------+------+----------------------------------------+ | Level | Code | Message | +-------+------+----------------------------------------+ | Note | 1265 | Data truncated for column 'z' at row 1 | +-------+------+----------------------------------------+ 1 row in set (0.00 sec)
上述示例插入的數據,實際顯示以下(這裏會有兩個123.46,是我不當心多插入了一邊數據,因此可忽略多出的一行):
經過實際插入的數據不難發現,若是插入不符合列規定的數據,那麼最終會以四捨五入的方法處理。優化
須要注意的是,在上面的數值類型中,它只容許在小數點後面多一位,而不容許在小數點以前多一位,如插入1234.5或1234.35就會報錯。3d
示例2:excel
mysql> create table tab3( # 建立多個列,長度都爲10,小數點後面有兩位 -> x float(10,2), -> y double(10,2), -> z decimal(10,2) -> ); mysql> insert into tab3 values(12345678.123,12345678.123,12345678.123); Query OK, 1 row affected, 1 warning (0.01 sec) #一樣會返回warning信息,提示z列有截斷數據
最終插入到表中的數據以下:
在上面的表中,x列爲float數值類型,其餘兩列的數值仍是基於四捨五入的方法進行插入的,可是float數值類型的x列,插入的數據和實際輸入的數據就有些出入了,而且會隨着小數點位數的增長,這個浮動範圍會更大。
三、日期和時間類型
表示時間值的日期和時間類型爲DATETIME、DATE、TIMESTAMP、TIME和YEAR。code
每一個時間類型有一個有效值範圍和一個"零"值,當指定不合法的MySQL不能表示的值時使用"零"值。
TIMESTAMP類型有專有的自動更新特性。
優化建議:
- MySQL能存儲的最小時間粒度爲秒。
- 建議用DATE數據類型來保存日期。MySQL中默認的日期格式是yyyy-mm-dd;
- 用MySQL的內建類型DATE、TIME、DATETIME來存儲時間,而不是使用字符串;
- 當數據格式爲TIMESTAMP和DATETIME時,能夠用CURRENT_TIMESTAMP做爲默認(MySQL5.6之後), MySQL會自動返回記錄插入的確切時間;
- TIMESTAMP是UTC時間戳,與時區相關;
- DATETIME的存儲格式是一個YYYYMMDD HH:MM:SS的整數,與時區無關;
- 除非有特殊需求,不然建議使用TIMESTAMP,它比DATETIME更節約空間。
YEAR
格式1:以4位字符串格式表示的 YEAR ,範圍爲 '1901' ~ '2155';
格式2:以4位數字格式表示的 YEAR ,範圍爲 1901 ~ 2155;
格式3:以2位字符串格式表示的 YEAR ,範圍爲 '00' ~ '99' ,其中,'00' ~ '69' 被轉換爲 2000 ~ 2069 ,'70' ~ '99' 被轉換爲 1970 ~ 1999;
格式4:以2位數字格式表示的 YEAR ,範圍爲 1 ~ 99 ,其中,1 ~ 69 被轉換爲 2001 ~ 2069 ,70 ~ 99 被轉換爲 1970 ~ 1999。
例:
mysql> create table tab4(x year); # 新建一個表,只有一列,數值類型爲year mysql> insert into tab4 values('2000'),(2000),('96'),(96); # 依次插入四位的字符、數值;兩位的字符、數值
插入的數據以下:
mysql> delete from tab4; # 刪除原有數據 mysql> insert into tab4 values('0'),(0),('00'),(00); # 插入一些不符合列規定的數值
當插入的年份不合法時,會用0000表示。
當插入的年份不合法時,會用0000表示。
當插入的年份不合法時,會用0000表示。
2)TIME
- TIME 類型的格式爲 HH:MM:SS ,HH 表示小時,MM 表示分鐘,SS 表示秒
- 格式1:以 'HHMMSS' 格式表示的 TIME ,例如 '101112' 被理解爲 10:11:12 ,但若是插入不合法的時間,如 '109712' ,則被存儲爲 00:00:00
- 格式2:以 'D HH:MM:SS' 字符串格式表示的 TIME ,其中 D 表示日,能夠取 0 ~ 34 之間的值,在插入數據庫的時候 D 會被轉換成小時,如 '2 10:10' 在數據庫中表示爲 58:10:00 ,即 2x24+10 = 58
例:
mysql> create table tab5(date time); mysql> insert into tab5 values('12:12:12'),(121212),(3),('3 10:2'),(14),('08:08');
上述插入的數據,基本能夠對應SQL語句來看出來其規律,惟一須要解釋的,應該就是「82:02:00」,對應的插入值是「3 10:2」,最中寫入表中的時間是3天(3 X 24)+10小時,零2分鐘,也就是82個小時零兩分鐘。
3)DATE
- DATE 類型的格式爲 YYYY-MM-DD ,其中,YYYY 表示年,MM 表示月,DD 表示日;
- 格式1:'YYYY-MM-DD' 或 'YYYYMMDD' ,取值範圍爲 '1000-01-01' ~ '9999-12-3';
- 格式2:'YY-MM-DD' 或 'YYMMDD' ,這裏 YY 表示兩位的年值,範圍爲 '00' ~ '99' ,其中,'00' ~ '69' 被轉換爲 2000 ~ 2069 ,'70' ~ '99' 被轉換爲 1970 ~ 1999;
- 格式3:YY-MM-DD 或 YYMMDD ,數字格式表示的日期,其中 YY 範圍爲 00 ~ 99 ,其中,00 ~ 69 被轉換爲 2000 ~ 2069 ,70 ~ 99 被轉換爲 1970 ~ 1999。
例:
mysql> create table tab6(t date); # 建立一個表,列的數據類型爲date mysql> insert into tab6 values('1999-09-09'),(990909),(19990909); # 插入不一樣格式的日期
插入的結果以下:
其實,對於date這一種數值類型,對於其格式並無嚴格的要求,如2019-12-12這樣的數值能夠插入成功,2000!10:10這樣的數值一樣能夠插入成功,以下:
4)DATETIME
- DATETIME 類型的格式爲 YYYY-MM-DD HH:MM:SS ,其中,YYYY 表示年,MM 表示月,DD 表示日,HH 表示小時,MM 表示分鐘,SS 表示秒;
- 格式1:'YYYY-MM-DD HH:MM:SS' 或 'YYYYMMDDHHMMSS' ,字符串格式,取值範圍爲 '1000-01-01 00:00:00' ~ '9999-12-31 23:59:59';
- 格式2:'YY-MM-DD HH:MM:SS' 或 'YYMMDDHHMMSS' ,字符串格式,其中 YY 範圍爲 '00' ~ '99' ,其中,'00' ~ '69' 被轉換爲 2000 ~ 2069 ,'70' ~ '99' 被轉換爲 1970 ~ 1999;
- 格式3:YYYYMMDDHHMMSS 或 YYMMDDHHMMSS ,數字格式,取值範圍同上。
例:
mysql> create table tab7(dt datetime); mysql> insert into tab7 values('1996-09-19 12:24:56');
5)TIMESTAMP
- TIMESTAMP 類型的格式爲 YYYY-MM-DD HH:MM:SS,顯示寬度固定在19個字符;
- TIMESTAMP 與 DATETIME 的區別在於,TIMESTAMP 的取值範圍小於 DATETIME 的取值範圍;
- TIMESTAMP 的取值範圍爲 1970-01-01 00:00:01 UTC ~ 2038-01-19 03:14:07 UTC ,其中 UTC 是世界標準時間,存儲時會對當前時區進行轉換,檢索時再轉換回當前時區。
字符串類型用來存儲字符串數據,還能夠存儲好比圖片和聲音的二進制數據;
MySQL 支持兩種字符串類型:文本字符串和二進制字符串。
優化建議:
- 字符串的長度相差較大用VARCHAR;
- 字符串短,且全部值都接近一個長度用CHAR;
- BINARY和VARBINARY存儲的是二進制字符串,與字符集無關;
- BLOB系列存儲二進制字符串,與字符集無關;
- TEXT是一個更大的VARCHAR;
- BLOB和TEXT都不能有默認值。
一、char和varchar
- CHAR(M) 爲固定長度的字符串,在定義時指定字符串列長,當保存時在右側填充空格以達到指定的長度,M 表示列長度,取值範圍是 0~255 個字符,例如,CHAR(4) 定義了一個固定長度的字符串列,其包含的字符個數最大爲 4,當檢索到 CHAR 值時,尾部的空格將被刪掉;
- VARCHAR(M) 爲可變長度的字符串,M 表示最大列長度,取值範圍是 0~65535 ,VARCHAR 的最大實際長度由最長的行的大小和使用的字符集肯定,而其實際佔用的空間爲字符串的實際長度加一(一個字符串結束符);
例:
#新建一個表,字符類型分別爲char和varchar mysql> create table tab8(c char(4),vc varchar(4)); #插入數據,每條數據都是兩個字母加兩個空格 mysql> insert into tab8 values('ab ','ab ');
調用length函數,查看插入的數據長度:
調用緊湊函數,查看其實際數據:
能夠驗證了,若是是char類型的列,尾部的空格會被刪除掉,若是是varchar類型的列,空格不會被刪除掉,而是一個空格佔一個位。
須要注意的是,若是是char類型的列,假如定義數值的長度爲4,那麼就算插入的數值長度只有2,它仍是會佔4個長度的空間,而varchar則不會,由於前者屬於不可變長度的數值類型,然後者是可變的。
二、TEXT
TINYTEXT 最大長度爲 255 個字符;
TEXT 最大長度爲 65536 個字符;
MEDIUMTEXT 最大長度爲 16777215 個字符;
LONGTEXT 最大長度爲 4294967295 個字符。
三、ENUM
在基本的數據類型中,無外乎就是些數字和字符,可是某些事物是較難用數字和字符來準確地表示的。好比一週有七天,分別是Sunday、Monday、Tuesday、Wednesday、Thursday、Friday 和 Saturday。若是咱們用整數 0、一、二、三、四、五、6 來表示這七天,那麼多下來的那些整數該怎麼辦?並且這樣的設置很容易讓數據出錯,即取值超出範圍。咱們可否自創一個數據類型,而數據的取值範圍就是這七天呢?所以有了 ENUM 類型(Enumeration,枚舉),它容許用戶本身來定義一種數據類型,而且列出該數據類型的取值範圍。ENUM 是一個字符串對象,其值爲表建立時在列規定中枚舉(即列舉)的一列值,語法格式爲:字段名 ENUM ('值1', '值2', ..... '值n') 字段名指將要定義的字段,值 n 指枚舉列表中的第 n 個值,ENUM類型的字段在取值時,只能在指定的枚舉列表中取,並且一次只能取一個。若是建立的成員中有空格時,其尾部的空格將自動刪除。ENUM 值在內部用整數表示,每一個枚舉值均有一個索引值:列表值所容許的成員值從 1 開始編號,MySQL 存儲的就是這個索引編號。枚舉最多能夠有 65535 個元素。
例1:
#建立一個表,類型爲enum,默認值依次爲first、second、third mysql> create table tab9( -> enm enum('first','second','third') -> ); #插入數據 mysql> insert into tab9 values('first'),('third'),('second');
正常查看插入的數據以下:
經過下面的方法,查看出每一個值所對應的枚舉的值,以下:
例2:
#建立兩個列的表,第二列爲enum類型 mysql> create table tab10( -> soc int, -> level enum('excellent','good','bad') -> ); #插入數據測試,第二列的值,能夠直接寫枚舉中包含的值,也能夠經過所在位數來調用 mysql> insert into tab10 values(70,'good'),(90,1),(75,2),(50,3); #若是插入一個沒有定義過的枚舉值則會報錯,以下: mysql> insert into tab10 values(70,'best'),(90,1),(75,2),(50,4); ERROR 1265 (01000): Data truncated for column 'level' at row 1
查看最終表中的值(只有第一個語句插入的值):
四、SET
- SET 是一個字符串對象,能夠有零個或多個值,SET 列最多能夠有 64 個成員,其值爲表建立時規定的一列值,語法:SET('值1','值2',...... '值n');
- 與 ENUM 類型相同,SET 值在內部用整數表示,列表中每個值都有一個索引編號;
- 與 ENUM 類型不一樣的是,ENUM 類型的字段只能從定義的列值中選擇一個值插入,而 SET 類型的列可從定義的列值中選擇多個字符的聯合;
- 若是插入 SET 字段中列值有重複,則 MySQL 自動刪除重複的值,插入 SET 字段的值的順序並不重要,MySQL 會在存入數據庫時,按照定義的順序顯示。
例:
#建立一個表,數據類型爲set,而且自定義set字段的值 mysql> create table tab11(s set('a','b','c','d')); #只能插入自定義的set字段的值 mysql> insert into tab11 values('a'),('b,c,a'),('a,b,a'); #若是插入沒有定義的值,則會報錯 mysql> insert into tab11 values('d,g,s'); ERROR 1265 (01000): Data truncated for column 's' at row 1
查看錶中的順序,發現已經把值去重而且將順序排列好了,以下:
五、BIT
- BIT 數據類型用來保存位字段值,即以二進制的形式來保存數據,如保存數據 13,則實際保存的是 13 的二進制值,即 1101;
- BIT 是位字段類型,BIT(M) 中的 M 表示每一個值的位數,範圍爲 1~64 ,若是 M 被省略,則默認爲 1 ,若是爲 BIT(M) 列分配的值的長度小於 M 位,則在值得左邊用 0 填充;
- 若是須要位數至少爲 4 位的 BIT 類型,便可定義爲 BIT(4) ,則大於 1111 的數據是不能被插入的。
例:
#建立一個表,數據類型爲bit,寬度爲4,也就是說,最多隻能插入16如下的數據 mysql> create table tab12(b bit(4)); #插入正常的數據 mysql> insert into tab12 values(2),(9),(15); #插入大於15以上的數據就會報錯 mysql> insert into tab12 values(2),(9),(18); ERROR 1406 (22001): Data too long for column 'b' at row 3
查看錶中最終插入的數據(二進制類型的值,須要用如下語句查看,能夠看到,只有第一條sql語句成功插入了):
六、BINARY 和 VARBINARY
- BINARY 和 VARBINARY 類型相似於 CHAR 和 VARCHAR,不一樣的是它們包含二進制字節字符串;
- BINARY 類型的長度是固定的,指定長度以後,不足最大長度的,將在它們右邊填充 '\0' 以補齊指定長度;
- VARBINARY 類型的長度是可變的,指定長度以後,其長度能夠在 0 到最大值之間。
例:
#建立一個表,數據類型分別爲binary和varbinary mysql> create table tab13( -> b binary(3), -> vb varbinary(30) -> ); #插入數據測試 mysql> insert into tab13 values(5,5);
也能夠經過如下語句進行查看對比:
mysql> select b,vb='0\0\5',b='5\0\0',vb='5',vb='5\0\0' from tab13;
七、BLOB
- BLOB 用來存儲可變數量的二進制字符串,分爲 TINYBLOB 、BLOB 、MEDIUMBLOB 、LONGBLOB 四種類型;
- BLOB 存儲的是二進制字符串,TEXT 存儲的是文本字符串;
- BLOB 沒有字符集,而且排序和比較基於列值字節的數值;TEXT 有一個字符集,而且根據字符集對值進行排序和比較。