溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SQL數(shù)據(jù)類型詳解

發(fā)布時間:2020-07-12 02:41:43 來源:網(wǎng)絡 閱讀:570 作者:warrent 欄目:MySQL數(shù)據(jù)庫

一、數(shù)據(jù)類型簡介

  • 數(shù)據(jù)表由多列字段構成,每一個字段指定了不同的數(shù)據(jù)類型,指定了數(shù)據(jù)類型之后,也就決定了向字段插入的數(shù)據(jù)內(nèi)容;
  • 不同的數(shù)據(jù)類型也決定了 MySQL 在存儲它們的時候使用的方式,以及在使用它們的時候選擇什么運算符號進行運算;
  • 數(shù)值數(shù)據(jù)類型:TINYINT 、SMALINT 、MEDIUMINT 、INT 、BIGINT 、FLOAT 、DOUBLE 、DECIMAL;
  • 日期/時間類型:YEAR 、TIME 、DATE 、DATETIME 、TIMESTAMP;
  • 字符串類型:CHAR 、VARCHAR 、BINARY 、VARBINARY 、BLOB 、TEXT 、ENUM 、SET。

二、數(shù)值類型簡介

  • 數(shù)值類型主要用來存儲數(shù)字,不同的數(shù)值類型提供不同的取值范圍,可以存儲的值范圍越大,所需要的存儲空間也越大;
  • 數(shù)值類型分為:①整數(shù)類型 ②浮點數(shù)類型 ③定點數(shù)類型。

1、整數(shù)類型如下:

SQL數(shù)據(jù)類型詳解

示例:

mysql> create table t1(
    -> m tinyint,
    -> n smallint,
    -> x mediumint,
    -> y int,
    -> z bigint unsigned       <!--默認是有符號的列,unsigned表示無符號列-->
    -> );

查看表的詳細信息如下(在創(chuàng)建表的時候沒有指定其長度,但是每一列都有自己默認的長度):

SQL數(shù)據(jù)類型詳解

2、浮點數(shù)類型和定點數(shù)類型

  • MySQL 中使用浮點數(shù)和定點數(shù)來表示小數(shù),浮點數(shù)有兩種類型:單精度浮點數(shù)(FLOAT)和雙精度浮點數(shù)(DOUBLE),定點數(shù)只有 DECIMAL;
  • 浮點數(shù)和定點數(shù)都可以用 (M,N) 來表示,其中 M 是精度,表示總共的位數(shù),N 是標度,表示小數(shù)的位數(shù),如:3.145,用M/N來表示就是4,3;
  • DECIMAL 實際是以字符串形式存放的,在對精度要求比較高的時候(如貨幣、科學數(shù)據(jù)等)使用 DECIMAL 類型會比較好;
  • 浮點數(shù)相對于定點數(shù)的優(yōu)點是在長度一定的情況下,浮點數(shù)能夠表示更大的數(shù)據(jù)范圍,它的缺點是會引起精度問題。

SQL數(shù)據(jù)類型詳解

優(yōu)化建議:

  • 建議使用 TINYINT 代替 ENUM、BITENUM、SET;
  • 避免使用整數(shù)的顯示寬度,也就是說,不要用INT(10)類似的方法指定字段顯示寬度,直接用INT;
  • DECIMAL最適合保存準確度要求高,而且用于計算的數(shù)據(jù),比如價格。但是在使用DECIMAL類型的時候,注意長度設置;
    ? 建議使用整型來運算和存儲實數(shù),方法是,實數(shù)乘以相應的倍數(shù)后再操作;
    ?
    整數(shù)通常是最佳的數(shù)據(jù)類型,因為它速度快,并且能使用AUTO_INCREMENT。
示例1:
<!--新建一個表,值的長度都為5,小數(shù)點后都是兩位-->
mysql> create table t2(
    -> x float(5,2),
    -> y double(5,2),
    -> z decimal(5,2)
    -> );
<!--插入正常符合要求的數(shù)據(jù),可以正常插入-->
mysql> insert into t2 values(123.45,123.45,123.45);
Query OK, 1 row affected (0.00 sec)
<!--插入一些不符合規(guī)定的數(shù)據(jù),會返回1個warning信息-->
mysql> insert into t2 values(123.456,123.456,123.456);
Query OK, 1 row affected, 1 warning (0.01 sec)

