MySQL (一) 數(shù)據(jù)類型優(yōu)化

整數(shù)類型:

TINYINT,SWALLINT, MEDIUMINT,INT,BIGINT. 分別是 8,16,24,32,64 位儲存空間隐岛。
整數(shù)型有 UNSIGNED 屬性猫妙,例如 TINYINT. UNSIGNRD 可以儲存的范圍是 0~255,TINYINT 儲存范圍是 -128~127. 儲存的空間是相同的聚凹。
使用最適合的類型吐咳。

實數(shù)類型:

FLOAT逻悠,DOUBLE元践,DECIMAL. 都可以指定精度韭脊,例如 DECIMAL(18,9) 小數(shù)兩邊各存儲9個數(shù)字,一共9個字節(jié)单旁,小數(shù)點前用 4 個字節(jié)沪羔,小數(shù)點后 4 個,小數(shù)點占一個象浑。
DECIMAL 允許最多 64 個數(shù)字蔫饰。計算的時候會轉(zhuǎn)換為 DOUNBLE 類型。
FLOAT 使用 4 個字節(jié)存儲愉豺。DOUBLE 占用 8 個字節(jié)篓吁。
盡量只在對小數(shù)進行精確計算的時候才使用 DECIMAL。在數(shù)據(jù)量比較大的時候蚪拦,可以考慮使用 BIGINT 代替 DECIMAL杖剪。

字符串類型

VARCHAR 和 CHAR 是主要的字符串類型。
VARCHAR 類型用于儲存可變長字符串驰贷,需要使用 1 或者 2 個額外字節(jié)記錄長度盛嘿,小于等于 255 字節(jié)用一個,大于用兩個括袒。字符串列的最大長度比平均長度大很多次兆;列的更新少,所以碎片不是問題锹锰;使用了像 UTF-8 這樣復(fù)雜的字符集芥炭,每個字符都使用不同的字節(jié)數(shù)存儲。

CHAR是定長的恃慧,適合存儲比較短的字符串园蝠,或者所有值都接近一個長度。非常短的列糕伐,單字符集砰琢。

與 CHAR 和 VARCHAR 類似的類型還有 BINARY 和 VARBINARY。它們儲存的是二進制字符串良瞧,它的儲存是字節(jié)碼不是字符陪汽,填充是 \0 不是空格。優(yōu)勢是大小寫敏感褥蚯,比較式每次按一個字節(jié)挚冤,比較快。

BLOB 和 TEXT 是為了存儲很大的數(shù)據(jù)而設(shè)計的字符串類型赞庶。
字符類型 TINTTEXT训挡,SMALLTEXT澳骤,TEXT,MEDIUNTEXT澜薄,LONGTEXT为肮;二進制類型 TINYBLOB,SMALLBLOB肤京,BLOB颊艳,MEDIUMBLOB,LONGNBLOB忘分。
BLOB 和 TEXT值太大的時候棋枕,InnoDB 會使用專門的“外部”存儲區(qū)來進行存儲,此時每個值在行內(nèi)需要 1~4 個字節(jié)存儲一個指針妒峦,外部存儲實際的值重斑。
BLOB 和 TEXT之間僅有的不同是 BLOB 是二進制數(shù)據(jù),沒有排序柜子或字符集肯骇,而 TEXT 類型有字符集和排序規(guī)則窥浪。

使用枚舉代替字符串類型
枚舉不好的地方是:字符串列表是固定的,添加刪除字符串必須使用 ALTER TABLE累盗。 對于一系列未來可能會改變的字符串寒矿,使用枚舉不是好主意。

日期和時間類型

DATATIME
從 1001 到 9999年 精度為秒若债。YYYYMMDDHHMMSS
TIMESTAMP
1970到2038年 只使用 4 個字節(jié)符相。
盡量使用 TIMESTAMP。

位數(shù)據(jù)類型

BIT
可以使用 BIT 列在一列中存儲一個或者多個 true/false 值蠢琳。最大長度是 64 個位啊终。當檢索 BIT(1)的時候,結(jié)果是一個包含二進制 0 或 1 值的字符串傲须,而不是 ASCII 碼的 “0” “1”蓝牲。然而在數(shù)字上下文場景的時候結(jié)果是將位字符串轉(zhuǎn)換為數(shù)字。
SET
如果要保存很多的 true/false 可以考慮合并這些列到一個 SET 泰讽。主要缺點例衍,改變列的定義需要 ALTER TABLE。一般也無法在 SET 列上通過索引查找已卸。
一種替代方式,使用一個整數(shù)包裝一系列的位佛玄。每一位代表一個 0/1。

選擇標識符

為標識列選擇合適的數(shù)據(jù)類型非常重要累澡,一般來說跟更有可能用標識列與其他值進行比較梦抢,標識列可能在另外的表作為外鍵使用,所以為標識列選擇數(shù)據(jù)類型的時候愧哟,應(yīng)該選擇跟關(guān)聯(lián)表中的對應(yīng)列一樣的類型奥吩。
整數(shù)通常是最好的選擇哼蛆,ENUM SET適合存儲固定信息,避免使用字符串類型霞赫。因為一些 SELECT 語句變的很慢腮介。

特殊類型數(shù)據(jù)

例如 IPv4 地址,經(jīng)常用 VARCHAR(15) 來儲存 IP 地址绩脆。是 32 位無符號整數(shù)萤厅,用小數(shù)點分為四段方便閱讀。不是字符串靴迫,MySQL 提供 INET_ATON() 和 INET_NTOA()函數(shù)在這兩種表示方法之間轉(zhuǎn)換。

