久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

mysql的char,varchar,text,blob的幾點個人理解

 quasiceo 2014-05-19

mysql的char,varchar,text,blob的幾點個人理解

Submitted by wayswang on 2011, June 28, 10:18 AM. PHP+MySQL

Tags: mysql, char, varchar, text, blob

mysql的char,varchar,text,blob是幾個有聯(lián)系但是有有很大區(qū)別的字段類型,這算是mysql的基礎(chǔ)吧,,可是基礎(chǔ)沒有學(xué)好,,惡補一下。

先簡單的總結(jié)一下:

char:定長,,最大255個字符

varchar:變長,,最大65535個字符(既是單列的限制,,又是整行的限制)

text:變長,,有字符集的大對象,并根據(jù)字符集進行排序和校驗,,大小寫不敏感

blob:變長,,無字符集的二進制大對象,大小寫敏感

以下只是我個人的理解,才疏學(xué)淺,,望各路高人指點,。

我使用的引擎是myisam,,所以以下的探討是集中在myisam上的,。

首先解釋char,,char是項目中常用的字段類型之一,,它代表的含義是采用固定長度存儲數(shù)據(jù),,換句話說,,數(shù)據(jù)初始化的是就為該類型的字段分配固定長度的存儲空間,即使沒有達到存儲空間的長度,,實際占用的存儲空間也是定義時的長度,。舉個例子來說,,比如某字段 a     char(50),指定的長度是50個字符的存儲空間,,那么當(dāng)你存入一個字符:“abc”的時候,,實際上字符長度是3個字符,,但是占用的硬盤空間還是50個字符。很顯然,,char的缺點就出來了:浪費存儲空間,!但是同時char的優(yōu)點也顯示出來了:固定長度,,(索引)效率極高,不存在碎片,。

這里我們再探討一下char的存儲方式,雖然char會浪費極大的存儲空間,,但是你想過對于字符串的前后空格char是如何處理的嗎,?當(dāng)存儲的字符串沒有達到char的最大長度時,,字符串后面是不會以空格來填充的,,而且char會過濾字符串末端的空格然后存儲,而在比較字符串的時候又會自動空格填充到字符串的末端,。

好了,,對char有了了解以后,,對varchar的理解也就容易了。

varchar是存儲可變長度的字符串,,簡單的說我們定義表機構(gòu)的時候指定的字段長度是最大長度,,當(dāng)字符串沒有達到最大長度的時候以字符串的實際長度來存儲的,不占用多余的存儲空間,。因此,,一般情況下,varchar比char節(jié)省存儲空間,,但是也經(jīng)常有例外,,后面接著探討這個問題。

一個特殊的情況是創(chuàng)建表的時候采用ROW_FORMAT=FIXED選項(默認的是ROW_FORMAT=DYNAMIC),,那么mysql就會為每行數(shù)據(jù)分配固定長度的存儲空間,,當(dāng)然這是特例。不知道你有沒有想過:為什么有管理員愿意這樣做呢,?對varchar分配固定長度的存儲空間是有道理的,。舉一個常見的例子,假設(shè)采用DYNAMIC默認選項,,那么我們創(chuàng)建一個字段b  varchar(100),,現(xiàn)在我們插入一個只有10個字符的數(shù)據(jù):abcdefghij,很好,,只占用了10個字符的空間,,相比char節(jié)省了不少存儲空間。但是你想到問題了嗎,?比如某天以后你發(fā)現(xiàn)這個字段需要更新一下,,更新為20個字符的數(shù)據(jù):abcdefghijklmnopqrst,你知道數(shù)據(jù)庫該如何存儲嗎,?原先的存儲位置分配的只有10個字符的空間,,現(xiàn)在要存儲20個字符,小于長度限制(最大長度是100個字符),,問題就來了,,mysql會如何處理呢?這里接下來可能要探討mysql存儲層面的分頁機制或者拆分機制,,就不再繼續(xù)深入了,。總之無論mysql采取什么方式,,肯定會在磁盤上形成碎片,,久而久之形成的磁盤碎片對系統(tǒng)效率是一個致命的打擊,所以我們經(jīng)??吹接泄芾韱T要把mysql導(dǎo)出然后導(dǎo)入,,就是為了解決這個問題,,提高效率。

上面我們提出來了一個問題:varchar比char節(jié)省存儲空間,,但是也經(jīng)常有例外,!對于這個疑問我們?nèi)绾卫斫饽兀恳钊敕治鲞@個問題,,我們需要再次深入了解varchar的存儲機制,。常用的中文存儲一般采用gbk或者utf-8兩種字符集,gbk每個字符占2個字節(jié),,utf-8每個字符占3個字節(jié),所以:gbk字符集的最大存儲長度是

