1. 程式人生 > 其它 >MySQL 5.7資料型別

MySQL 5.7資料型別

——《深入淺出MySQL(第二版)》筆記

數值型別

MySQL支援所有標準SQL中的型別,其中包括嚴格數值型別(INTEGERSMALLINTDECIMALNUMBERIC),以及近似數值型別(FLOATFEALDOUBLE PRECISION),並且在此基礎上做了擴充套件。擴充套件增加了TINYINTMEDIUMINTBIGINT三種長度不同的整型型別,並增加了BIT型別,用來存放位資料。

整數型別 位元組 最小值 最大值
TINYINT 1 有符號 -128;無符號 0 有符號 127;無符號 255
SMALLINT 2 有符號 -2^16;無符號 0 有符號 2^16-1;無符號 2^17-1
MEDIUMINT 3 有符號 -2^24;無符號 0 有符號 2^24-1;無符號 2^25-1
INT\INTEGER 4 有符號 -2^32;無符號 0 有符號 2^32-1;無符號 2^33-1
BIGINT 8 有符號 -2^64;無符號 0 有符號 2^64-1;無符號 2^65-1

浮點型別 位元組 最大值 最小值
FLOAT 4
DOUBLE 8

定點數型別 位元組 描述
DEC(M,D)\DECIMAL(M,D) M+2 最大值取值範圍與DOUBLE相同,給定DECIMAL的有效取值範圍由M和D決定

位型別 位元組 最小值 最大值
BIT(M) 1~8 BIT(1) BIT(8)

整數型別

對於整數型別,MySQL支援在型別名稱後面使用(n)的方式指定顯示寬度,例如int(5)表示當數值寬度小於5位時,在數字前面填滿寬度,如果不顯示指定寬度則預設為int(11)。一般配合zerofill使用,就是用'0'填充。

示例:

--建立表t1,有id1和id2兩個欄位,指定數值寬度分別為int和int(5)
mysql> create table t1 (id1 int,id2 int(5));
mysql> desc t1;
--在id1和id2中都插入數值1
mysql> insert into t1 values (1,1);
mysql> select * from t1;
--分別給id1和id2欄位增加zerofill引數
mysql> alter table t1 modify id1 int zerofill;
mysql> alter table t1 modify id2 int(5) zerofill;

設定了寬度限制後,如果插入大於寬度限制的值,不會對插入的資料有任何影響,還是按照型別的書記精度進行儲存。這時,寬度格式實際已經沒有意義,左邊不會再填充任何的“0”字元。

--向表t1的id1中插入1,id2中插入12345678
mysql> insert into t1 values(1,12345678);
mysql> select * from t1;

所有的整數型別都有一個可選屬性UNSIGNED(無符號),如果需要在欄位裡面儲存非負數或者需要較大的上限值,可以用此選項。而當一個列指定為zerofill,則MySQL自動為該列新增UNSIGNED屬性。

另外,整數型別還有一個獨有的AUTO_INCREMENT屬性,表示該列的值是自增型。AUTO_INCREMENT值一般從1開始,每行增加1。在插入NULL到一個AUTO_INCREMENT列時,MySQL插入一個比該列當前最大值大1的值。一個表中最多隻能有一個列是AUTO_INCREMENT的。

對於任何想要使用AUTO_INCREMENT的列,應該定義為NOT NULL,並定義為UNIQUE。

浮點型別

對於小數的表示,MySQL分為浮點數和定點數兩種。浮點數包括float(單精度)和double(雙精度),而定點數只有decimal一種。定點數在MySQL內部以字串形式存放,比浮點數更精確,適合用來表示貨幣等精度高的資料。

浮點數和定點數都可以用型別名稱後加"(M,D)"的方式來進行表示,"(M,D)"表示該值一共顯示M位,小數有D位。MySQL儲存浮點值時對超出位採用的是四捨五入的方式。因此如果在float(5,3)中插入123.006,則儲存的值為123.01。float和double在不指定精度時,預設按照實際硬體和作業系統來決定;而decimal不指定時,預設整數位為10,小數位為0。

示例:

--建立表tf,分別將id1,id2,id3欄位設定為float(5,2),double(5,2),decimal(5,2)
mysql> create table tf( id1 float(5,2),id2 double(5,2),id3 decimal(5,2));
--向表中三個欄位分別插入資料1.23
mysql> insert into tf values(1.23,1.23,1.23);
--向表中分別插入資料1234.005
mysql> insert into tf values(1234.005,1234.005,1234.005);
--向表中分別插入資料123.005
mysql> insert into tf values(123.005,123.005,123.005);
--向表中分別插入資料123.006,123.006,123.004
mysql> insert into tf values(123.006,123.006,123.004);
--去掉表tf欄位的精度,並重新插入1.23
mysql> alter table tf modify id1 float;
mysql> alter table tf modify id2 double;
mysql> alter table tf modify id3 decimal;
mysql> insert into tf values(1.23,1.23,1.23);
mysql> desc tf;
--向表中分別插入1.234567123321,1.234567123321123321,1.23234233
mysql> insert into tf values(1.234567123321,1.234567123321123321,1.23234233);

位型別

對於BIT型別,用於存放位欄位值,BIT(M)可以用來存放多位二進位制數,M範圍從1~64,如果不寫,預設為1位。而直接使用SELECT命令不會看到查詢結果,需使用bin()(顯示為二進位制)函式或者hex()(顯示為16進位制)函式進行讀取。

示例:

--建立表tb,定義欄位id1為bit(1),id2欄位為bit
mysql> create table tb(id1 bit(1),id2 bit);
--向tb中插入1,1
mysql> insert into tb values(1,1);
mysql> select * from tb;
mysql> select bin(id1),hex(id2) from tb;

資料插入bit兩型別欄位時,首先轉換為二進位制,如果位數允許,則成功插入;如果位數超出定義的位數,則插入失敗。

時間型別

MySQL中由多種資料型別可以用於日期和時間的表示,下表是MySQL5.0中所有支援的日期和時間型別。

日期和時間型別 位元組 最小值 最大值
DATE 4 1000-01-01 9999-12-31
DATETIME 8 1000-01-01 00:00:00 9999-12-31 23:59:59
TIMESTAMP 4 19700101080001 2038年某個時刻
TIME 3 -838:59:59 838:59:59
YEAR 1 1901 2155

每種時間型別都有一個有效範圍,如果超出這個範圍,在預設的SQLMode下,系統會進行錯誤提示,並將以零值來進行儲存。

資料型別 零值表示
DATE 0000-00-00
DATETIME 0000-00-00 00:00:00
TIMESTAMP 00000000000000
TIME 00:00:00
YEAR 0000
--建立表tdt
mysql> create table tdt(dt date, dttm datetime, tms timestamp,tm time,yr year);
--使用now()函式向表中插入當前時間
mysql> insert into tdt values(now(),now(),now(),now(),now() );
--向tms中插入NULL,MySQL會自動賦值系統時間
mysql> insert into tdt(tms) values(null);

MySQL只會給表中第一個TIMESTAMP欄位賦值系統時間,如果有其他的,則賦值為0值。

--修改表tdt,增加TIMESTAMP型別的tms1列,並給tms,tms1賦值null
mysql> alter table tdt add tms1 timestamp;
mysql> desc tdt;
mysql> insert into tdt(tms,tms1) values(null,null);

TIMESTAMP有一個重要特點,就是和失去相關。當插入提起時,會先轉換為本地時區後存放;而從資料庫取出時,需要將日期轉換為本地時區後顯示。

--建立表tdt1,包含欄位tms,dt
mysql> create table tdt1(tms timestamp,dt datetime);
--檢視當前時區,並向表tdt1中插入系統時間
mysql> show variables like 'time_zone';
mysql> insert into tdt1 values(now(),now());

可以發現,時區的值為SYSTEM,這個值預設是和主機的時區一致的,因為處在中國,這裡實際是東八區(+8:00)。

--修改時區為東九區,再次檢視tdt1中的時間
mysql> set time_zone='+9:00';

字串型別

MySQL中提供了多種對字串資料的儲存型別,不同版本有所差異。以5.0為例,MySQL包括了CHARVARCHARBINARYVARBINARYBLOBTEXTENUMSET等多種。

資料型別 描述即儲存
CHAR(M) M為0~255之間的整數
VARCHAR(M) M為0~65535之間的整數,值的長度+1個位元組
TINYBLOB 允許長度0~255位元組,值的長度+1個位元組
BLOB 允許長度0~65535位元組,值的長度+2個位元組
MEDIUMBLOB 允許長度0~167772150位元組,值的長度+3個位元組
LONGBLOB 允許長度0~4294967295位元組,值的長度+4個位元組
TINYTEXT 允許長度0~255位元組,值的長度+1個位元組
TEXT 允許長度0~65535位元組,值的長度+2個位元組
MEDIUMTEXT 允許長度0~167772150位元組,值的長度+3個位元組
LONGTEXT 允許長度0~4294967295位元組,值的長度+4個位元組
VARBINARY(M) 允許長度0~M個位元組的變長位元組字串,值的長度+1個位元組
BINARY(M) 允許長度0~M個位元組的定長位元組字串

CHAR和VARCHAR

兩者很類似,都用來儲存MySQL中較短的字串。二者主要區別在於儲存方式的不同:CHAR列的長度固定為建立表時宣告的長度;而VARCHAR列中的值為可變長字串。在檢索時,CHAR會刪除尾部的空格,而VARCHAR不會。

--建立表tc,包含兩個欄位ch(char(6))和vc(varchar(6))
mysql> create table tc (ch char(6),vc varchar(6));
--向ch和vc欄位插入'abc   '
mysql> insert into tc values('abc   ','abc   ');
--查詢欄位長度
mysql> select length(ch),length(vc) from tc;

BINARY和VARBINARY

類似於CHAR和VARCHAR,不同的是它們儲存的是二進位制的字串。

--建立表tbc,包含欄位bc(binary(6))、vbc(varbinary(6))
mysql> create table tbc (bc binary(6),vbc varbinary(6));
--向表中插入資料('a  ','a  ')
mysql> insert into tbc values('a  ','a  ');
--檢視欄位值長度
mysql> select length(bc),length(vbc) from tbc;

當儲存BINARY值時,MySQL通過在值的最後填充0x00(零位元組)以達到指定的欄位定義長度。

--通過hex()函式檢視tbc中資料的儲存
mysql> select length(bc),length(vbc) from tbc;

ENUM型別

列舉型別,它的值範圍需要在建立表時通過列舉方式顯示指定,對1255個成員的列舉,需要1個位元組儲存;對於25665535個成員,需要2個位元組儲存。最多允許有65535個成員。

--建立表te,包含欄位f1(enum('a','b','c'))
mysql> create table te(f1 enum('a','b','c'));
--向表中插入幾條記錄
mysql> insert into te values('a'),('B'),('3'),(null);

ENUM是忽略大小寫的。還支援使用下標(從1開始,下標越界時報錯)的方式插入資料。特殊值'0'表示一個空值。

SET型別

SET和ENUM非常類似,也是一個字串物件,裡面可以包含0~64個成員。根據成員個數不同,儲存也有所不同。

1~8個成員的集合,佔1個位元組

9~16個成員的集合,佔2個位元組

17~24個成員的集合,佔3個位元組

25~32個成員的集合,佔4個位元組

32~64個成員的集合,佔8個位元組

而且,SET型別一次可以選擇多個成員。

--建立表ts,包含欄位f1(set())
mysql> create table ts (f1 set('a','b','c','d'));
mysql> insert into ts values('a,b'),('a,d'),('b,c,d');
--向表中插入資料('a,b,a,c,d,d')
mysql> insert into ts values('a,b,a,c,d,d');

SET型別可以從允許值集合中選擇任意個元素進行組合,所以對於輸入的值只要在允許值的組合範圍內,都可以正確的記錄到SET型別的列中。對於超出允許範圍的值,報錯。而有重複成員的集合,將自動去重。