MySQL數據類型詳解

在上一篇博客中,我們簡單的瞭解了MySQL中的常用數據類型以及約束條件,本篇博客我們來對常用的數據類型做一個詳細的介紹

這裏做個簡單的回顧:

MySQL數據類型

MySQL支持多種類型的SQL數據類型:數值,日期和時間類型,字符串(字符和字節)類型,空間類型和 JSON數據類型等
數據類型描述使用以下約定:

  • M表示整數類型的最大顯示寬度。M表示整數類型的最大顯示寬度。對於浮點和定點類型, M是可以存儲的總位數(精度)。對於字符串類型, M是最大長度。允許的最大值M取決於數據類型。
  • D適用於浮點和定點類型,並指示小數點後面的位數。最大可能值爲30,但不應大於 M-2。
  • [ ]表示類型定義的可選部分。

在MySQL中常用數據類型主要分爲以下幾類
1. 數值類型
2. 字符串類型
3. 日期時間類型


約束條件

約束條件就是在給字段加一些約束,使該字段存儲的值更加符合我們的預期。

常用約束條件有以下這些

  • UNSIGNED :無符號,值從0開始,無負數
  • ZEROFILL:零填充,當數據的顯示長度不夠的時候可以使用前補0的效果填充至指定長度,字段會自動添加UNSIGNED
  • NOT NULL:非空約束,表示該字段的值不能爲空
  • DEFAULT:表示如果插入數據時沒有給該字段賦值,那麼就使用默認值
  • PRIMARY KEY:主鍵約束,表示唯一標識,不能爲空,且一個表只能有一個主鍵。一般都是用來約束id
  • AUTO_INCREMENT:自增長,只能用於數值列,而且配合索引使用,默認起始值從1開始,每次增長1
  • UNIQUE KEY:唯一值,表示該字段下的值不能重複,null除外。比如身份證號是一人一號的,一般都會用這個進行約束
  • FOREIGN KEY:外鍵約束,目的是爲了保證數據的完成性和唯一性,以及實現一對一或一對多關係

數值類型

數值類型包括整數型浮點型定點型

整數型(精確值)

  • TINYINT[(M)] [UNSIGNED] [ZEROFILL] 範圍非常小的整數,有符號的範圍是 -128到127,無符號的範圍是0到 255
  • SMALLINT[(M)] [UNSIGNED] [ZEROFILL] 範圍較小的整數,有符號的範圍是 -32768到32767,無符號的範圍是0到 65535
  • MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL] 中等大小的整數,有符號的範圍是 -8388608到8388607,無符號的範圍是0到 16777215。
  • INT[(M)] [UNSIGNED] [ZEROFILL] 正常大小的整數,有符號的範圍是 -2147483648到 2147483647。無符號的範圍是 0到4294967295。
  • BIGINT[(M)] [UNSIGNED] [ZEROFILL] 大整數,有符號的範圍是 -9223372036854775808到 9223372036854775807,無符號的範圍是0到 18446744073709551615。

這裏寫圖片描述

上面出現了兩個詞,有符號和無符號。
我們來看看有符號和無符號(UNSIGNED)是啥玩意

在計算機中,可以區分正負的類型,稱爲有符號類型。無正負的類型,稱爲無符號類型。
簡單的理解爲就是
有符號值可以表示負數,0以及正數
無符號值只能爲0或正數

關於有符號和無符號詳解可以看這篇文章或者自己百度百科。

這裏我們就不關心原理了,我們只需要知道有符號數可以表示負數,無符號數只能爲非負數即可,如果不手動指定UNSIGNED,那麼默認就是有符號的

下面我們用一下整數型數據
首先創建一個表

CREATE TABLE int_db(
a TINYINT,
b SMALLINT,
c MIDDLEINT,
d INT,
e BIGINT
);

查看錶結構

這裏寫圖片描述

我們來看看type這一列,可以看到,每個字段類型後面都有一個括號,括號裏面的有個數值,這個數值實際上就是字段的顯示寬度,也就是M的值,M表示整數類型的最大顯示寬度。最大顯示寬度爲255.顯示寬度與類型可包含的值範圍無關

我們在創建表的時候並沒有指定字段類型的顯示寬度,那麼,默認的顯示寬度則是該字段類型最大的顯示寬度

例如字段a的顯示寬度爲4,是因爲TINYINT有符號值的範圍是-128到127,
-128的長度爲4(負號、1、2、8共四位),所以默認的顯示寬度最大爲4,其他的以此類推

下面我們再新建一個表,將字段a的修改爲無符號類型的。再看看a字段的默認顯示寬度
這裏寫圖片描述

可以看到,默認顯寬度就變成3了,因爲無符號的TINYINT的值範圍爲0-255,沒有負號,所以最多是3位。

ZEROFILL
下面我們來試試ZEROFILL約束,前面的博客中我們知道。使用該約束後當數據的長度比我們指定的顯示寬度小的時候會使用前補0的效果填充至指定長度,字段會自動添加UNSIGNED