mysql> show warnings;     <!--查看warning信息,提示z列有截斷的數(shù)據(jù)-->
+-------+------+----------------------------------------+
| Level | Code | Message                                |
+-------+------+----------------------------------------+
| Note  | 1265 | Data truncated for column 'z' at row 1 |
+-------+------+----------------------------------------+
1 row in set (0.00 sec)

上述示例插入的數(shù)據(jù),實際顯示如下:

SQL數(shù)據(jù)類型詳解

通過實際插入的數(shù)據(jù)不難發(fā)現(xiàn),如果插入不符合列規(guī)定的數(shù)據(jù),那么最終會以四舍五入的方法處理。

需要注意的是,在上面的數(shù)值類型中,它只允許在小數(shù)點后面多一位,而不允許在小數(shù)點之前多一位,如插入1234.5或1234.35就會報錯。

示例2:
mysql> create table t3(      <!--創(chuàng)建多個列,長度都為10,小數(shù)點后面有兩位-->
    -> x float(10,2),
    -> y double(10,2),
    -> z decimal(10,2)
    -> );
mysql> insert into t3 values(12345678.123,12345678.123,12345678.123);
Query OK, 1 row affected, 1 warning (0.00 sec)
<!--同樣會返回warning信息,提示z列有截斷數(shù)據(jù),我就不看了-->

最終插入到表中的數(shù)據(jù)如下:

SQL數(shù)據(jù)類型詳解
在上面的表中,x列為float數(shù)值類型,其他兩列的數(shù)值還是基于四舍五入的方法進行插入的,但是float數(shù)值類型的x列,插入的數(shù)據(jù)和實際輸入的數(shù)據(jù)就有些出入了,并且會隨著小數(shù)點位數(shù)的增加,這個浮動范圍會更大。

3、日期和時間類型

表示時間值的日期和時間類型為DATETIME、DATE、TIMESTAMP、TIME和YEAR。

每個時間類型有一個有效值范圍和一個"零"值,當指定不合法的MySQL不能表示的值時使用"零"值。

TIMESTAMP類型有專有的自動更新特性。

SQL數(shù)據(jù)類型詳解

優(yōu)化建議:

  • MySQL能存儲的最小時間粒度為秒。
  • 建議用DATE數(shù)據(jù)類型來保存日期。MySQL中默認的日期格式是yyyy-mm-dd;
  • 用MySQL的內(nèi)建類型DATE、TIME、DATETIME來存儲時間,而不是使用字符串;
  • 當數(shù)據(jù)格式為TIMESTAMP和DATETIME時,可以用CURRENT_TIMESTAMP作為默認(MySQL5.6以后),?MySQL會自動返回記錄插入的確切時間;
  • TIMESTAMP是UTC時間戳,與時區(qū)相關;
  • DATETIME的存儲格式是一個YYYYMMDD HH:MM:SS的整數(shù),與時區(qū)無關;
  • 除非有特殊需求,否則建議使用TIMESTAMP,它比DATETIME更節(jié)約空間。
1)YEAR
  • 格式1:以4位字符串格式表示的 YEAR ,范圍為 '1901' ~ '2155';
  • 格式2:以4位數(shù)字格式表示的 YEAR ,范圍為 1901 ~ 2155;
  • 格式3:以2位字符串格式表示的 YEAR ,范圍為 '00' ~ '99' ,其中,'00' ~ '69' 被轉(zhuǎn)換為 2000 ~ 2069 ,'70' ~ '99' 被轉(zhuǎn)換為 1970 ~ 1999;
  • 格式4:以2位數(shù)字格式表示的 YEAR ,范圍為 1 ~ 99 ,其中,1 ~ 69 被轉(zhuǎn)換為 2001 ~ 2069 ,70 ~ 99 被轉(zhuǎn)換為 1970 ~ 1999。

示例:

mysql> create table t4(y year);    <!--新建一個表,只有一列,數(shù)值類型為year-->
 <!--依次插入四位的字符、數(shù)值;兩位的字符、數(shù)值-->
mysql> insert into t4 values('2000'),(2000),('94'),(94);  

插入的數(shù)據(jù)如下所示:

SQL數(shù)據(jù)類型詳解

