1? 概述
數(shù)據(jù)類型
.數(shù)據(jù)長什么樣?
.數(shù)據(jù)需要多少空間來存放?如整數(shù)有不同的類型,存儲的空間不一樣
.系統(tǒng)內(nèi)置數(shù)據(jù)類型和用戶定義數(shù)據(jù)類型
.MySql支持多種列類型:(內(nèi)置數(shù)據(jù)類型)
.數(shù)值類型
.日期/時間類型
.字符串(字符)類型
.選擇正確的數(shù)據(jù)類型對于獲得高性能至關(guān)重要,三大原則:
.更小的通常更好,盡量使用可正確存儲數(shù)據(jù)的最小數(shù)據(jù)類型,原則是夠用就好
.簡單就好,簡單數(shù)據(jù)類型的操作通常需要更少的CPU周期,復(fù)雜的話會消耗額外的資源
.盡量避免NULL,如果包含為NULL的列,對MySQL更難優(yōu)化
2 數(shù)據(jù)類型
1? 整型
.tinyint(m)? 1個字節(jié)范圍(-128~127)
.smallint(m)2個字節(jié)范圍(-32768~32767)
.mediumint(m)3個字節(jié)范圍(-8388608~8388607)
.int(m)4個字節(jié)范圍(-2147483648~2147483647)
.bigint(m)8個字節(jié)范圍(+-9.22*10的18次方)
取值范圍如果加了unsigned,那么最大值就會翻倍,如tinyint? unsigned的取值范圍為(0~255),表示正整數(shù)
int(m)里的m是表示SELECT查詢結(jié)果集中的顯示寬度,并不影響實(shí)際的取值范圍,
在int(M)中,M的值跟int(M)所占多少存儲空間并無任何關(guān)系。int(3)、int(4)、int(8)在磁盤上都是占用4 btyes的存儲空間。說白了,除了顯示給用戶的方式有點(diǎn)不同外,int(M)跟int數(shù)據(jù)類型是相同的。
“(M)”指定了int型數(shù)值顯示的寬度,如果字段數(shù)據(jù)類型是int(4),則:當(dāng)顯示數(shù)值10時,在左邊要補(bǔ)上“00”;當(dāng)顯示數(shù)值100是,在左邊要補(bǔ)上“0”;當(dāng)顯示數(shù)值1000000時,已經(jīng)超過了指定寬度“(4)”,因此按原樣輸出。
MySQL可以為整型類型指定寬度(這里是表示顯示的寬度),例如Int(11),對絕大多數(shù)應(yīng)用這是沒有意義的:它不會限制值的合法范圍,只是規(guī)定了MySQL的一些交互工具(例如MySQL命令行客戶端)用來顯示字符的個數(shù)。對于存儲和計算來說,Int(1)和Int(20)是相同的
2? 浮點(diǎn)型(float和double),近似值
.float(m,d)單精度浮點(diǎn)型8位精度(4字節(jié)) m總個數(shù)(88.66,則m為4個數(shù),d為2為小數(shù)),d小數(shù)位
.double(m,d)雙精度浮點(diǎn)型16位精度(8字節(jié)) m總個數(shù),d小數(shù)位
.設(shè)一個字段定義為float(6,3),如果插入一個數(shù)123.45678,實(shí)際數(shù)據(jù)庫里存的是123.457,但總個數(shù)還以實(shí)際為準(zhǔn),即6位
這里和awk不一樣,awk把小數(shù)點(diǎn)也算作一位,但是這里定義的小數(shù),小數(shù)點(diǎn)不算一位數(shù)。
3? 定點(diǎn)數(shù)
.在數(shù)據(jù)庫中存放的是精確值,存為十進(jìn)制
.decimal(m,d)參數(shù)m<65是總個數(shù),d<30且d
.MySQL5.0和更高版本將數(shù)字打包保存到一個二進(jìn)制字符串中(每4個字節(jié)存9個數(shù)字)。例如,decimal(18,9)小數(shù)點(diǎn)兩邊將各存儲9個數(shù)字,一共使用9個字節(jié):小數(shù)點(diǎn)前的數(shù)字用4個字節(jié),小數(shù)點(diǎn)后的數(shù)字用4個字節(jié),小數(shù)點(diǎn)本身占1個字節(jié)
定點(diǎn)數(shù)一般用來存放財務(wù)數(shù)據(jù)
.浮點(diǎn)類型在存儲同樣范圍的值時,通常比decimal使用更少的
空間。float使用4個字節(jié)存儲。double占用8個字節(jié)
.因?yàn)樾枰~外的空間和計算開銷,所以應(yīng)該盡量只在對小數(shù)進(jìn)行精確計算時才使用decimal——例如存儲財務(wù)數(shù)據(jù)。但在數(shù)據(jù)量比較大的時候,可以考慮使bigint代替decimal
4? 字符串(char,varchar,_text)
.char(n)固定長度,最多255個字符,如定義20字節(jié),允許短,如實(shí)際只有3字節(jié),但是實(shí)際在內(nèi)存或磁盤中存儲占用20個字節(jié)
.varchar(n)可變長度,最多65535個字符,根據(jù)實(shí)際位數(shù)暫用空間
.tinytext可變長度,最多255個字符
.text可變長度,最多65535個字符
.mediumtext可變長度,最多2的24次方-1個字符
.longtext可變長度,最多2的32次方-1個字符
.BINARY(M)固定長度,可存二進(jìn)制或字符,允許長度為0-M字節(jié),
.VARBINARY(M)可變長度,可存二進(jìn)制或字符,允許長度為0-M字節(jié),如存儲圖片或二進(jìn)制內(nèi)容
.內(nèi)建類型:ENUM枚舉, SET集合
.char和varchar:
.1.char(n)若存入字符數(shù)小于n,則以空格補(bǔ)于其后,查詢之時再將空格去掉。所以char類型存儲的字符串末尾不能有空格,varchar不限于此。
.2.char(n)固定長度,char(4)不管是存入幾個字符,都將占用4個字節(jié),varchar是存入的實(shí)際字符數(shù)+1個字節(jié)(最后可能有一個結(jié)束符字符)(n< n>255),所以varchar(4),只存入3個字符也將占用4個字節(jié)。
.3.char類型的字符串檢索速度要比varchar類型的快
.varchar和text:
.1.varchar可指定n,text不能指定,內(nèi)部存儲varchar是存入的實(shí)
際字符數(shù)+1個字節(jié)(n< n>255),text是實(shí)際字符數(shù)+2個字節(jié)。
.2.text類型不能有默認(rèn)值
.3.varchar可直接創(chuàng)建索引,text創(chuàng)建索引要指定前多少個字符。
varchar查詢速度快于text
除非是寫一篇文章或者小短文,考慮用text,如果是普通的字符串,就直接用varchar就可以
5? 二進(jìn)制數(shù)據(jù):BLOB
.BLOB和text存儲方式不同,TEXT以文本方式存儲,英文存儲區(qū)分大小寫,而Blob是以二進(jìn)制方式存儲,不分大小寫
.BLOB存儲的數(shù)據(jù)只能整體讀出
.TEXT可以指定字符集,BLOB不用指定字符集
6? 日期時間類型
.date日期'2008-12-2'
.time時間'12:25:36'
.datetime日期時間'2008-12-222:06:44'
.timestamp自動存儲記錄修改時間,時間戳,只要表里的任意字段被改動,這個時間戳就會自動變化,這里的日期格式是和datetime一樣,如日期時間'2008-12-222:06:44'
若定義一個字段為timestamp,這個字段里的時間數(shù)據(jù)會隨其他字段修改的時候自動刷新,這個數(shù)據(jù)類型的字段可以存放這條記錄最后被修改的時間
例子如下
創(chuàng)建一張表
如下
create table datetb (idint(3) not null,t1 date not null,t2 time not null,t3 datetime,t4timestamp,primary key (id));
往表里插入一條記錄,如下
insert into datetb values(1,"2017-09-09","12:53:12","2017-09-0910:10:08","2017-09-09 10:10:09");
修改記錄t2的值如下
update datetb sett2="01:02:03" where id=1;
實(shí)驗(yàn)結(jié)果是,timestamp這個字段t4的值會自動變更為當(dāng)前系統(tǒng)的時間
.YEAR(2), YEAR(4):年份