SQL中char、varchar、text和nchar、nvarchar、ntext的區(qū)別
1、CHAR。CHAR存儲(chǔ)定長(zhǎng)數(shù)據(jù)很方便,CHAR字段上的索引效率級(jí)高,比如定義char(10),那么不論你存儲(chǔ)的數(shù)據(jù)是否達(dá)到了10個(gè)字節(jié),都要占去10個(gè)字節(jié)的空間。
2、VARCHAR。存儲(chǔ)變長(zhǎng)數(shù)據(jù),但存儲(chǔ)效率沒(méi)有CHAR高。如果一個(gè)字段可能的值是不固定長(zhǎng)度的,我們只知道它不可能超過(guò)10個(gè)字符,把它定義為 VARCHAR(10)是最合算的。VARCHAR類型的實(shí)際長(zhǎng)度是它的值的實(shí)際長(zhǎng)度+1。為什么“+1”呢?這一個(gè)字節(jié)用于保存實(shí)際使用了多大的長(zhǎng)度。
從空間上考慮,用varchar合適;從效率上考慮,用char合適,關(guān)鍵是根據(jù)實(shí)際情況找到權(quán)衡點(diǎn)。
3、TEXT。text存儲(chǔ)可變長(zhǎng)度的非Unicode數(shù)據(jù),最大長(zhǎng)度為2^31-1(2,147,483,647)個(gè)字符。
4、NCHAR、NVARCHAR、NTEXT。這三種從名字上看比前面三種多了個(gè)“N”。它表示存儲(chǔ)的是Unicode數(shù)據(jù)類型的字符。我們知道字符中,英文字符只需要一個(gè)字節(jié)存儲(chǔ)就足夠了,但漢字眾多,需要兩個(gè)字節(jié)存儲(chǔ),英文與漢字同時(shí)存在時(shí)容易造成混亂,Unicode字符集就是為了解決字符集這種不兼容的問(wèn)題而產(chǎn)生的,它所有的字符都用兩個(gè)字節(jié)表示,即英文字符也是用兩個(gè)字節(jié)表示。nchar、nvarchar的長(zhǎng)度是在1到4000之間。和char、varchar比較起來(lái),nchar、nvarchar則最多存儲(chǔ)4000個(gè)字符,不論是英文還是漢字;而char、varchar最多能存儲(chǔ)8000個(gè)英文,4000個(gè)漢字。可以看出使用nchar、nvarchar數(shù)據(jù)類型時(shí)不用擔(dān)心輸入的字符是英文還是漢字,較為方便,但在存儲(chǔ)英文時(shí)數(shù)量上有些損失。
所以一般來(lái)說(shuō),如果含有中文字符,用nchar/nvarchar,如果純英文和數(shù)字,用char/varchar。
數(shù)據(jù)庫(kù)定義到char類型的字段時(shí) char、nchar、varchar、nvarchar、text、ntext中哪一種呢
數(shù)據(jù)庫(kù)定義到char類型的字段時(shí),不知道大家是否會(huì)猶豫一下,到底選char、nchar、varchar、nvarchar、text、ntext中哪一種呢?結(jié)果很可能是兩種,一種是節(jié)儉人士的選擇:最好是用定長(zhǎng)的,感覺(jué)比變長(zhǎng)能省些空間,而且處理起來(lái)會(huì)快些,無(wú)法定長(zhǎng)只好選用定長(zhǎng),并且將長(zhǎng)度設(shè)置盡可能地小;另一種是則是覺(jué)得無(wú)所謂,盡量用可變類型的,長(zhǎng)度盡量放大些。
鑒于現(xiàn)在硬件像蘿卜一樣便宜的大好形勢(shì),糾纏這樣的小問(wèn)題實(shí)在是沒(méi)多大意義,不過(guò)如果不弄清它,總覺(jué)得對(duì)不起勞累過(guò)度的CPU和硬盤(pán)。
下面開(kāi)始了(以下說(shuō)明只針對(duì)SqlServer有效):
1、當(dāng)使用非unicode時(shí)慎用以下這種查詢:
select f from t where f = N'xx'
原因:無(wú)法利用到索引,因?yàn)閿?shù)據(jù)庫(kù)會(huì)將f先轉(zhuǎn)換到unicode再和N'xx'比較
2、char 和相同長(zhǎng)度的varchar處理速度差不多(后面還有說(shuō)明)
3、varchar的長(zhǎng)度不會(huì)影響處理速度!!!(看后面解釋)
4、索引中列總長(zhǎng)度最多支持總為900字節(jié),所以長(zhǎng)度大于900的varchar、char和大于450的nvarchar,nchar將無(wú)法創(chuàng)建索引
5、text、ntext上是無(wú)法創(chuàng)建索引的
6、O/R Mapping中對(duì)應(yīng)實(shí)體的屬性類型一般是以string居多,用char[]的非常少,所以如果按mapping的合理性來(lái)說(shuō),可變長(zhǎng)度的類型更加吻合
7、一般基礎(chǔ)資料表中的name在實(shí)際查詢中基本上全部是使用like '%xx%'這種方式,而這種方式是無(wú)法利用索引的,所以如果對(duì)于此種字段,索引建了也白建
8、其它一些像remark的字段則是根本不需要查詢的,所以不需要索引
9、varchar的存放和string是一樣原理的,即length {block}這種方式,所以varchar的長(zhǎng)度和它實(shí)際占用空間是無(wú)關(guān)的
10、對(duì)于固定長(zhǎng)度的字段,是需要額外空間來(lái)存放NULL標(biāo)識(shí)的,所以如果一個(gè)char字段中出現(xiàn)非常多的NULL,那么很不幸,你的占用空間比沒(méi)有NULL的大(但這個(gè)大并不是大太多,因?yàn)镹ULL標(biāo)識(shí)是用bit存放的,可是如果你一行中只有你一個(gè)NULL需要標(biāo)識(shí),那么你就白白浪費(fèi)1byte空間了,罪過(guò)罪過(guò)!),這時(shí)候,你可以使用特殊標(biāo)識(shí)來(lái)存放,如:'NV'
11、同上,所以對(duì)于這種NULL查詢,索引是無(wú)法生效的,假如你使用了NULL標(biāo)識(shí)替代的話,那么恭喜你,你可以利用到索引了
12、char和varchar的比較成本是一樣的,現(xiàn)在關(guān)鍵就看它們的索引查找的成本了,因?yàn)椴檎也呗远家粯樱虼藨?yīng)該比較誰(shuí)占用空間小。在存放相同數(shù)量的字符情況下,如果數(shù)量小,那么char占用長(zhǎng)度是小于varchar的,但如果數(shù)量稍大,則varchar完全可能小于char,而且要看實(shí)際填充數(shù)值的充實(shí)度,比如說(shuō)varchar(3)和char(3),那么理論上應(yīng)該是char快了,但如果是char(10)和varchar(10),充實(shí)度只有30%的情況下,理論上就應(yīng)該是varchar快了。因?yàn)関archar需要額外空間存放塊長(zhǎng)度,所以只要length(1-fillfactor)大于這個(gè)存放空間(好像是2字節(jié)),那么它就會(huì)比相同長(zhǎng)度的char快了。
13、nvarchar比varchar要慢上一些,而且對(duì)于非unicode字符它會(huì)占用雙倍的空間,那么這么一種類型推出來(lái)是為什么呢?對(duì),就是為了國(guó)際化,對(duì)于unicode類型的數(shù)據(jù),排序規(guī)則對(duì)它們是不起作用的,而非unicode字符在處理不同語(yǔ)言的數(shù)據(jù)時(shí),必須指定排序規(guī)則才能正常工作,所以n類型就這么一點(diǎn)好處。
總結(jié)陳詞:
1、如果數(shù)據(jù)量非常大,又能100%確定長(zhǎng)度且保存只是ansi字符,那么char
2、能確定長(zhǎng)度又不一定是ansi字符或者,那么用nchar;
3、不確定長(zhǎng)度,要查詢且希望利用索引的話,用nvarchar類型吧,將它們?cè)O(shè)到400;
4、不查詢的話沒(méi)什么好說(shuō)的,用nvarchar(4000)
5、性格豪爽的可以只用3和4,偶爾用用1,畢竟這是一種額外說(shuō)明,等于告訴別人說(shuō),我一定需要長(zhǎng)度為X位的數(shù)據(jù)
這樣一來(lái),生活是不是變成美好多了? 如果還有沒(méi)明白的,那么還是省點(diǎn)錢(qián)去買(mǎi)蘿卜吧。
小時(shí)候家的對(duì)面有一座山,山的上面就是藍(lán)天,所以總是幻想著有一天站到山頂用手摸一下藍(lán)天……
posted on 2008-04-14 22:21
丫丫 閱讀(3732)
評(píng)論(2) 編輯 收藏 所屬分類:
資料網(wǎng)摘