mysql> delete from t4;         <!--刪除原有數(shù)據(jù)-->
mysql> insert into t4 values('0'),(0),('00'),(00);       <!--插入一些不符合列規(guī)定的數(shù)值-->

新插入的數(shù)據(jù)如下:

SQL數(shù)據(jù)類型詳解

結論:當插入的年份不合法時,會用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 之間的值,在插入數(shù)據(jù)庫的時候 D 會被轉(zhuǎn)換成小時,如 '2 10:10' 在數(shù)據(jù)庫中表示為 58:10:00 ,即 2x24+10 = 58

示例:

mysql> create table t5(d time);
mysql> insert into t5 values('12:12:12'),(121212),(3),('3 10:2'),(14),('08:08');

插入的數(shù)據(jù)如下:

SQL數(shù)據(jù)類型詳解

上述插入的數(shù)據(jù),基本可以對應SQL語句來看出來其規(guī)律,唯一需要解釋的,應該就是“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' 被轉(zhuǎn)換為 2000 ~ 2069 ,'70' ~ '99' 被轉(zhuǎn)換為 1970 ~ 1999;
  • 格式3:YY-MM-DD 或 YYMMDD ,數(shù)字格式表示的日期,其中 YY 范圍為 00 ~ 99 ,其中,00 ~ 69 被轉(zhuǎn)換為 2000 ~ 2069 ,70 ~ 99 被轉(zhuǎn)換為 1970 ~ 1999。

示例:

mysql> create table t6(d date);     <!--創(chuàng)建一個表,列的數(shù)據(jù)類型為date-->
mysql> insert into t6 values('1999-09-09'),(990906),(19990909);
<!--插入不同格式的日期-->

查看插入的結果如下:
SQL數(shù)據(jù)類型詳解

其實,對于date這一種數(shù)值類型,對于其格式并沒有嚴格的要求,如2019-12-12這樣的數(shù)值可以插入成功,2000!10:10這樣的數(shù)值同樣可以插入成功,如下:

SQL數(shù)據(jù)類型詳解

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' 被轉(zhuǎn)換為 2000 ~ 2069 ,'70' ~ '99' 被轉(zhuǎn)換為 1970 ~ 1999;
  • 格式3:YYYYMMDDHHMMSS 或 YYMMDDHHMMSS ,數(shù)字格式,取值范圍同上。

示例:

mysql> insert into t7 values('1996-09-19 12:24:56');

插入到表中的數(shù)據(jù)如下:
SQL數(shù)據(jù)類型詳解

5)TIMESTAMP
  • TIMESTAMP 類型的格式為 YYYY-MM-DD HH:MM:SS,顯示寬度固定在19個字符;
  • TIMESTAMP 與 DATETIME 的區(qū)別在于,TIMESTAMP 的取值范圍小于 DATETIME 的取值范圍;
  • TIMESTAMP 的取值范圍為 1970-01-01 00:00:01 UTC ~ 2038-01-19 03:14:07 UTC ,其中 UTC 是世界標準時間,存儲時會對當前時區(qū)進行轉(zhuǎn)換,檢索時再轉(zhuǎn)換回當前時區(qū)。

三、字符串數(shù)據(jù)類型

  • 字符串類型用來存儲字符串數(shù)據(jù),還可以存儲比如圖片和聲音的二進制數(shù)據(jù);
  • MySQL 支持兩種字符串類型:文本字符串和二進制字符串。

SQL數(shù)據(jù)類型詳解

SQL數(shù)據(jù)類型詳解

優(yōu)化建議:

  • 字符串的長度相差較大用VARCHAR;
  • 字符串短,且所有值都接近一個長度用CHAR;
  • BINARY和VARBINARY存儲的是二進制字符串,與字符集無關;
  • BLOB系列存儲二進制字符串,與字符集無關;
  • TEXT是一個更大的VARCHAR;
  • BLOB和TEXT都不能有默認值。

1、char和varchar

  • CHAR(M) 為固定長度的字符串,在定義時指定字符串列長,當保存時在右側填充空格以達到指定的長度,M 表示列長度,取值范圍是 0~255 個字符,例如,CHAR(4) 定義了一個固定長度的字符串列,其包含的字符個數(shù)最大為 4,當檢索到 CHAR 值時,尾部的空格將被刪掉;
  • VARCHAR(M) 為可變長度的字符串,M 表示最大列長度,取值范圍是 0~65535 ,VARCHAR 的最大實際長度由最長的行的大小和使用的字符集確定,而其實際占用的空間為字符串的實際長度加一(一個字符串結束符);

