Schema優(yōu)化之選擇整數(shù)木柬、實數(shù)皆串、字符串和日期時間等

選擇數(shù)據(jù)類型的原則

1.更小的通常更好:一般情況下,應該盡量使用可以正確存儲數(shù)據(jù)的最小數(shù)據(jù)類型眉枕。更小的數(shù)據(jù)類型通常更快恶复,因為它們占用更少的磁盤、內存和CPU緩存速挑,并且處理時需要的CPU周期也更少寂玲。

2.簡單就好:簡單數(shù)據(jù)類型的操作通常需要更少的CPU周期。例如梗摇,整型比字符操作代價更低拓哟,因為字符集和校對規(guī)則(排序規(guī)則)使字符比較比整型比較更復雜。這里有兩個例子:一個是應該使用MySQL內建的類型而不是字符串來存儲日期和時間伶授,另外一個是應該用整型存儲IP地址断序。

3.盡量避免NULL:如果查詢中包含可為NULL的列,對MySQL來說更難優(yōu)化糜烹,因為可為NULL的列使得索引統(tǒng)計和值比較都更復雜违诗。可為NULL的列會使用更多的存儲空間疮蹦,在MySQL利也需要特殊處理诸迟。當可為NULL的列被索引時,每個索引記錄需要一個額外的字節(jié),在MyISAM里甚至還可能導致固定大小的索引(例如只有一個整數(shù)列的索引)變成可變大小的索引阵苇。

InnoDB使用單獨的位(bit)存儲NULL值壁公,所以對于稀疏數(shù)據(jù)有很好的空間效率。


整數(shù)類型

TINYINT绅项,SMALLINT紊册,MEDIUMINT,INT快耿,BIGINT囊陡。分別使用8,16掀亥,24撞反,32,64位存儲空間搪花。它們可以存儲的值的范圍從-2的(N-1)次方到2的(N-1)次方減一遏片,其中N是存儲空間的位數(shù)。

整數(shù)類型有可選的UNSIGNED屬性鳍侣,表示不允許負值,這大致可以使正數(shù)的上限提高一倍吼拥。例如TINYINT UNSIGNED可以存儲的范圍是0~255倚聚,而TINYINT的存儲范圍是-128~127。因此可以根據(jù)實際情況選擇合適的類型凿可。

MySQL可以為整數(shù)類型制定寬度惑折,例如INT(11),對大多數(shù)應用這是沒有意義的:他不會限制值的合法范圍枯跑,只是規(guī)定了MySQL的一些交互工具(例如命令行)用來顯示字符個數(shù)惨驶。對于存儲和計算來說,INT(1)和INT(20)是相同的敛助。


實數(shù)類型

實數(shù)是帶有小數(shù)部分的數(shù)字粗卜。但是不只是為了存儲小數(shù),也可以用DECIMAL存儲比BIGINT還大的整數(shù)纳击。

FLOAT和DOUBLE類型支持使用標準的浮點運算進行近似計算续扔。DECIMAL類型用于存儲精確的小數(shù),并且它可以指定小數(shù)點前后的所允許的最大位數(shù)焕数。這會影響列的空間消耗纱昧。在較高的版本將會把數(shù)字打包保存到一個二進制字符串中(每4個字節(jié)存9個數(shù)字)。例如DECIMAL(18堡赔,9)小數(shù)點兩邊將各存儲9個數(shù)字识脆,一共使用9個字節(jié):小數(shù)點前的數(shù)字用4個字節(jié),小數(shù)點后的數(shù)字用4個字節(jié),小數(shù)點本身占1個字節(jié)灼捂。而DECIMAL類型允許最多65個數(shù)字离例,注意DECIMAL只是一種存儲格式,計算時會轉換為DOUBLE類型纵东。DOUBLE是MySQL內部計算類型粘招。

浮點類型在存儲同樣范圍的值時,通常比DECIMAL使用更少的空間偎球。FLOAT使用4個字節(jié)存儲洒扎。DOUBLE占用8個字節(jié),相比FLOAT有更高的精度和更大的范圍衰絮。

由于消耗問題袍冷。所以應該有小數(shù)精確計算時才用DECIMAL。另外猫牡,某些場合可以考慮用BIGINT代替DECIMAL胡诗,比如存儲財務數(shù)據(jù),可以將需要存儲的貨幣單位根據(jù)小數(shù)的位數(shù)乘以相應的倍數(shù)淌友,然后用BIGINT存儲煌恢。


字符串類型

VARCHAR和CHAR類型

VARCHAR:VARCHAR類型用于存儲可變長字符串,因此它僅使用必要的空間震庭,它比定長類型更節(jié)省空間瑰抵。VARCHAR需要使用1或2個額外字節(jié)記錄字符串的長度,如果列的最大長度小于或等于255字節(jié)器联,則只使用1個字節(jié)表示二汛,否則使用2個字節(jié)。

VARCHAR節(jié)省了存儲空間拨拓,所以對性能也有幫助肴颊。但是,由于行是變長的渣磷,在UPDATE時可能使行變得更長婿着,這就需要做額外的工作。如果一個行占用的空間增長醋界,并且在頁內沒有更多的空間可以存儲祟身,這種情況下,不同的存儲引擎的處理方式不一樣物独。例如MyISAM會將行拆成不同的片段存儲袜硫,InnoDB則需要分裂頁來使行可以放進頁內。這樣一來就會產(chǎn)生很多內存碎片挡篓。

根據(jù)上面的描述可以確定VARCHAR適合的情況:

1.字符串列的最大長度比平均長度大很多婉陷;

2.列的更新很少所以碎片不是問題帚称;

3.使用了像UTF-8這樣復雜的字符集,每個字符都使用不同的字節(jié)數(shù)進行存儲秽澳。


CHAR:CHAR類型是定長的闯睹,MySQL總是根據(jù)定義的字符串長度分配足夠的空間。當存儲CHAR值時担神,MySQL會刪除所有的末尾空格

1.CHAR適合存儲很短的字符串楼吃,或所有值都接近同一個長度。例如妄讯,CHAR非常適合存儲密碼的MD5值孩锡,因為這是一個定長的值。

2.對于經(jīng)常變更的數(shù)據(jù)亥贸,CHAR也比VARCHAR更好躬窜,因為定長的CHAR類型不容易產(chǎn)生碎片。

3.對于非常短的列炕置,CHAR也比VARCHAR在存儲空間上也更有效率荣挨。例如用CHAR(1)來存儲只有Y和N的值,如果采用單字符集只需一個字節(jié)朴摊,但是VARCHAR(1)卻需要兩個字節(jié)默垄,因為還有一個記錄長度的額外字節(jié)。

注:使用VARCHAR(5)和VARCHAR(200)存儲較小的數(shù)據(jù)時甚纲,雖然空間開銷一樣口锭,但是還是用VARCHAR(5)比較好。因為更長的列會消耗更多的內存贩疙,MySQL通常會分配固定大小的內存塊來保存內部值讹弯。所以最好的策略就是分配真正需要的空間况既。


日期和時間類型

DATETIME

這個類型能保存大范圍的值这溅,從1001年到9999年,精度為秒棒仍。他把日期和時間封裝到格式為YYYYMMDDHHMMSS的整數(shù)中悲靴,與時區(qū)無關。使用8個字節(jié)的存儲空間莫其。默認情況下癞尚,MySQL以一種可排序的格式顯示DATETIME值。

TIMESTAMP

保存了從1970年1月1日午夜以來的秒數(shù)乱陡。它只使用4個字節(jié)的存儲空間浇揩,因此它的范圍比DATETIME小的多。

TIMESTAMP顯示的值也依賴于時區(qū)憨颠,MySQL服務器胳徽、操作系統(tǒng)积锅,以及客戶端連接都有時區(qū)設置。

應該多用TIMESTAMP因為它比DATETIME空間效率更高养盗。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末缚陷,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子往核,更是在濱河造成了極大的恐慌箫爷,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件聂儒,死亡現(xiàn)場離奇詭異虎锚,居然都是意外死亡,警方通過查閱死者的電腦和手機薄货,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門翁都,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人谅猾,你說我怎么就攤上這事柄慰。” “怎么了税娜?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵坐搔,是天一觀的道長。 經(jīng)常有香客問我敬矩,道長概行,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任弧岳,我火速辦了婚禮凳忙,結果婚禮上,老公的妹妹穿的比我還像新娘禽炬。我一直安慰自己涧卵,他們只是感情好,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布腹尖。 她就那樣靜靜地躺著柳恐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪热幔。 梳的紋絲不亂的頭發(fā)上乐设,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機與錄音绎巨,去河邊找鬼近尚。 笑死,一個胖子當著我的面吹牛场勤,可吹牛的內容都是我干的戈锻。 我是一名探鬼主播介汹,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼舶沛!你這毒婦竟也來了嘹承?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤如庭,失蹤者是張志新(化名)和其女友劉穎叹卷,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體坪它,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡骤竹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了往毡。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蒙揣。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖开瞭,靈堂內的尸體忽然破棺而出懒震,到底是詐尸還是另有隱情,我是刑警寧澤嗤详,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布个扰,位于F島的核電站,受9級特大地震影響葱色,放射性物質發(fā)生泄漏递宅。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一苍狰、第九天 我趴在偏房一處隱蔽的房頂上張望办龄。 院中可真熱鬧,春花似錦淋昭、人聲如沸俐填。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽玷禽。三九已至赫段,卻和暖如春呀打,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背糯笙。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工贬丛, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人给涕。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓豺憔,卻偏偏與公主長得像额获,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子恭应,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內容

  • 什么是數(shù)據(jù)庫抄邀? 數(shù)據(jù)庫是存儲數(shù)據(jù)的集合的單獨的應用程序。每個數(shù)據(jù)庫具有一個或多個不同的API昼榛,用于創(chuàng)建境肾,訪問,管理...
    chen_000閱讀 4,030評論 0 19
  • MySQL5.6從零開始學 第一章 初始mysql 1.1數(shù)據(jù)庫基礎 數(shù)據(jù)庫是由一批數(shù)據(jù)構成的有序的集合胆屿,這些數(shù)據(jù)...
    星期四晚八點閱讀 1,136評論 0 4
  • MySQL技術內幕:SQL編程 姜承堯 第1章 SQL編程 >> B是由MySQL創(chuàng)始人之一Monty分支的一個版...
    沉默劍士閱讀 2,408評論 0 3
  • 良好的邏輯設計和物理設計是高性能的基石奥喻,應該根據(jù)系統(tǒng)將要執(zhí)行的查詢語句設計schema,但記住這往往需要權衡各種因...
    CaesarXia閱讀 1,346評論 0 3
  • 我遇到了一個在公眾號向我求助的女孩非迹,她說她生活得很絕望环鲤,自殺過好幾次,如果在廈門也過不下去憎兽,就在廈門再自殺吧冷离,結束...
    愛晚睡閱讀 583評論 1 3