(65535-1-1)/2= 32766或者(65535-1-2)/2= 32766,,這個算法的含義是:65535是varchar的最大長度,,第一個-1表示實際存儲位置是從第二位開始的,第二個-1或者-2代表的含義是:varchar 字段是將實際內(nèi)容單獨存儲在聚簇索引之外,,內(nèi)容開頭用1到2個字節(jié)表示實際長度(長度小于255時用1個字節(jié),,長度超過255時需要2個字節(jié)),除以2的原因是一個gbk字符集的字符占2個字節(jié)長度,,所以根據(jù)情況可以得出gbk字符集的最大存儲長度是32766,。

那么UTF-8字符集呢?算法如下:

(65535-1-1)/3=  21844或者(65535-1-2)/3= 21844減1減2的含義同上,,除以3的含義是一個utf-8的字符集字符占用實際長度是3個字節(jié),。

看完了這段你就能理解char(1)和varchar(1)占用的存儲空間了吧?在這個極端情況下,,很顯然char更節(jié)省存儲空間,,因為char沒有管理數(shù)據(jù)的額外開銷。

 

接下來,,我們重點探討一下varchar的65535存儲長度代表的真正含義是什么,?因為前面說過一句話:既是單列的限制,又是整行的限制,!我們詳細來解釋一下,。對于單列的限制,我們舉一個例子:create table tablename(c varchar(N)) charset=gbk;那么N的最大值是(65535-1-2)=32766,。同時,,如果同一個有其他字段的話,那么所有字段的長度和不能超過65535,,舉個例子:create table tablename(c1 int(4), c2 char(30), c3 varchar(N) ) charset=utf8,,那么N的最大值是(65535-1-2-4-30*3)/3=21812,也許你很理解int(4)需要4個字符的位置,,這里可能需要更深入的了解int的存儲機制,,我不太了解,,書還沒有看呢??傊甶nt類型占用4個字符的長度,,換句話說create table tablename(c1 int(32), c2 char(30), c3 varchar(N) ) charset=utf8,N的最大值也是(65535-1-2-4-30*3)/3=21812,。我做了一個簡單的實驗,,看截圖。

第一張varchar的長度大于21812,,于是失敗了

大小: 89.39 K
尺寸: 550 x 264
瀏覽: 17 次
點擊打開新窗口瀏覽全圖

第二張varchar長度等于21812,,保存成功

大小: 58.9 K
尺寸: 550 x 334
瀏覽: 20 次
點擊打開新窗口瀏覽全圖

 轉(zhuǎn)載請注明來源:www.

 廢話了這么多,總之一句話:char在浪費存儲空間的劣勢下,,獲得了較高的效率,,varchar相反。接下來我們也要總結(jié)一下什么情況下使用char,,什么情況下使用varchar,。

原則一:根據(jù)字符串長度確定,凡是固定長度的字符串或者類似固定長度的字符串一律用char,。比如身份證號碼,,手機號碼,銀行卡號,,MD5,,哈希值等這是字符串是固定長度的,毫無疑問用char,,還有一類是基本固定長度但是略有出入的,,比如中國人的姓名等,一般長度可能是2~5個漢字,,這類信息也非常適合用char來存儲,,只要分配一些略大于通常長度即可。

原則二:數(shù)據(jù)是否經(jīng)常更改導(dǎo)致碎片,,可能經(jīng)常變動而產(chǎn)生存儲碎片的小字符串一律用char,。我們知道char類型的數(shù)據(jù)是一次性分配存儲空間的,無論以后你怎么修改,,數(shù)據(jù)始終在該存儲空間內(nèi)的,,不會產(chǎn)生碎片。而varchar則不同,,varchar的數(shù)據(jù)長度是可變的,,當(dāng)修改后的數(shù)據(jù)大于當(dāng)前存儲長度時,就會產(chǎn)生碎片,如果該應(yīng)用是反復(fù)修改數(shù)據(jù)的應(yīng)用,,那么久而久之就是產(chǎn)生無數(shù)碎片,,效率可想而知。

原則三:理解varchar的存儲空間和內(nèi)存空間的區(qū)別,,合理指定varchar的長度,。我們知道varchar的存儲長度是根據(jù)字符串的長度而定的,但是運行時占用的內(nèi)存空間卻是按照定義的長度分配內(nèi)存空間的(我的理解,,不知道是否正確),。這個現(xiàn)象導(dǎo)致存儲一個字符串,比如通信地址,,通暢在100個字符內(nèi)就能存儲完成,,于是varchar(100)是一個合理的選擇,但是由于之前講的,,可能有人圖方便使用varchar(500),,反正用的存儲空間是一樣的,但是效果確實不一樣的,。在內(nèi)存模型中varchar(100)與varchar(500)是兩碼事,后者比前者占用多5倍的內(nèi)存空間,,在臨時表和排序的時候這個差別幾乎可能差一個數(shù)量級,,于是效率可想而知。

轉(zhuǎn)載注明來源:www.

 基本上解釋完char和varchar,,這里順帶看看Nchar和Nvarchar是什么,?

