mysql中char、varchar、nvarchar數(shù)據(jù)類型的用法區(qū)別 有需要的朋友可
說(shuō)明:
1、char:
固定長(zhǎng)度的非 Unicode 字符數(shù)據(jù),最大長(zhǎng)度為 8,000 個(gè)字符。
2、varchar:
可變長(zhǎng)度的非 Unicode 數(shù)據(jù),最長(zhǎng)為 8,000 個(gè)字符。
3、nvarchar:
可變長(zhǎng)度 Unicode 數(shù)據(jù),其最大長(zhǎng)度為 4,000 字符。
4、nchar
固定長(zhǎng)度的 Unicode 數(shù)據(jù),最大長(zhǎng)度為 4,000 個(gè)字符。
5、char和varchar都是字符串類型的
用Unicode編碼的字符串,結(jié)果是字符的整數(shù)值
如有以下數(shù)據(jù)結(jié)構(gòu):
工號(hào) 姓名 部門(mén)
———————–
1 張三 財(cái)務(wù)
2 李四 人事
3 王五 銷售
……..
我們定義”姓名”為char(10)(靜態(tài))的時(shí)簡(jiǎn)單地用php代碼表示:
簡(jiǎn)單地模擬底層數(shù)據(jù)存儲(chǔ)鏈表$data
代碼如下 | |
$col_num_len =1; //工號(hào)長(zhǎng)度為1 $col_name_len=10; //姓名長(zhǎng)度為10 $col_unit_len =4; //部門(mén)長(zhǎng)度為4 $col_len=$col_num_len+$col_name_len+$col_unit_len+3; |
//表示每筆記錄的總長(zhǎng)度,包括3個(gè)分隔符
實(shí)現(xiàn)如下:
代碼如下 | |
$data="1|張三 |財(cái)務(wù)|2|李四 |人事|3|王五 |銷售|..."; //簡(jiǎn)單地模擬底層數(shù)據(jù)存儲(chǔ)鏈表 //假設(shè)查找第2條記錄的"姓名"字段數(shù)據(jù) |
-----------
代碼如下 | |
//假設(shè)更新第2條記錄的"姓名"字段數(shù)據(jù)為"李小四" $update_info="李小四"; $data=substr_replace($data,$update_info,$col_name_start,$col_name_len); //更新字段,流程結(jié)束 而如果我們定義”姓名”字段為varchar(10)(動(dòng)態(tài))的時(shí)候情況則要復(fù)雜: 注意存儲(chǔ)”姓名”的字段沒(méi)有空格,這是char和varchar的存儲(chǔ)區(qū)別 $col_num_len =1; //工號(hào)長(zhǎng)度為1 $col_name_len=10; //姓名長(zhǎng)度為10 $col_unit_len =4; //部門(mén)長(zhǎng)度為4 $col_len=$col_num_len+$col_name_len+$col_unit_len+3; |
實(shí)現(xiàn)如下:
代碼如下 | |
//動(dòng)態(tài)存放數(shù)據(jù)行的起始位置,數(shù)據(jù)為更新時(shí)生成(重新) $data="1|張三|財(cái)務(wù)|2|李四|人事|3|王小明|銷售|..."; //簡(jiǎn)單地模擬底層數(shù)據(jù)存儲(chǔ)鏈表,注意存儲(chǔ)"姓名"的字段沒(méi)有空格 //假設(shè)查找第2條記錄的"姓名"字段數(shù)據(jù) //假設(shè)更新第2條記錄的"姓名"字段數(shù)據(jù)為"李小四",這邊比靜態(tài)的復(fù)雜很多 //在此假設(shè)總記錄數(shù)為n $data=substr_replace($data,$update_info,$col_name_start,0); |
文中直接使用”substr_replace”,而在數(shù)據(jù)量很大的時(shí)候,底層實(shí)現(xiàn)上的開(kāi)銷也是不小的,在mysql中表現(xiàn)為(Row Migration)現(xiàn)象,在此不作贅述
根據(jù)以上的粗略實(shí)現(xiàn)證明:
1、varchar類型在更新環(huán)節(jié)上的系統(tǒng)開(kāi)銷是遠(yuǎn)大于char類型的。
2、兩者間查找搜索性能上是不相上下的。
3、兩者間的存儲(chǔ)數(shù)據(jù)量($data)環(huán)節(jié)上,char要顯示大于varchar。
4、大數(shù)據(jù)量提取時(shí)varchar的磁盤(pán)IO消耗更低,意味著varchar綜合查詢性能會(huì)更好。
5、沒(méi)有了。
實(shí)際應(yīng)用中的結(jié)論(如在mysql中):
1、char適合字段頻繁更新時(shí)的應(yīng)用。
2、varchar更節(jié)省磁盤(pán)空間。
3、實(shí)際應(yīng)用中大數(shù)據(jù)量(多行)查詢返回,varchar的查詢性能比起char來(lái)要好出不少。
4、選擇char和varchar會(huì)改變整體數(shù)據(jù)結(jié)構(gòu)的算法以及存儲(chǔ)方式。在mysql應(yīng)用中,如已存在varchar字段,那么其它所有的char字段將以varchar方式存儲(chǔ)。
5、沒(méi)有了。
(以上算法僅以PHP簡(jiǎn)單描述,歡迎更好的思路加以指教)
注:此文原作者的寫(xiě)作時(shí)間比較久遠(yuǎn)了,所以有些地方和現(xiàn)在的有些出入,體現(xiàn)在:
1.在innodb引擎中,char和varchar的實(shí)現(xiàn)已無(wú)異,效率上并沒(méi)多大區(qū)別。
2.選擇char和varchar并不會(huì)改變整體數(shù)據(jù)結(jié)構(gòu)的算法以及存儲(chǔ)方式。(我記得這是在MYSQL4里的特性,網(wǎng)上的老文章有講述,到了MYSQL5實(shí)測(cè)已無(wú)此特性)
總結(jié)分析:
文字字段若長(zhǎng)度固定,如:身分證號(hào)碼,就不要用 varchar 或 nvarchar,應(yīng)該用 char 或 nchar。
支持多語(yǔ)言的站點(diǎn)應(yīng)考慮使用 Unicode nchar 或 nvarchar 數(shù)據(jù)類型以盡量減少字符轉(zhuǎn)換問(wèn)題
文字字段若長(zhǎng)度不固定,如:地址,則該用 varchar 或 nvarchar。除了可節(jié)省存儲(chǔ)空間外,存取硬盤(pán)時(shí)也會(huì)較有效率
聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com