国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數(shù)據(jù)庫 > MySQL > 正文

mysql中char、varchar、nvarchar數(shù)據(jù)類型的用法區(qū)別

2024-07-24 12:38:47
字體:
供稿:網(wǎng)友

說明:1、char:固定長度的非 Unicode 字符數(shù)據(jù),最大長度為 8,000 個字符。 

2、varchar:可變長度的非 Unicode 數(shù)據(jù),最長為 8,000 個字符。

3、nvarchar:可變長度 Unicode 數(shù)據(jù),其最大長度為 4,000 字符。

4、nchar:固定長度的 Unicode 數(shù)據(jù),最大長度為 4,000 個字符。

5、char和varchar都是字符串類型的,用Unicode編碼的字符串,結(jié)果是字符的整數(shù)值.

如有以下數(shù)據(jù)結(jié)構(gòu):

  1. 工號 姓名 部門 
  2. ———————– 
  3. 1 張三 財務(wù) 
  4. 2 李四 人事 
  5. 3 王五 銷售 
  6. …….. 

我們定義”姓名”為char(10)(靜態(tài))的時簡單地用php代碼表示,簡單地模擬底層數(shù)據(jù)存儲鏈表$data,代碼如下:

  1. $col_num_len  =1;      //工號長度為1 
  2. $col_name_len=10;    //姓名長度為10 
  3. $col_unit_len   =4;     //部門長度為4 
  4. $col_len=$col_num_len+$col_name_len+$col_unit_len+3;        
  5.   //表示每筆記錄的總長度,包括3個分隔符 

實現(xiàn)如下,代碼如下:

  1. $data="1|張三  |財務(wù)|2|李四 |人事|3|王五 |銷售|..."//簡單地模擬底層數(shù)據(jù)存儲鏈表 
  2. //假設(shè)查找第2條記錄的"姓名"字段數(shù)據(jù) 
  3. $record_start=$col_len*1+1;   //獲取第2行的起始位置 
  4. $record  =substr($data,$record_start,$col_len); //獲取第2條記錄 
  5. $col_name_start=$col_num_len+2; //獲取"姓名"字段的起始位置 
  6. $col_name=substr($record,$col_name_start,$col_name_len);//獲取"姓名"字段的數(shù)據(jù) 
  7. echo $col_name

代碼如下:

  1. //假設(shè)更新第2條記錄的"姓名"字段數(shù)據(jù)為"李小四" 
  2. $update_info="李小四"
  3. $data=substr_replace($data,$update_info,$col_name_start,$col_name_len);      //更新字段,流程結(jié)束 

而如果我們定義”姓名”字段為varchar(10)(動態(tài))的時候情況則要復(fù)雜,注意存儲”姓名”的字段沒有空格,這是char和varchar的存儲區(qū)別:

  1. $col_num_len  =1;      //工號長度為1 
  2. $col_name_len=10;    //姓名長度為10 
  3. $col_unit_len   =4;     //部門長度為4 
  4. $col_len=$col_num_len+$col_name_len+$col_unit_len+3; 

