posts - 27,  comments - 37,  trackbacks - 0
          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類(lèi)型的實(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ù)類(lèi)型的字符。我們知道字符中,英文字符只需要一個(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ù)類(lèi)型時(shí)不用擔(dān)心輸入的字符是英文還是漢字,較為方便,但在存儲(chǔ)英文時(shí)數(shù)量上有些損失。
               所以一般來(lái)說(shuō),如果含有中文字符,用nchar/nvarchar,如果純英文和數(shù)字,用char/varchar。






          數(shù)據(jù)庫(kù)定義到char類(lèi)型的字段時(shí) char、nchar、varchar、nvarchar、text、ntext中哪一種呢
           數(shù)據(jù)庫(kù)定義到char類(lèi)型的字段時(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ú)所謂,盡量用可變類(lèi)型的,長(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ì)影響處理速度!!!(看后面解釋?zhuān)?

          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í)體的屬性類(lèi)型一般是以string居多,用char[]的非常少,所以如果按mapping的合理性來(lái)說(shuō),可變長(zhǎng)度的類(lèi)型更加吻合

          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)型推出來(lái)是為什么呢?對(duì),就是為了國(guó)際化,對(duì)于unicode類(lèi)型的數(shù)據(jù),排序規(guī)則對(duì)它們是不起作用的,而非unicode字符在處理不同語(yǔ)言的數(shù)據(jù)時(shí),必須指定排序規(guī)則才能正常工作,所以n類(lèi)型就這么一點(diǎn)好處。


          總結(jié)陳詞:
          1、如果數(shù)據(jù)量非常大,又能100%確定長(zhǎng)度且保存只是ansi字符,那么char
          2、能確定長(zhǎng)度又不一定是ansi字符或者,那么用nchar;
          3、不確定長(zhǎng)度,要查詢且希望利用索引的話,用nvarchar類(lèi)型吧,將它們?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 丫丫 閱讀(3731) 評(píng)論(2)  編輯  收藏 所屬分類(lèi): 資料網(wǎng)摘


          FeedBack:
          # re: SQL中char、varchar、text和nchar、nvarchar、ntext的區(qū)別
          2008-07-08 16:40 | ppxmdeng
          hehe,感覺(jué)好像是在坐辯護(hù)律師。不過(guò)內(nèi)容我覺(jué)得不錯(cuò)。Thank you   回復(fù)  更多評(píng)論
            
          # re: SQL中char、varchar、text和nchar、nvarchar、ntext的區(qū)別
          2014-08-06 17:38 | 12

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          <2014年8月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          31123456

          常用鏈接

          留言簿(1)

          隨筆分類(lèi)(25)

          隨筆檔案(27)

          文章分類(lèi)

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 比如县| 英山县| 海南省| 纳雍县| 手机| 铜山县| 温泉县| 宜兴市| 沙洋县| 彰武县| 贵溪市| 宕昌县| 洛扎县| 和静县| 军事| 华坪县| 门头沟区| 南城县| 山西省| 鄂伦春自治旗| 五家渠市| 昌吉市| 余干县| 定南县| 五峰| 镇康县| 宁化县| 黔西| 泰和县| 任丘市| 庆阳市| 太仓市| 山丹县| 长沙县| 齐齐哈尔市| 高青县| 湛江市| 漠河县| 遵义县| 舒城县| 田林县|