MySQL 數(shù)據(jù)表優(yōu)化設(shè)計(二):數(shù)值字段類型如何選擇?

在MySQL 中有兩種數(shù)值類型,整型和實數(shù)(即帶有小數(shù)的數(shù)字)。整型可以通過 TINYINT、SMALLINT、MEDIUMINT、INT 或 BIGINT 表示,分別對應(yīng)8bit、16bit、24bit、32bit 和64bit 的存儲空間。實數(shù)可以通過 FLOAT、DOUBLE 和 DECIMAL 表示,其中 FLOAT 和 DOUBLE 即通常所說的浮點數(shù),由于計算機二進制存儲的精度問題,其計算得到的是近似的結(jié)果。

整型字段類型設(shè)計

整型可以選擇是否是無符號數(shù),這樣可以禁止使用負數(shù),并且可以將存儲的最大值翻倍,例如 TINYINT UNSIGNED類型的字段可以存儲的值的范圍是0-255,而不是有符號的-128-127。使用無符號還是有符號取決與字段類型的范圍,但是如果確定字段是無符號的,那么優(yōu)先選擇無符號類型,因為最大值翻倍可以在一定程度上避免使用更大存儲空間的整型類型。

MySQL 允許我們指定整型的寬度,例如 INT(11)。這對于大部分應(yīng)用并沒有太大意義——實際上 MySQL 并不會限制合法值的范圍,也就是即便指定為 INT(11),實際上只要數(shù)值類型的存儲空間足夠,也可以存儲超過設(shè)定寬度的整型,例如 INT(12)的數(shù)字也可能可以存儲到 INT(11)類型的字段中。對于存儲和計算而言,INT(1)和 INT(20)是等效的。

如果確實要考慮性能,應(yīng)該是根據(jù)業(yè)務(wù)真實的數(shù)值范圍來確定使用整型字段類型,原則是只要字段類型不會超過業(yè)務(wù)系統(tǒng)的數(shù)值最大值,那么盡可能地選擇低存儲長度的整型類型。如果是無符號的數(shù)值,那就盡量使用無符號屬性。例如,假設(shè)使用整型替代枚舉的話,如果枚舉數(shù)量不超過255個,那就優(yōu)先使用 UNSIGNED TINYINT 類型。

實數(shù)

實數(shù)不僅僅可以用來存儲浮點數(shù),實際上還可以使用 DECIMAL 類型來存儲超出 BIGINT 類型的數(shù)值。對于 浮點數(shù),MySQL 支持精確浮點數(shù)類型和不精確浮點數(shù)。

FLOAT 和 DOUBLE 類型支持標(biāo)準(zhǔn)數(shù)學(xué)運算的近似運算,浮點數(shù)的實際計算結(jié)果的精確度依賴于實現(xiàn)浮點數(shù)的平臺。DECIMAL 類型用于存儲精確的浮點數(shù),在 MySQL 5.0以后,DECIMAL 也支持精確的數(shù)學(xué)運算(更早的版本實際上是使用浮點數(shù)來進行 DECIMAL 運算的)。但是,由于 CPU 本身不能直接精確計算浮點數(shù),因此 DECIMAL 數(shù)據(jù)類型的計算速度會比浮點數(shù)要慢。

浮點數(shù)和 DECIMAL 都支持指定精度。DECIMAL 類型的可以分別指定小數(shù)點前后最大的數(shù)字位數(shù),這會影響數(shù)據(jù)列的存儲空間占用。MySQL5.0版本以后將數(shù)字位以二進制形式存儲(每9位數(shù)使用4個字節(jié)存儲)。例如 DECIMAL(18, 9)將在小數(shù)點兩側(cè)均為9位數(shù)字,算上小數(shù)點(占一個字節(jié)),總共需要9個字節(jié)來存儲。DECIMAL 最大的數(shù)字位數(shù)是65(包含小數(shù)位和整數(shù)位),例如下面的表表創(chuàng)建語句會報錯提示#1426 - Too-big precision 66 specified for 'number'. Maximum is 65.

CREATE TABLE t_numbers ( 
  id INT(11) AUTO_INCREMENT PRIMARY KEY, 
  number DECIMAL(66,1) 
);

對于 FLOAT 和 DOUBLE類型,也可以類似 DECIMAL 那種方式指定整數(shù)位和小數(shù)位來確定存儲范圍和精度。不同的長度會使得 MySQL默認(rèn)選擇不同的數(shù)據(jù)類型并使用近似值存儲數(shù)據(jù)。FLOAT 類型的存儲長度固定為4個字節(jié), DOUBLE 類型的存儲長度固定為8個字節(jié)。精度是不確定的,指定精度對存儲空間并沒有幫助,因此從計算準(zhǔn)確度考慮,建議是不要指定精度。在內(nèi)部計算的時候,MySQL 會選擇使用 DOUBLE類型計算 FLOAT 類型的數(shù)據(jù)。

由于 DECIMAL 占據(jù)的空間更大以及計算資源消耗也更大,因此建議只有在需要精確表示數(shù)值的情況下選擇使用 DECIMAL(例如金融數(shù)據(jù),如金額)。如果考慮計算性能,也可以考慮使用 BIGINT 來存儲精確的浮點數(shù),例如將金額統(tǒng)一乘以固定的倍數(shù)轉(zhuǎn)換為 BIGINT 進行運算,這種方式的計算效率和存儲空間都會更小。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,401評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,011評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,263評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,543評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,323評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,874評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,968評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,095評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,605評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,551評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,720評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,242評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 43,961評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,358評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,612評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,330評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,690評論 2 370

推薦閱讀更多精彩內(nèi)容