MySQL schema 設(shè)計中的陷阱

太多的列
MySQL 的儲存引擎 API 工作時需要在服務(wù)器和儲存引擎之間通過行緩存格式拷貝數(shù)據(jù)楼誓,然后在服務(wù)器層將緩沖內(nèi)容解碼成各個列玉锌。說白了列越多轉(zhuǎn)換代價就會非常高。
太多的關(guān)聯(lián)
實體-屬性-值(EVA) 是常見的糟糕的設(shè)計模式疟羹,MySQL限制了每個關(guān)聯(lián)操作最多只能有61張表主守,EVA 需要許多自關(guān)聯(lián)。經(jīng)驗告訴我們榄融,單個查詢最好在12個表以內(nèi)做關(guān)聯(lián)参淫。
全能的枚舉
防止過度使用枚舉,如果枚舉值過多愧杯,應(yīng)當用整數(shù)作為外鍵關(guān)聯(lián)到字典表或者查找表來查找具體值涎才。
但是每增加一個枚舉值有需要 ALTER TABLE。

范式的優(yōu)點和缺點

范式化的更新操作通常比反范式化要快力九。
當數(shù)據(jù)較好地范式化時耍铜,就只有很少沒有重復(fù)的數(shù)據(jù),所以只需要修改更少的數(shù)據(jù)跌前。
范式化的表通常更小棕兼,可以更好的放在內(nèi)存里,所以執(zhí)行操作會更快抵乓。
很少有多余的數(shù)據(jù)意味著檢索列表數(shù)據(jù)時更少需要 DISTINCT 或者 GROUP BY 語句伴挚。

缺點是通常需要關(guān)聯(lián)。

反范式的優(yōu)點和缺點

很好地避免了關(guān)聯(lián)灾炭。

在實際應(yīng)用當中都是混用范式化和反范式化的茎芋。
最常見的反范式化的數(shù)據(jù)方法是復(fù)制或者緩存,在不同的表中存儲相同的特定列咆贬,可以使用觸發(fā)器更新緩存值败徊。
網(wǎng)站實例中,可以再 user 和 message 中都儲存 account_type 字段掏缎,避免了完全反范式化的插入和刪除問題皱蹦,不會吧 user_message 表搞的太大煤杀,有利于高效的獲取數(shù)據(jù)。但是更新用戶的賬戶類型操作代價就高了沪哺,這需要考慮更新的頻率以及更新的時長沈自,并和執(zhí)行 SELECT 查詢的頻率進行比較。
如果需要顯示每個用戶發(fā)了多少消息辜妓,可以再 user 表中建一個 num_message 列枯途,每當用戶發(fā)消息就更新這個表。

緩存表和匯總表

有時提升性能最好的方法是在同一張表中保存衍生冗余數(shù)據(jù)籍滴,有時也需要創(chuàng)建一張完全獨立的匯總表和緩存表酪夷。
緩存表儲存那些可以比較簡單地從 schema 其他表(但每次獲取的速度比較慢)數(shù)據(jù)的表
匯總表保存的是使用 GROUP BY 語句聚合數(shù)據(jù)的表。 緩存表對優(yōu)化搜索和檢索查詢語句很有效孽惰。

當重建匯總表和緩存表示需要一個影子表晚岭。

加快 ALTER TABLE 操作的速度

對于常見的場景,只有兩種:一是先在一臺不提供服務(wù)的機器上執(zhí)行 ALTER TALBLE 操作勋功,然后和提供服務(wù)的主庫進行切換坦报。另一種是,影子拷貝狂鞋,是用要求的表結(jié)構(gòu)創(chuàng)建一張和源表不管的新表片择,然后通過重命名和刪除操作叫喚兩張表。
一些場景中骚揍,可以通過 ALTER COLUMN 操作來改變列的值字管,這樣只會修改.frm文件。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末疏咐,一起剝皮案震驚了整個濱河市纤掸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌浑塞,老刑警劉巖借跪,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異酌壕,居然都是意外死亡掏愁,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門卵牍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來果港,“玉大人,你說我怎么就攤上這事糊昙⌒谅樱” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長萝衩。 經(jīng)常有香客問我回挽,道長,這世上最難降的妖魔是什么猩谊? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任千劈,我火速辦了婚禮,結(jié)果婚禮上牌捷,老公的妹妹穿的比我還像新娘墙牌。我一直安慰自己,他們只是感情好暗甥,可當我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布喜滨。 她就那樣靜靜地躺著,像睡著了一般淋袖。 火紅的嫁衣襯著肌膚如雪鸿市。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天即碗,我揣著相機與錄音,去河邊找鬼陌凳。 笑死剥懒,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的合敦。 我是一名探鬼主播初橘,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼充岛!你這毒婦竟也來了保檐?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤崔梗,失蹤者是張志新(化名)和其女友劉穎夜只,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蒜魄,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡扔亥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了谈为。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片旅挤。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖伞鲫,靈堂內(nèi)的尸體忽然破棺而出粘茄,到底是詐尸還是另有隱情,我是刑警寧澤秕脓,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布柒瓣,位于F島的核電站儒搭,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏嘹朗。R本人自食惡果不足惜师妙,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望屹培。 院中可真熱鬧默穴,春花似錦、人聲如沸褪秀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽媒吗。三九已至仑氛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間闸英,已是汗流浹背锯岖。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留甫何,地道東北人出吹。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像辙喂,于是被迫代替她去往敵國和親捶牢。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,927評論 2 355

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