下面我們新建個表試一下,這次我們來指定一下顯示寬度

CREATE TABLE int_db2(
a TINYINT(8) ZEROFILL,
b TINYINT(5) UNSIGNED);

然後插入一條記錄:

INSERT int_db2() VALUES(12,12);

這裏寫圖片描述
可以看到,12變成了00000012,自動在前面補了0,這是因爲指定的顯示寬度是8,但是12只有兩位,所以在前面補0,使長度爲8。這就是ZEROFILL的效果

浮點型

  • FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]
    一個小的(單精度)浮點數。允許值是-3.402823466E+38 到-1.175494351E-38, 0以及1.175494351E-38 到3.402823466E+38,M是總位數,D是小數點後面的位數。
  • DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]
    正常大小(雙精度)浮點數。允許值是 -1.7976931348623157E+308到-2.2250738585072014E-308,0以及 2.2250738585072014E-308到 1.7976931348623157E+308。M是總位數,D是小數點後面的位數

下面我們來用一下浮點型
創建表

CREATE TABLE float_db(
a FLOAT(3,2),
b DOUBLE(5,3)
)

我們指定a字段爲FLOAT類型,總長度爲3,小數點後兩位爲2,b字段總長度爲5,小數點後兩位長度爲3

這裏寫圖片描述

插入數據

INSERT float_db VALUES(1.111,2.113);

這裏寫圖片描述

可以看到,我們給a字段的值是1.111,但是隻存進去了1.11
浮點數存在精度丟失的問題,如果涉及到小數運算,儘量不要用浮點型

定點型

  • DECIMAL[(M[,D])] [UNSIGNED] [ZEROFILL]
    常用於存儲精確的小數,M是總位數,D是小數點後的位數。小數點和(負數) -符號不計入 M。如果 D爲0,則值沒有小數點或小數部分。最大位數(M)爲 65. 最大支持小數(D)爲30.如果D省略,則默認值爲0.如果M省略,則默認值爲10。M的範圍是1到65。D範圍爲0到30,且不得大於M。

我們來用一下DECIMAL類型

首先創建表,先不指定M和D

CREATE TABLE decimal_db(a DECIMAL);

這裏寫圖片描述

可以看到,默認的總長度(M)爲10,小數點位數(D)默認爲0.

插入一條數據

INSERT decimal_db VALUES(30.556)

這裏寫圖片描述

可以看到,存進去的數值被四捨五入階段了,也就是說,DECIMAL也在存儲時存在精度丟失的問題

超出範圍和溢出處理

當MySQL將值存儲在超出列數據類型允許範圍的數值列中時,結果取決於當時生效的SQL模式:
如果啓用了嚴格的SQL模式,則MySQL會根據SQL標準拒絕帶有錯誤的超出範圍的值,並且插入失敗。
如果未啓用限制模式,MySQL會將值截斷到列數據類型範圍的相應端點,並存儲結果值,併產生一個警告

在我們的配置文件中可以看到SQL模式的配置,關於SQL模式詳情請看SQL模式官方文檔

這裏寫圖片描述


字符串類型

常用的字符串類型有如下

  • CHAR[(M)] 一個固定長度的字符串,在存儲時始終用空格填充指定長度。 M表示以字符爲單位的列長度。M的範圍爲0到255.如果M省略,則長度爲1,存儲時佔用M個字節
  • VARCHAR(M)可變長度的字符串,M 表示字符的最大列長度,M的範圍是0到65,535,存儲時佔用L+1(L<=M,L爲實際字符的長度)個字節
  • TINYTEXT[(M)] 不能有默認值,佔用L+1個字節,L<2^8
  • TEXT[(M)] 不能有默認值,佔用L+2個字節,L<2^16
  • MEDIUMTEXT[(M)] 不能有默認值,佔用L+3個字節,L<2^24
  • LONGTEXT[(M)] 不能有默認值,佔用L+4個字節,L<2^32
  • ENUM('value1','value2',...) ENUM是一個字符串對象,其值從允許值列表中選擇,它只能有一個值,從值列表中選擇,最多可包含65,535個不同的元素
  • SET('value1','value2',...) 字符串對象,該對象可以有零個或多個值,最多可包含64個不同的成員

    CHAR和VARCHAR

    創建表

CREATE TABLE str_db(
a CHAR(4),
b VARCHAR(4));

插入數據

INSERT str_db() VALUES("","");
INSERT str_db() VALUES("ab","ab");
INSERT str_db() VALUES("abcd","abcd");
INSERT str_db() VALUES("abcdefg","abcdefg");//在嚴格模式下,改條數據會插入失敗,非嚴格模式則會對數據進行截取

這裏寫圖片描述