nvarchar表示可變長度 Unicode 數(shù)據(jù),其最大長度為 4,000 字符,;nchar表示固定長度的 Unicode 數(shù)據(jù),,最大長度為 4,000 個字符。

那Nchar和Nvarchar在什么情況下使用呢,?我們知道字符 中,,英文字符只需要一個字節(jié)存儲就足夠了,但漢字眾多,,需要兩個字節(jié)存儲,,英文與漢字同時存在時容易造成混亂,Unicode字符集就是為了解決字符集這 種不兼容的問題而產(chǎn)生的,,它所有的字符都用兩個字節(jié)表示,,即英文字符也是用兩個字節(jié)表示。于是支持多語言的站點應(yīng)考慮使用 Unicode nchar 或 nvarchar 數(shù)據(jù)類型以盡量減少字符轉(zhuǎn)換問題,。同樣的解釋還有下面我們要研討的NText,。

 

下面我們看看text和blob

 text分為4種類型:TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT,,分別對應(yīng)不同的長度,。text是非二進制字符串,并且需要指定字符集,,并按照該字符集進行校驗和排序,。只能存儲純文本,可以看作是VARCHAR在長度不足時的擴展,。

blob也分為4種類型:TINYBLOB,BLOB,mediumblob和LongBlob,,分別對應(yīng)不同的長度,blob存儲的是二進制數(shù)據(jù),,因此無需字符集校驗,,blob除了存儲文本信息外,由于二進制存儲格式,,所以還可以保存圖片等信息,,blob可以看作是VARBINARY在長度不足時的擴展。

 text和blob的各種類型存儲長度,,我們用如下的表格表示:

TinyBlob                             最大長度255個字元(2^8-1)  
TinyText                             最大長度255個字元(2^8-1)
Blob                                    最大長度65535個字元(2^16-1)
Text                                    最大長度65535個字元(2^16-1)
MediumBlob                         最大長度 16777215 個字元(2^24-1)
MediumText                         最大長度 16777215 個字元(2^24-1
LongBlob                              最大長度4294967295個字元 (2^32-1)
LongText                              最大長度4294967295個字元 (2^32-1)

 

 好了,,到此char,varchar,text,blob內(nèi)容探討基本完成了,下面是我再次復(fù)習(xí)一下有關(guān)int型數(shù)據(jù)的內(nèi)容,,列在這里方便對比,。

 

XML/HTML代碼
  1. · TINYINT——一個微小的整數(shù),支持 -128到127(SIGNED),,0到255(UNSIGNED),,需要1個字節(jié)存儲   
  2. · BIT——同TINYINT(1)   
  3. · BOOL——同TINYINT(1)   
  4. · SMALLINT——一個小整數(shù),支持 -32768到32767(SIGNED),,0到65535(UNSIGNED),,需要2個字節(jié)存儲 MEDIUMINT——一個中等整數(shù),支持 -8388608到8388607(SIGNED),,0到16777215(UNSIGNED),,需要3個字節(jié)存儲   
  5. · INT——一個整數(shù),支持 -2147493648到2147493647(SIGNED),,0到4294967295(UNSIGNED),,需要4個字節(jié)存儲   
  6. · INTEGER——同INT   
  7. · BIGINT——一個大整數(shù),支持 -9223372036854775808到9223372036854775807(SIGNED),,0到18446744073709551615(UNSIGNED),,需要8個字節(jié)存儲   
  8. · FLOAT(precision)——一個浮點數(shù)。precision<=24用于單精度浮點數(shù),;precision在25和53之間,,用于又精度浮點數(shù),。FLOAT(X)與相誚的FLOAT和DOUBLE類型有差相同的范圍,但是沒有定義顯示尺寸和小數(shù)位數(shù),。在MySQL3.23之前,,這不是一個真的浮點值,且總是有兩位小數(shù),。MySQL中的所有計算都用雙精度,,所以這會帶來一些意想不到的問題。   
  9. · FLOAT——一個小的菜單精度浮點數(shù),。支持 -3.402823466E+38到-1.175494351E-38,,0和1.175494351E-38 to 3.402823466E+38,需要4個字節(jié)存儲,。如果是UNSIGNED,,正數(shù)的范圍保持不變,但負數(shù)是不允許的,。   
  10. · DOUBLE——一個雙精度浮點數(shù),。支持 -1.7976931348623157E+308到-2.2250738585072014E-308,0和2.2250738585072014E-308到1.7976931348623157E+308,。如果是FLOAT,,UNSIGNED不會改變正數(shù)范圍,但負數(shù)是不允許的,。   
  11. · DOUBLE PRECISION——同DOUBLE   
  12. · REAL——同DOUBLE   
  13. · DECIMAL——將一個數(shù)像字符串那樣存儲,,每個字符占一個字節(jié)   
  14. · DEC——同DECIMAL   
  15. · NUMERIC——同DECIMAL   

 

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多