序言數據庫
今天去健身了,感受把身體練好仍是不錯的,閒話很少說,把這個數據庫所遇到的數據類型今天通通在這裏講清楚了,之後在看到什麼數據類型,咱度應該認識,下面就跟着個人節奏去把這個拿下吧。函數
---WZYspa
1、數據類型設計
MySQL的數據類型有大概能夠分爲5種,分別是 整數類型、浮點數類型和定點數類型、日期和時間類型、字符串類型、二進制類型。如今能夠來看看你對這5種類型的熟悉程度,哪一個看起來懵逼了,那就說明本身哪一個不熟悉,不理解。
3d
注意:整數類型和浮點數類型能夠統稱爲數值數據類型,這不難理解。excel
數值數據類型對象
整數類型:TINYINT、SMALLINT、MEDIUMINT、INT、BIGINTblog
浮點數類型:FLOAT、DOUBLE索引
定點小數:DECIMAL事件
日期/時間類型
YEAR、TIME、DATE、DATETIME、TIMESTAMP
字符串類型
CHAR、VARCHAR、TEXT、ENUM、SET等
二進制類型
BIT、BINARY、VARBINARY、BLOB
一、整數類型
無論你學什麼語言,在基礎方面,都應該知道 1個字節= 8位二進制數。 每一個類型的取值範圍也就可以知道,好比 TINYINT佔用1個字節,也就是8位,2的8次方減1等於255,也就是說若是表明沒符號的整數,該取值範圍爲0~255,若是是有符號的,最高位爲符號號位,也就是2的7次方減1,也就是127,取值範圍爲-128~127, 爲何須要減1,這個問題就須要考慮臨界值的問題了。而考慮臨界值問題又有須要討論原碼補碼反碼的知識,這些度不是咱們討論的重點,因此在這就自行百度。給出一張範圍表,給你們作參考。
不一樣整數類型的取值範圍
根據本身所需去選取不一樣的類型名稱,
例如:
CREATE TABLE aaa(
id INT(10) PRIMARY KEY,
age INT(6)
);
這個例子中INT(10)、INT(6) 括號中的數字表示的是該數據類型指定的顯示寬度,指定可以顯示的數值中數字的個數。這裏要注意:顯示寬度和數據類型的取值範圍是無關的,顯示寬度只是指明MySQL最大可能顯示的數字個數,注意是可能。通俗點講就是,好比這個age字段,顯示寬度爲6,可是若是你插入的數據大於6,達到了8,6666 6666,那也不要緊,只要插入的數值的位數不超過該類型整數的取值範圍,就行,若是插入的數值長度是4,或者3,數值的位數小於指定的寬度,後面的位數就會由空格填空,5555插入age字段,存的就是"5555 "後面用空格補齊。還有一點,這個顯示寬度沒限制,你寫100度沒問題,可是插入數據時,實際起控制做用的仍是數據類型的取值範圍。若是不寫顯示寬度,就會用系統默認的,好比,INT的默認顯示寬度是11,看上面表,最高也就能表示10位大小的數值,可是要注意,有符號的,也就是負數時,符號位也佔一位。
二、浮點數類型和定點數類型
2.1解釋M,D的意思:
M:數值的總位數。 通俗點講,就是看有多少個數字,好比,5.6789,M就是5
D:小數點後面能保留幾位。 好比上面的5.6789 ,D就是4。 這只是舉一個例子,來講明M,D是什麼,實際是先有M,D的,而後在來控制數值,而不是更具數值來肯定M,D。
不僅僅就MECIMAL有M,D這兩個參數,FLOAT 和 DOUBLE 度有,看下面例子
好比:
CREATE TABLE tmp(
x FLOAT(3,1),
y DOUBLE(5,3),
z DECIMAL(5,4)
);
假設x插入的值爲:5.69,56.78,5.438,349.2 (注意:實驗給x這個字段插入的值,可能實驗了三次,不要錯當作x的值爲5.69,y爲56.78等等了)
實際上在數據庫中存的值爲:5.7,56.9,5.3,349.2這個報錯
分析:x的M爲3,D爲1,那麼小數點上必須是佔了一位數字,就算沒有值,也會用0來填充,因此說,整數位上最多就只能是2位,這裏要切記要先根據D的值,來算整數位能最多有多少位。
經過分析x,y和z也就簡單了,
y字段上的值,整數部分最可能是2位,小數點後的位數最可能是3位,也就是說小數點後超過了3位,就會四捨五入。
z字段上的值,整數部分最多隻能是一位,小數點後的位數最可能是4位,若是不足4位,也會用0補充。好比插入1.56,在數據庫中存的就是1.5600, 好比插入25.46,這個就會報錯,由於整數部分只能是一位,小數點後的位數已經佔了4位了。這裏要搞清楚。
2.二、FLOAT、DOUBLE、DECIMAL三者的區別。
都是用來表示咱們所說的小數的也就是浮點數,可是三種的精度不同,也就是後面顯示的位數不同,
區別一:
FLOAT顯示後面的小數點位大概在40多位,
DOUBLE能顯示的就是300多位了,不是一個層次上的,
DECIMAL這個小數點後面能顯示的位數跟DOUBLE差很少,
區別二:
FLOAT和DOUBLE在不指定精度時,也就是不用(M,D),默認會按照實際的精度,也就是你寫多少就是多少,而DECIMAL如不指定精度默認爲(10,0),也就是若是不指定精度,插入數值56.89,在數據庫中存儲的就是57。因此通常使用DECIMAL時就會指定精度,而使用FLOAT和DOUBLE就不用。
區別三:
浮點數相對與定點數(DECIMAL)的優勢就是在長度必定的狀況下,浮點數可以表示更大的數據範圍,可是缺點是會引發精度問題。
2.三、何時使用FLOAT、DOUBLE、DECIMAL
對精度要求比較高的時候,好比貨幣、科學數據等,使用DECIMAL的類型比較好。其餘的時候,看你要存放的數據的大小而定了,通常使用DOUBLE。而且在使用浮點數時須要注意,儘可能避免作浮點數的比較,好比加、減,誰大誰小,這樣的操做,會引發精度缺失。相信在一些程序語言中,遇到過float精度丟失的問題。
三、日期與時間類型
如今有些東西看不懂不要緊,大概有個瞭解先,接下來一一進行講解。
3.一、YEAR
3.1.一、重點看他的存儲範圍,1901~2155. 在插入該數值時,有兩種方式,一種是用字符串來表明插入的YEAR值,另外一種是用數字表明YEAR值,其中字符串插入的能夠用單引號和雙引號,沒區別,跟一些程序設計語言不同,單個字符就必須用單引號,多字符就要用雙引號,在MySQL中,單雙引號度表示字符。
例子:
CREATE TABLE tmp(
y YEAR
);
向表中插入數據:INSERT INTO tmp VALUES(2010),('2010'),("2010");
查詢表中數據:SELECT * FROM tmp;
能查看三條記錄度插入到數據庫tmp表中了。注意:這裏插入數據和查詢數據操做還沒學過,若是不知道,能夠暫時跳過,直接看結論。
若是向表中插入超出範圍的值,2166則會報錯
3.1.二、在插入完全年份時,用字符串和用數字表明YEAR值的效果是同樣的,可是當省略YEAR值時,用這兩種方式就不同了。
例子一:就拿上面那張tmp表來講。向表中插入用字符串表明的YEAR值,'’0' 、'00'、 '77'、 '10'
刪除表中數據:DELETE FROM tmp;
向表中插入數據:INSERT INTO tmp VALUES('0'),('00'),('77'),('10');
結果:
插入的字符'0'、'00'變成了2000
插入的字符'77'變成了1977
插入的字符'10'變成了2010
例子二:向tmp表中y字段插入2位數字表示YEAR值,0,00,78,11
刪除表中數據:DELETE FROM tmp;
向表中插入數據:INSERT INTO tmp VALUES(0),(00),(77),(11);
結果:
插入的數字0、00變成了0000
插入的數字77變成了1977
插入的數字11變成了2011
結論:在省略寫年份時,
一、用字符表示和用數字表示的區別就在於0。若是是字符0或字符00,則在數據庫中會生成2000,若是是數字0或00,則會生成0000.
二、在不超過70,也就是小於70,度會生成2000年以上,也就是若是是69,則生成2069.若是是70以上包含70,就會變成1970以上。好比70,就會變爲1970。也就是00-69範圍的年值轉換爲2000~2069. 70-99範圍的年值轉換爲1970~1999
三、通常咱們若是要使用,也就用全稱,這樣不容易混淆,可是得知道有這些特性
3.二、TIME
格式:HH:MM:SS HH表示小時 、MM表示分鐘、SS表示秒
取值範圍:-838:59:59 ~ 838:59:59
解釋:這裏的時間不只僅能夠用來表示一天的時間(也就是24小時),還多是某件事情過去的時間或兩個事件之間的時間間隔,通俗點講,咱們日常天天的時間就是從凌晨0點就從新開始計時,計滿24個小時,而後又從新開始,也就至關於當前咱們看到的時間是凌晨0點過去的時間,也就是距凌晨0點過去了多少個小時。 早上7點,也就是距離凌晨0點這件事7個小時,以此類推,直到距離了24個小時,而後從新開始計算。 在MySQL中,這個TIME就不侷限於天天距離凌晨0點多長時間了,能夠是過去某個時間距離如今多長時間了,好比昨天早上7點,距離如今上午9.00多長時間了,就超過了24小時,因此。這個TIME的取值範圍就比咱們所理解的24小時更大。
3.2.一、表示TIME有不少種格式,上面的HH:MM:SS只是標準的一種,
一、D HH:MM:SS :D表示日、天數。在數據庫中存儲時,D會被轉換爲小時保存,D*24+HH
二、HH:MM 、D:HH、 SS :這些格式度是能夠的,注意最後一個,若是是單獨就是2個數字,那麼就表明的是秒,好比"20"那就表明的是00:00:20
三、HHMMSS: 這是沒有間隔符的字符串或者數值,好比101112會被理解爲10:11:12,可是109712就是不合法的,由於分鐘位上超過了59。存儲時會報錯。這個沒有冒號時須要注意一點,數值的最右邊兩位表示秒,以此類推,好比 5523 表示的是00:55:23而不是55:23:00。 因此說上面SS格式時表明的是秒就是這樣來的,從最右邊看起。若是有冒號,則從左邊小時開始看起,好比 55:23 就是表明的55:23:00
例如:
CREATE TABLE tmp(
t TIME
);
插入值"10:05:05"、"23:23"、"2 10:10"、"3 02"、"10"、"101112"、"109712"
INSERT INTO tmp VALUES("10:05:05"),("23:23"),("2 10:10"),("3 02"),("10"),("101112");
SELECT * FROM tmp;
能夠看出:都是如咱們預期的那樣顯示數據。
3.2.二、使用系統的函數,插入當前的時間。
DELETE FROM tmp;
INSERT INTO tmp VALUES(CURRENT_TIME),(NOW());
SELECT * FROM tmp;
3.三、DATE
格式:YYYY-MM-DD YYYY表示年份 MM表示月份 DD表示日
取值範圍:1000-01-01~9999-12-3
使用字符或者數值的數據度能夠插入
注意:這個除了標準格式以外,跟TIME同樣YEAR同樣,在年份這裏也有其省略格式,其規則和YEAR中同樣。00-69範圍的年值轉換爲2000~2069. 70-99範圍的年值轉換爲1970~1999。 例如:12-12-31 表示2012-12-31 981231表示1998-12-31
也可使用CURRENT_DATE或者NOW()插入當前的系統日期。
例子:(注意,每次建立表以前,會把以前的老表給刪除掉,這裏省略掉了,使用DROP TABLE 表名; )
CREATE TABLE tmp(
d DATE
);
INSERT INTO tmp VALUES("1998-08-08"),(19980808),(100511),(CURRENT_DATE),(NOW());
SELECT * FROM tmp;
注意:MySQL容許「不嚴格」語法,也就是任何標點符號度能夠當用日期部分之間的間隔符,好比"98.11.23"、"98/11/31"、"98@11@31"均可以,本身能夠去嘗試嘗試,可是通常使用標準格式比較好,讓人看起來舒服。
3.四、DATETIME
格式:YYYY-MM-DD HH:MM:SS
取值範圍:1000-01-01 00:00:00~9999-12-3 23:59:59
這個不用作多解釋,由於這個就是DATE和TIME的結合體。其各類特色在這裏也可以適合。可是注意HH:MM:SS 只能表示一天的時間,也就最多到23:59:59.
例子:
CREATE TABLE tmp(
dt DATETIME
);
INSERT INTO tmp VALUES("1998-08-08 08-08-08"),(980808080808),(CURRENT_DATE()),(NOW());
SELECT * FROM tmp;
CURRENT_DATE()返回的是當前系統的日期 格式 YYYY-MM-DD 因此在前面打印YEAR和DATE度能夠用到該函數,由於包含了其數據類型所要的信息
NOE()返回當前系統的日期和時間值,格式爲YYYY-MM-DD HH:MM:SS,因此在這裏可以使用其輸出DATETIME類型的值。
3.五、TIMESTAMP
格式:YYYY-MM-DD HH:MM:SS
取值範圍:1970-01-01 00:00:01 UTC ~ 2038-01-19 03:14:17 UTC
解釋:顯示寬度固定在 19個字符。也就是這個輸出標準格式,UTC表示世界標準時間,這個跟DATETIME基本上同樣,可是有一個最大的區別,咱們須要知道。
區別:存儲字節和支持的範圍不同,最重要的區別在DATETIME在存儲日期數據時,按實際輸入的格式存儲,即輸入什麼就存儲什麼,也就輸出什麼,與時區無關,而TIMESTAMP值的存儲是以UTC格式保存,存儲時會對當前時區進行轉換,檢索時再轉換回當前時區,也就是查詢時,會根據當前時區的不一樣,顯示的時間值不一樣。 時區的意思就是,你在美國和你在中國兩邊的時間顯示不同,你在美國有在美國的時間,比中國快多長時間,好比在中國才早上8點,在美國可能就是晚上8.9點了(這個只是打個比方,準備轉換時間我沒去看。)
例如:
CREATE TABLE tmp(
ts TIMESTAMP
);
INSERT INTO tmp VALUES(NOW());
SELECT * FROM tmp;
轉換時區
能夠看到,如咱們所想,輸出時間變了,增長了兩個小時,這個是關於什麼東10區,東8區等,我也不懂這些時差,總之可以得出結論就好了。
也就是說,TIMESTAMP和DATETIME其實差很少,就是一個時區的差異。TIMESTAMP也叫時間戳。之後遇到它咱們就應該知道是什麼東西了
四、字符串類型
有CHAR、CARCHAR、TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT、ENUM、SET
4.一、CHAR和VARCHAR
CHAR(M):爲固定長度字符串,固定長度的意思就是M的值爲多少,那麼該M的值就是其實際存儲空間的值,就算插入的數據少於M位,其存儲空間仍是那麼大,多餘的用空格補齊。在輸出時,空格將被刪除不輸出。M最大爲255,好比char(4),若是插入abc,則存儲的值爲'abc '後面多了一個空格,輸出仍是‘abc’, 存儲空間仍是佔4個字節。M最大爲255
VARCHAR(M):長度可變的字符串,跟CHAR相反,會根據實際的大小值來肯定存儲空間的大小,好比 VARCHAR(4),插入'ab',則存儲空間爲3字節,看上面圖就知道VARCHAR會多一個字節用來存儲長度,M最大爲65535.
注意:字符串跟數值類型不同,M爲多大,就最多能插入多少字符,超過了M,就會報錯
例子:
CREATE TABLE tmp(
ch CHAR(4),
vch VARCHAR(4);
);
INSERT INTO tmp VALUES('asdf','asdfg');
結果報錯:
INSERT INTO tmp VALUES('ab ','ab ');
SELECT concat( '(', ch ,')' ),concat( '(',vch,')' ) FROM tmp;//這句話的意思就用(將結果包起來,用來觀察輸出的字符長度)
說明,CHAR不可以存儲空格字符,而VARCHAR能夠。
4.二、TEXT
text分四種:TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT
TINYTEXT:255字符
TEXT:65535字符
MEDIUNTEXT:16777215字符
LONGTEXT:4294967295,大概4GB的字符
也就是說,好比咱們要存一本小說,那麼就須要使用上面四種中的一種來存儲,選取MEDIUNTEXT或者LONGTEXT差很少。
4.三、ENUM
枚舉,格式:字段名 ENUM('值1','值2','值3'...,'值n'); n最多爲65535
例如:
CREATE TABLE tmp(
enm ENUM('first','second','third');
);
解釋:enm字段的數據類型爲ENUM,枚舉類型,那麼在插入該字段中的值只能爲枚舉中的這幾個值,不能插入別得值,不然報錯
INSERT INTO tmp VALUES('first'),('FIRST');
SELECT * FROM tmp;
MySQL不區分大小寫。
INSERT INTO tmp VALUES('four');
報錯:
例子二:
CREATE TABLE tmp(
soc INT,
level ENUM('excellent','good','bad')
);
INSERT INTO tmp VALUES(70,2),(90,1),(55,3);
SELECT * FROM tmp;
使用索引值,也能夠選擇枚舉中得值,從1開始,不是0,注意這點
總結:使用ENUM類型就是爲了限制字段上的值的取值範圍,只能取咱們所規定的值。
4.四、SET
格式:字段名 SET('值1','值2','值3','值4'...,'值n') n最大爲64
經過例子來說解這個SET的特色
CREATE TABLE tmp(
s SET('a','b','c','d');
);
INSERT INTO tmp VALUES('a'),('a,b,a'),('c,a,d');
SELECT * FROM tmp;
a 變成 a
a,b,a 變成 a,b
c,a,d 變成 a,c,d
結論:
一、插入SET字段中的值若是有重複,則會自動刪除重複的值
二、插入SET字段中的值會按順序排列,排列規則就是按照SET中的值的排列優先順序
INSERT INTO tmp VALUES('a,x,b');
報錯:
結論:
三、若是插入了不屬於SET中的值,就會報錯
SET的特性就上面所說的三點
五、二進制類型
用來存放二進制數,也就是01010這種。有BIT、BINARY、VARBINARY、TINYBLOB、BLOB、MEDIUNBLOB和LONGBLOB
5.一、BIT類型
位字段類型,M表示插入值的位數,最大爲64位,默認值爲1,若是插入值小於M位,值的左邊用0填充,
例子:
CREATE TABLE tmp(
b BIT(4)
);
解釋:4位的二進制,也就是可以保存0到15之間的值。
INSERT INTO tmp VALUES(2),(10),(15);
SELECT BIN(b+0) FROM tmp;
解釋:咱們將2,10,15這三個10進制存入數據表中,其字段爲BIT類型,因此在表中存放的是二進制數,可是將其顯示出來,要先將二進制數轉換爲對應的數字的值,也就是經過b+0, 而後在經過BIN()函數將數字轉換爲二進制。咱們能夠嘗試不用BIN()函數,只用b+0,看輸出什麼
SELECT b+0 FROM tmp;
5.二、BINARY和VARBINARY類型
格式:字段 BINARY(M)或者VARBINARY(M)
這兩個跟CHAR和VARCHAR相似,
BINARY:長度是固定的,指定長度後,不足最大程度的,將在它們右邊填充"\0"來達到指定長度,
VARBINARY:長度是可變的,制定好長度後,其長度能夠在0到最大值之間,例如,指定字段數據類型爲VARBINARY(20),若是插入的值的長度只有10,則實際存儲空間爲10加1,即實際佔用的空間爲字符串的實際長度加1.
說了這麼多,可是仍是不明白這兩個有什麼用處,如今來告訴你,咱們說MySQL中對大小寫不敏感,可是這兩個數據類型卻對大小寫敏感,緣由是他們是用二進制來保存數據的,好比A和a,兩個的二進制就不同。因此在不少時候咱們須要區分大小寫的時候,就會用到該類型。
注意:這兩個類型的長度計算的是字節長度,一個字符等於2個字節,好比BINARY(4)這個表示可以存放4個字節的長度,也就是隻能存放2個漢字。能夠存4個字母。不要把這個長度當成二進制位的長度了,說是二進制字符串的意思是,用二進制來進行存儲,可是其長度約束是字節長度。
例子:
CREATE TABLE tmp(
b BINARY(10)
);
INSERT INTO tmp VALUES('a');
select * from tmp WHERE b='A';
解釋:在tmp表中存放了一個小寫a,而後經過大寫A查找表中,看是否能找到a,結果找不到,就驗證了咱們上面的說法,具備區分大小寫的功能。
總結:BINARY和VARBINARY的主要做用就是用來區分大小寫的,其餘沒什麼做用,可是使用時要注意限制其大小的是字節數,而不是二進制位,它存儲的格式是用二進制來存儲的。這兩個不要搞混淆了。
5.三、BLOB類型
是一個二進制大對象,TINYBLOB(32kb)、BLOB(64kb)、MEDIUMBLOB(16M)和LONGBLOB(4GB)。通常存儲的是一些圖像,音頻文件。
2、如何選擇數據類型
一、整數和浮點數
若是不須要小數部分,則使用整數來保存數據,而且根據整數的大小,來選擇合適的整數類型,若是須要小數部分,則使用浮點數類型,浮點數類型中,有float和double,若是須要精度高一點,則選擇double。根據本身的需求來決定選什麼。
二、浮點數和定點數
浮點數FLOAT、DOUBLE相對應定點數DECIMAL的優點在於:在長度必定的狀況下,浮點數能表示更大的數據範圍,可是浮點數容易產生偏差,所以在精度比較高時,建議使用DECIMAL,好比貨幣這一類東西,就用DECIMAL比較合理,注意浮點數在進行加減運算時也容易出現問題。若是進行數值比較,也建議用DECIMAL
三、日期與時間類型
能夠看上面詳解時的圖,根據各類格式,選擇本身所須要的數據類型,注意TIMESTAMP和DATETIME的區別,一個是跟時區有關,一個無關,其餘沒什麼大的區別。
四、CHAR與VARCHAR之間的特色與選擇
區別:
CHAR是固定長度字符、VARCHAR是可變長度字符。CHAR會自動刪除插入數據的尾部空格,VARCHAR不會。
CHAR是固定長度,處理速度比VARCHAR更快,缺點很明顯,浪費存儲空間,因此對存儲不大,但在速度上有要求的可使用CHAR類型,反之用VARCHAR。
五、ENUM和SET
ENUM只能取單值,也就是從枚舉類型中選取其中一個值,可是SET能夠取多值,
ENUM最多能存放65535個成員,SET只能65個
空字符串也能在SET中存儲,
要存儲一我的的喜好時,最好使用SET類型,其實最重要的是看具體的狀況在選取最爲合適的把
六、BLOB和TEXT
BLOB是二進制字符串,TEXT是非二進制字符串,二者都可存放大容量的信息,BLOB主要存儲圖片、音頻信息,而TEXT只能存儲純文本文件。分清楚二者的用途
七、BINARY和VARBINARY
這兩個的區別和CHAR與VARCHAR的區別差很少,BINARY是固定長度、VARBINARY是可變程度,這兩個的做用就是爲了區分大小寫的,注意這兩個是字節字符串。