實現(xiàn)如下,代碼如下:

  1. //動態(tài)存放數(shù)據(jù)行的起始位置,數(shù)據(jù)為更新時生成(重新) 
  2. $record_1_start=1;$record_1_name_dynamic_len=4;                //$col_1_name_dynamic_len記錄"姓名"動態(tài)字段的長度 
  3. $record_2_start=13;$record_2_name_dynamic_len=4; 
  4. $record_3_start=26;$record_3_name_dynamic_len=6; 
  5. ... 
  6. $data="1|張三|財務(wù)|2|李四|人事|3|王小明|銷售|..."//簡單地模擬底層數(shù)據(jù)存儲鏈表,注意存儲"姓名"的字段沒有空格 
  7. //假設(shè)查找第2條記錄的"姓名"字段數(shù)據(jù) 
  8. $record_2_end=$record_3_start-1;   //獲取第2行的結(jié)束位置 
  9. $record  =substr($data,$record_2_start,$record_2_end); //獲取第2條記錄 
  10. $col_name_start=$col_num_len+2;      //獲取"姓名"字段的起始位置 
  11. $col_name=substr($record,$col_name_start,$record_2_name_dynamic_len);  //獲取"姓名"字段的數(shù)據(jù) 
  12. echo $col_name
  13. //假設(shè)更新第2條記錄的"姓名"字段數(shù)據(jù)為"李小四",這邊比靜態(tài)的復(fù)雜很多 
  14. $update_info="李小四"
  15. $update_len=strlen($update_info);  //獲取更新內(nèi)容的長度 
  16. if($diff_len=$update_len-$record_2_name_dynamic_len
  17. $data=substr_replace($data,"",$col_name_start,$record_2_name_dynamic_len);        //清除原先數(shù)據(jù) 
  18. $record_2_name_dynamic_len=$update_len//更新字段的長度(并存儲新值) 
  19. //在此假設(shè)總記錄數(shù)為n 
  20. for($i=2;$i<=n;$i++) 
  21. //Vevb.com 
  22. ${'record_'.$i.'_start'}=${'record_'.$i.'_start'}+$diff_len;                 //重新更新每個行的起始位置(并存儲新值),系統(tǒng)開銷大(實際上有不同的方法解決) 
  23. $data=substr_replace($data,$update_info,$col_name_start,0); 

文中直接使用”substr_replace”,而在數(shù)據(jù)量很大的時候,底層實現(xiàn)上的開銷也是不小的,在mysql中表現(xiàn)為(Row Migration)現(xiàn)象,在此不作贅述.

根據(jù)以上的粗略實現(xiàn)證明:

1、varchar類型在更新環(huán)節(jié)上的系統(tǒng)開銷是遠(yuǎn)大于char類型的。

2、兩者間查找搜索性能上是不相上下的。

3、兩者間的存儲數(shù)據(jù)量($data)環(huán)節(jié)上,char要顯示大于varchar。

4、大數(shù)據(jù)量提取時varchar的磁盤IO消耗更低,意味著varchar綜合查詢性能會更好。

5、沒有了。

實際應(yīng)用中的結(jié)論(如在mysql中):

1、char適合字段頻繁更新時的應(yīng)用。

2、varchar更節(jié)省磁盤空間。

3、實際應(yīng)用中大數(shù)據(jù)量(多行)查詢返回,varchar的查詢性能比起char來要好出不少。

4、選擇char和varchar會改變整體數(shù)據(jù)結(jié)構(gòu)的算法以及存儲方式。在mysql應(yīng)用中,如已存在varchar字段,那么其它所有的char字段將以varchar方式存儲。

5、沒有了。

(以上算法僅以PHP簡單描述,歡迎更好的思路加以指教)

注:此文原作者的寫作時間比較久遠(yuǎn)了,所以有些地方和現(xiàn)在的有些出入,體現(xiàn)在:

1.在innodb引擎中,char和varchar的實現(xiàn)已無異,效率上并沒多大區(qū)別。

2.選擇char和varchar并不會改變整體數(shù)據(jù)結(jié)構(gòu)的算法以及存儲方式,我記得這是在MYSQL4里的特性,網(wǎng)上的老文章有講述,到了MYSQL5實測已無此特性.

總結(jié)分析:

文字字段若長度固定,如:身分證號碼,就不要用 varchar 或 nvarchar,應(yīng)該用 char 或 nchar.

支持多語言的站點應(yīng)考慮使用 Unicode nchar 或 nvarchar 數(shù)據(jù)類型以盡量減少字符轉(zhuǎn)換問題.

文字字段若長度不固定,如:地址,則該用 varchar 或 nvarchar。除了可節(jié)省存儲空間外,存取硬盤時也會較有效率.

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 永春县| 同江市| 邵阳县| 清涧县| 航空| 黄龙县| 平江县| 溧水县| 宣恩县| 泾阳县| 中宁县| 迁西县| 霞浦县| 闽清县| 广丰县| 延寿县| 阿克陶县| 彩票| 方城县| 平泉县| 墨玉县| 莱州市| 桑植县| 葵青区| 宜川县| 金坛市| 彭水| 仪征市| 怀集县| 牟定县| 乃东县| 健康| 方山县| 清河县| 峨山| 瑞安市| 喜德县| 娱乐| 岳普湖县| 遂平县| 通山县|