示例:

<!--新建一個表,字符類型分別為char和varchar-->
mysql> create table t9(c char(4),vc varchar(4));
Query OK, 0 rows affected (0.01 sec)
<!--插入數(shù)據(jù),每條數(shù)據(jù)都是兩個字母加兩個空格-->
mysql> insert into t9 values('ab  ','ab  ');

調(diào)用length函數(shù),查看插入的數(shù)據(jù)長度:

SQL數(shù)據(jù)類型詳解

調(diào)用緊湊函數(shù),查看其實際數(shù)據(jù):

SQL數(shù)據(jù)類型詳解

可以驗證了,如果是char類型的列,尾部的空格會被刪除掉,如果是varchar類型的列,空格不會被刪除掉,而是一個空格占一個位。

需要注意的是,如果是char類型的列,假如定義數(shù)值的長度為4,那么就算插入的數(shù)值長度只有2,它還是會占4個長度的空間,而varchar則不會,因為前者屬于不可變長度的數(shù)值類型,而后者是可變的。

2、TEXT

  • TINYTEXT 最大長度為 255 個字符;
  • TEXT 最大長度為 65536 個字符;
  • MEDIUMTEXT 最大長度為 16777215 個字符;
  • LONGTEXT 最大長度為 4294967295 個字符。

3、ENUM

在基本的數(shù)據(jù)類型中,無外乎就是些數(shù)字和字符,但是某些事物是較難用數(shù)字和字符來準確地表示的。比如一周有七天,分別是Sunday、Monday、Tuesday、Wednesday、Thursday、Friday 和 Saturday。如果我們用整數(shù) 0、1、2、3、4、5、6 來表示這七天,那么多下來的那些整數(shù)該怎么辦?而且這樣的設置很容易讓數(shù)據(jù)出錯,即取值超出范圍。我們能否自創(chuàng)一個數(shù)據(jù)類型,而數(shù)據(jù)的取值范圍就是這七天呢?因此有了 ENUM 類型(Enumeration,枚舉),它允許用戶自己來定義一種數(shù)據(jù)類型,并且列出該數(shù)據(jù)類型的取值范圍。ENUM 是一個字符串對象,其值為表創(chuàng)建時在列規(guī)定中枚舉(即列舉)的一列值,語法格式為:字段名 ENUM ('值1', '值2', ..... '值n') 字段名指將要定義的字段,值 n 指枚舉列表中的第 n 個值,ENUM類型的字段在取值時,只能在指定的枚舉列表中取,而且一次只能取一個。如果創(chuàng)建的成員中有空格時,其尾部的空格將自動刪除。ENUM 值在內(nèi)部用整數(shù)表示,每個枚舉值均有一個索引值:列表值所允許的成員值從 1 開始編號,MySQL 存儲的就是這個索引編號。枚舉最多可以有 65535 個元素。

示例1:

<!--創(chuàng)建一個表,類型為enum,默認值依次為first、second、third-->
mysql> create table t10(
    -> enm enum('first','second','third')
    -> );
<!--插入數(shù)據(jù)-->
mysql> insert into t10 values('first'),('third'),('second');

正常查看插入的數(shù)據(jù)如下:

SQL數(shù)據(jù)類型詳解

通過下面的方法,查看出每個值所對應的枚舉的值,如下:

SQL數(shù)據(jù)類型詳解

示例2:

<!--創(chuàng)建兩個列的表,第二列為enum類型-->
mysql> create table t11(
    -> soc int,
    -> level enum('excellent','good','bad')
    -> );
<!--插入數(shù)據(jù)測試,第二列的值,可以直接寫枚舉中包含的值,也可以通過所在位數(shù)來調(diào)用-->
mysql> insert into t11 values(70,'good'),(90,1),(75,2),(50,3);
<!--如果插入一個沒有定義過的枚舉值則會報錯,如下-->
mysql> insert into t11 values(70,'best'),(90,1),(75,2)),(50,4);
ERROR 1265 (01000): Data truncated for column 'level' at row 1

查看最終表中的值(只有第一個語句插入的值):

SQL數(shù)據(jù)類型詳解

