摘要:數(shù)據(jù)類型優(yōu)化作者的故事原本覺(jué)得數(shù)據(jù)類型是非常簡(jiǎn)單并十分基礎(chǔ)的知識(shí),認(rèn)為自己掌握的差不多了。數(shù)據(jù)類型存儲(chǔ)空間時(shí)間范圍個(gè)字節(jié)年年個(gè)字節(jié)年年通常情況下應(yīng)該盡量使用,相比于空間效率更高。
MySQL數(shù)據(jù)類型優(yōu)化 作者的故事
原本覺(jué)得mysql數(shù)據(jù)類型是非常簡(jiǎn)單并十分基礎(chǔ)的知識(shí),認(rèn)為自己掌握的差不多了。但經(jīng)過(guò)上一次的面試,才發(fā)現(xiàn)自己掌握的并不牢固,很多細(xì)節(jié)和原理并不知道。后來(lái)翻閱了《高性能mysql》這本書(shū),仔細(xì)閱讀了第四章Schema與數(shù)據(jù)類型優(yōu)化。因此,寫(xiě)這篇文章記錄和總結(jié)下,并加深理解。
選擇優(yōu)化的數(shù)據(jù)類型不管存儲(chǔ)哪幾種類型,以下幾個(gè)簡(jiǎn)單的原則都有助于做出更好的選擇
更小的通常更好
簡(jiǎn)單就好
盡量避免null
整數(shù)類型數(shù)據(jù)類型 | 存儲(chǔ)空間 |
---|---|
TINYINT | 8位 |
SMALLINT | 16位 |
MEDINUMINT | 24位 |
INT | 32位 |
BIGINT | 64位 |
取值范圍:-2^(N-1) ~ 2^(N-1)-1,N位存儲(chǔ)空間的位數(shù)。
整數(shù)類型有可選的UNSIGNED類型,表示不允許負(fù)值,這大致可以使正數(shù)的上限提高一倍。例如 TINYINT UNSIGNED可以存儲(chǔ)的范圍是0~255,而TINYINT的存儲(chǔ)范圍是-128~127。
有符號(hào)和無(wú)符號(hào)類型使用相同的存儲(chǔ)空間,并且具有相同的性能,因此可根據(jù)實(shí)際情況選擇合適的類型。
MySQL可以為整數(shù)類型指定寬度,例如INT(11),對(duì)大多數(shù)應(yīng)用是沒(méi)有意義的,他不會(huì)限制值的合法范圍,只是規(guī)定了MySQL的一些交互工具(如MySQL命令行客戶端)用來(lái)顯示字符的個(gè)數(shù)。對(duì)于存儲(chǔ)和計(jì)算來(lái)說(shuō),INT(1)和INT(20)是相同的。
實(shí)數(shù)類型浮點(diǎn)類型和DECIMAL類型都可以指定精度。
對(duì)于DECIMAL列,可以指定小數(shù)點(diǎn)前后所允許的最大位數(shù)。這會(huì)影響列的空間消耗。MySQL5.0和更高版本將數(shù)字打包保存到一個(gè)二進(jìn)制字符串中(每4個(gè)字節(jié)存9個(gè)數(shù)字)。例如DECIMAL(18,9)小數(shù)點(diǎn)兩邊各存儲(chǔ)9個(gè)數(shù)字,一共使用9個(gè)字節(jié),小數(shù)點(diǎn)前后各占4個(gè)字節(jié),小數(shù)點(diǎn)占1個(gè)字節(jié)。
浮點(diǎn)類型在存儲(chǔ)同樣的值時(shí),通常比DECIMAL使用更少的空間。FLOAT使用4個(gè)字節(jié),DOUBLE使用8個(gè)字節(jié),相比FLOAT有更高的精度和更大的范圍。
因?yàn)樾枰~外的空間和計(jì)算開(kāi)銷,所以應(yīng)該盡量只在對(duì)小數(shù)進(jìn)行精確計(jì)算時(shí)才使用DECIMAL,例如存儲(chǔ)財(cái)務(wù)數(shù)據(jù)。但是在數(shù)據(jù)量比較大的時(shí)候,可以考慮使用BIGINT代替DECIMAL,將要存儲(chǔ)的值根據(jù)小數(shù)的位數(shù)乘以相應(yīng)的倍數(shù)即可。
字符串類型VARCHAR和CHAR是最主要的字符串類型
VARCHARVARCHAR主要用于存儲(chǔ)可變長(zhǎng)字符串,他比定長(zhǎng)更節(jié)省空間。有一種情況例外,如果MySQL表使用ROW_FORMAT=FIXED創(chuàng)建的話,每一行都會(huì)定長(zhǎng)存儲(chǔ)。
VARCHAR需要使用1或2個(gè)額外字節(jié)存儲(chǔ)字符串的長(zhǎng)度,如果列的最大長(zhǎng)度<=255則使用1個(gè)字節(jié),否則使用2個(gè)字節(jié)。
VARCHAR節(jié)省了存儲(chǔ)空間,對(duì)性能也有好處。但是由于行是變長(zhǎng)的,在update時(shí)可能使行變得比原來(lái)更長(zhǎng),這就需要額外的工作。
適合用VARCHAR的場(chǎng)景:字符串列的最大長(zhǎng)度比平均長(zhǎng)度大很多;列的更新少。
CHAR類型是定長(zhǎng)的,適合存儲(chǔ)很短的字符串或者所有的值都接近同一個(gè)長(zhǎng)度。例如非常適合存儲(chǔ)密碼的MD5值。對(duì)于經(jīng)常變更的列,CHAR比VARCHAR更適合。
備注:使用VARCHAR(5)和VARCHAR(200)存儲(chǔ)hello的空間開(kāi)銷是一樣的,但是更長(zhǎng)的列會(huì)消耗更多的內(nèi)存,因?yàn)镸ySQL通常會(huì)分配固定大小的內(nèi)存塊來(lái)保存內(nèi)部值。最好的策略就是只分配真正需要的空間。
日期和時(shí)間類型MySQL可以使用很多類型來(lái)保存時(shí)間和日期,如YEAR和DATE,MySQL能存儲(chǔ)最小時(shí)間粒度為秒。
這里主要介紹2種相似的日期類型DATETIME和TIMESTAMP。
數(shù)據(jù)類型 | 存儲(chǔ)空間 | 時(shí)間范圍 |
---|---|---|
DATETIME | 8個(gè)字節(jié) | 1001年~9999年 |
TIMESTAMP | 4個(gè)字節(jié) | 1970年~2038年 |
通常情況下應(yīng)該盡量使用TIMESTAMP,相比于DATETIME空間效率更高。有的人會(huì)將unix時(shí)間戳存儲(chǔ)為整數(shù)值,但這不會(huì)帶來(lái)任何收益(除了特殊情況,如下),數(shù)據(jù)處理起來(lái)也不方便,因此不推薦這樣做。
對(duì)于需要存儲(chǔ)比秒更小粒度的日期和時(shí)間值情況,建議可以使用BIGINT類型存儲(chǔ)微秒級(jí)別的時(shí)間戳,或者使用DOUBLE存儲(chǔ)秒之后的小數(shù)部分。
總結(jié)本篇文章主要是介紹MySQL常用的數(shù)據(jù)類型,如有錯(cuò)誤或者不準(zhǔn)確的地方,歡迎交流。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/30881.html
摘要:要確保沒(méi)有低估需要存儲(chǔ)的值的范圍,更小是相對(duì)與數(shù)據(jù)類型的最大值范圍來(lái)講的。如果無(wú)法確定哪個(gè)數(shù)據(jù)類型是最好的,就選擇你認(rèn)為不會(huì)超過(guò)范圍的最小類型。整數(shù)類型有兩個(gè)類型的數(shù)字整數(shù)和實(shí)數(shù)。列默認(rèn)為,這與其他的數(shù)據(jù)類型不一樣。 簡(jiǎn)述 良好的邏輯設(shè)計(jì)和物理設(shè)計(jì)是高性能系統(tǒng)的基石,比如反范式設(shè)計(jì)可以加快某些類型的查詢同時(shí)也會(huì)影響另外一些類型的查詢效率,所以我們必須重視Mysql對(duì)于數(shù)據(jù)庫(kù)的設(shè)計(jì)(本...
摘要:要確保沒(méi)有低估需要存儲(chǔ)的值的范圍,更小是相對(duì)與數(shù)據(jù)類型的最大值范圍來(lái)講的。如果無(wú)法確定哪個(gè)數(shù)據(jù)類型是最好的,就選擇你認(rèn)為不會(huì)超過(guò)范圍的最小類型。整數(shù)類型有兩個(gè)類型的數(shù)字整數(shù)和實(shí)數(shù)。列默認(rèn)為,這與其他的數(shù)據(jù)類型不一樣。 簡(jiǎn)述 良好的邏輯設(shè)計(jì)和物理設(shè)計(jì)是高性能系統(tǒng)的基石,比如反范式設(shè)計(jì)可以加快某些類型的查詢同時(shí)也會(huì)影響另外一些類型的查詢效率,所以我們必須重視Mysql對(duì)于數(shù)據(jù)庫(kù)的設(shè)計(jì)(本...
閱讀 3371·2021-11-24 09:39
閱讀 2927·2021-10-12 10:20
閱讀 2001·2019-08-30 15:53
閱讀 3148·2019-08-30 14:14
閱讀 2663·2019-08-29 15:36
閱讀 1198·2019-08-29 14:11
閱讀 2065·2019-08-26 13:51
閱讀 3498·2019-08-26 13:23