我們看到查詢的結果是一樣的,但實際上他們存儲時佔用的長度是不一樣的。
CHAR類型不管存儲的值的長度是多少,都會佔用M個字節,而VARCHAR則佔用實際長度+1個字節。

這裏寫圖片描述

但是CHAR的查詢效果要高於VARCHAR,所以說,如果字段的長度能夠確定的話,比如手機號,身份證號之類的字段,可以用CHAR類型,像地址,郵箱之類的就用VARCHAR

TEXT系列

TEXT系列的存儲範圍比VARCHAR要大,當VARCHAR不滿足時可以用TEXT系列中的類型。需要注意的是TEXT系列類型的字段不能有默認值,在檢索的時候不存在大小寫轉換,沒有CHAR和VARCHAR的效率高

這裏寫圖片描述

ENUM

枚舉類型
創建表

CREATE TABLE enum_db(gender ENUM("男","女"));

這裏寫圖片描述

插入數據

INSERT enum_db() VALUES("男");
INSERT enum_db() VALUES(1); 也可以使用編號插入值,等同於"男",序號從1開始
INSERT enum_db() VALUES("女");
INSERT enum_db() VALUES(2);等同於"女"

這裏寫圖片描述

下面我們插入一條不是枚舉集合中的數據試一下

這裏寫圖片描述

可以看到是插入失敗的

SET

在ENUM中我們只能從允許值列表中給字段插入一個值,而在SET類型中可以給字段插入多個值

創建表


CREATE TABLE set_db(
a SET('1','2','3','4','5')

)

這裏寫圖片描述

插入數據


INSERT set_db() VALUES('1')
INSERT set_db() VALUES('1,2,3')

這裏寫圖片描述


日期時間類型

  • TIME 範圍是’-838:59:59.000000’ 到’838:59:59.000000’
  • DATE 支持的範圍是 ‘1000-01-01’到 ‘9999-12-31’
  • DATETIME 日期和時間組合。支持的範圍是 ‘1000-01-01 00:00:00.000000’到 ‘9999-12-31 23:59:59.999999’。
  • TIMESTAMP 時間戳。範圍是’1970-01-01 00:00:01.000000’UTC到’2038-01-19 03:14:07.999999’UTC。
  • YEAR 範圍是 1901到2155

TIME

我們可以看到TIME的存儲範圍是’-838:59:59’到 ‘838:59:59’,因爲TIME類型不僅可以用於表示一天中的時間(,還可以用於表示兩個事件之間的經過時間或時間間隔

TIME的完整的顯示爲 D HH:MM:SS
D:表示天數,當指定該值時,存儲時小時會先乘以該值
HH:表示小時
MM:表示分鐘
SS:表示秒

創建表:

CREATE TABLE time_db(
a TIME
)

插入值:


INSERT time_db() VALUES('22:14:16');
--   -2表示間隔了2兩天
INSERT time_db() VALUES('-2 22:14:16');
-- 有冒號從小時開始
INSERT time_db() VALUES('14:16');
-- 沒有冒號且沒有天數則數據從秒開始
INSERT time_db() VALUES('30');
-- 有天數也從小時開始
INSERT time_db() VALUES('3 10');
-- 直接使用數字代替也可以
INSERT time_db() VALUES(253621);


![這裏寫圖片描述](https://img-blog.csdn.net/20180813155752176?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3l1emhpcWlhbmdfMTk5Mw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)



**DATE**

創建表

CREATE TABLE date_db(
a DATE)


插入數據

INSERT date_db() VALUES(20180813);
INSERT date_db() VALUES(“2018-06-1”);
INSERT date_db() VALUES(“2018-4-1”);
INSERT date_db() VALUES(“2018-04-07”);

這裏寫圖片描述

DATETIME

創建表

CREATE TABLE datetime_db(
a DATETIME
)

插入數據

INSERT datetime_db() VALUES(20180102235432);
INSERT datetime_db() VALUES("2015-04-21 21:14:32");
INSERT datetime_db() VALUES("2015-04-23");

這裏寫圖片描述

TIMESTAMP

TIMESTAMP和DATETIME使用上差不多,但是範圍相對較小。

創建表

CREATE TABLE timestamp_db(
a TIMESTAMP
)

插入數據

INSERT timestamp_db() VALUES(20020121);
INSERT timestamp_db() VALUES(20020121142554);
INSERT timestamp_db() VALUES("2015-12-16 21:14:15");
INSERT timestamp_db() VALUES("2015-12-17");
INSERT timestamp_db() VALUES(NULL);
INSERT timestamp_db() VALUES(CURRENT_TIMESTAMP);
INSERT timestamp_db() VALUES();

這裏寫圖片描述

YEAR

創建表

CREATE TABLE year_db(
a YEAR
)

插入數據

INSERT year_db() VALUES("1993");
INSERT year_db() VALUES(1993);

這裏寫圖片描述


MySQL中的常用數據類型大概就這些,我們在建表的時候要選擇合適的數據類型定義字段。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章