4、SET

  • SET 是一個字符串對象,可以有零個或多個值,SET 列最多可以有 64 個成員,其值為表創(chuàng)建時規(guī)定的一列值,語法:SET('值1','值2',...... '值n');
  • 與 ENUM 類型相同,SET 值在內(nèi)部用整數(shù)表示,列表中每一個值都有一個索引編號;
  • 與 ENUM 類型不同的是,ENUM 類型的字段只能從定義的列值中選擇一個值插入,而 SET 類型的列可從定義的列值中選擇多個字符的聯(lián)合;
  • 如果插入 SET 字段中列值有重復,則 MySQL 自動刪除重復的值,插入 SET 字段的值的順序并不重要,MySQL 會在存入數(shù)據(jù)庫時,按照定義的順序顯示。

示例:


<!--創(chuàng)建一個表,數(shù)據(jù)類型為set,并且自定義set字段的值-->
mysql> create table t12(s set('a','b','c','d'));
<!--只能插入自定義的set字段的值-->
mysql> insert into t12 values('a'),('b,c,a'),('a,b,a');
<!--如果插入沒有定義的值,則會報錯-->
mysql> insert into t12 values('d,g,s,');
ERROR 1265 (01000): Data truncated for column 's' at row 1

查看表中的順序,發(fā)現(xiàn)已經(jīng)把值去重并且將順序排列好了,如下:
SQL數(shù)據(jù)類型詳解

5、BIT

  • BIT 數(shù)據(jù)類型用來保存位字段值,即以二進制的形式來保存數(shù)據(jù),如保存數(shù)據(jù) 13,則實際保存的是 13 的二進制值,即 1101;
  • BIT 是位字段類型,BIT(M) 中的 M 表示每個值的位數(shù),范圍為 1~64 ,如果 M 被省略,則默認為 1 ,如果為 BIT(M) 列分配的值的長度小于 M 位,則在值得左邊用 0 填充;
  • 如果需要位數(shù)至少為 4 位的 BIT 類型,即可定義為 BIT(4) ,則大于 1111 的數(shù)據(jù)是不能被插入的。

示例:

<!--創(chuàng)建一個表,數(shù)據(jù)類型為bit,寬度為4,也就是說,最多只能插入16以下的數(shù)據(jù)-->
mysql> create table t13(b bit(4));
<!--插入正常的數(shù)據(jù)-->
mysql> insert into t13 values(2),(9),(15);
<!--插入大于15以上的數(shù)據(jù)就會報錯-->
mysql> insert into t13 values(2),(9),(18);
ERROR 1406 (22001): Data too long for column 'b' at row 3

查看表中最終插入的數(shù)據(jù)(二進制類型的值,需要用以下語句查看,可以看到,只有第一條sql語句成功插入了):

SQL數(shù)據(jù)類型詳解

6、BINARY 和 VARBINARY

  • BINARY 和 VARBINARY 類型類似于 CHAR 和 VARCHAR,不同的是它們包含二進制字節(jié)字符串;
  • BINARY 類型的長度是固定的,指定長度之后,不足最大長度的,將在它們右邊填充 '\0' 以補齊指定長度;
  • VARBINARY 類型的長度是可變的,指定長度之后,其長度可以在 0 到最大值之間。

示例:

<!--創(chuàng)建一個表,數(shù)據(jù)類型分別為binary和varbinary-->
mysql> create table t14(
    -> b binary(3),
    -> vb varbinary(30)
    -> );
<!--插入數(shù)據(jù)測試-->
mysql> insert into t14 values(5,5);

查看插入的數(shù)據(jù)長度:

SQL數(shù)據(jù)類型詳解

也可以通過以下語句進行查看對比:
SQL數(shù)據(jù)類型詳解

7、BLOB

  • BLOB 用來存儲可變數(shù)量的二進制字符串,分為 TINYBLOB 、BLOB 、MEDIUMBLOB 、LONGBLOB 四種類型;
  • BLOB 存儲的是二進制字符串,TEXT 存儲的是文本字符串;
  • BLOB 沒有字符集,并且排序和比較基于列值字節(jié)的數(shù)值;TEXT 有一個字符集,并且根據(jù)字符集對值進行排序和比較。

SQL數(shù)據(jù)類型詳解

———————— 本文至此結束,感謝閱讀 ————————

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI