MySQL 5.7資料型別
——《深入淺出MySQL(第二版)》筆記
數值型別
MySQL支援所有標準SQL中的型別,其中包括嚴格數值型別(INTEGER
、SMALLINT
、DECIMAL
、NUMBERIC
),以及近似數值型別(FLOAT
、FEAL
、DOUBLE PRECISION
),並且在此基礎上做了擴充套件。擴充套件增加了TINYINT
、MEDIUMINT
和BIGINT
三種長度不同的整型型別,並增加了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包括了CHAR
、VARCHAR
、BINARY
、VARBINARY
、BLOB
、TEXT
、ENUM
和SET
等多種。
資料型別 | 描述即儲存 |
---|---|
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型別的列中。對於超出允許範圍的值,報錯。而有重複成員的集合,將自動去重。