MySQL學習 - 數據類型的選擇
1. 類似的,數據類型間的,比較
1.1 原則上咱們但願你這樣去選擇數據類型
- 夠用的狀況下,越小越好
- 使用簡單的數據類型: 理論上MySQL內建類型處理起來更加方便,int會比varchar好處理
- 儘可能避免使用NULL: NULL的使用使得MySQL的優化比較難以執行下去
- 在你設計一張表的時候: 你最好先肯定大的類型例如int, 而後再去肯定小類型如int8
1.2 整數類型
- TINYINT / SMALLINT / ... / BIGINT 消耗的存儲空間逐漸變大
- 在它們前面加上 UNSIGNED 標誌能進一步將存儲能力加大一倍
- 涉及整數計算 最好使用 64 位的 BIGINT
- INT(11) 這種寫法大部分狀況下都沒什麼意義
- INT(11) 存儲能力 = INT(1)
- INT(11) 計算能力 = INT(1)
- 在Mysql一些客戶端中,有時候INT(11)會只顯示11字符
1.3 實數類型
- FLOAT[4] / DOUBLE[8] / DECIMAL(a,b) [ max(a,b) + 2 ]
- FLOAT / DOUBLE 是常見的單雙精度數據,計算過程由CPU本身實現
- DECIMAL類型的出現是爲了存更加精確的小數。 假設你精確到了必定程度,那麼CPU自己是沒有實現這種東西的計算過程的。
- 所以在MYSQL-5.0之前其實是由浮點數模擬的DECIMAL計算
故而可能會損失一些精度
- 5之後的版本MYSQL本身實現了DECIMAL計算
可是就快而言,天然是CPU自身實現計算會更快
- MYSQL自己存在一種機制,即便你自身指定了精度,可是實際存儲的過程當中仍是會作出一些取捨,能夠說是本身在悄悄優化,因此建議只指定類型,不要指定精度
1.4 字符串類型
- VARCHAR(變長) - 存儲的時候僅消耗一些必要的空間,可是會額外消耗1~2字節記錄長度
- 最好不要老是更新VARCHAR
- 假設變長了,可能致使內存頁內沒有更多空間存儲
- 假設變短了,可能出現一個沒法被利用的內存碎片
- 字符串長度波動幅度很是大的時候用,能佔到便宜
- CHAR(定長)
- MD5這樣的定長度值
- 由於長度不會變,所以內存利用效率更高
- VARCHAR & CHAR 具體是如何存儲的這要看存儲引擎怎麼決定
- 一些行爲諸如TRIM是由MYSQL數據庫決定的
- 若是真的按照你說的,VARCHAR只作必要的開銷,那麼VARCHAR(5) == VARCHAR(200)嗎
1.5 枚舉ENUM類型
- 假設如今有三種字符串A/B/C,在使用ENUM的狀況下實際存儲的時候會變成1/2/3。在對這一列進行排序的時候,也是按照1/2/3的方式進行排序的。
- 很差的地方:
- 排序的時候須要使用FILED( )來指定排序,不然就會按照1/2/3排序
- 由於ENUM的candidate是固定的,所以但凡想要作出一些修改,最大的可能就是ALTER TABLE
- 由於實際存儲的時候是按照1/2/3存儲的,所以轉換存在一些開銷,好在大部分時候這個映射表並不大,所以開銷也不是很大
- 好的地方:
- 假設某個屬性成爲了主鍵的一部分,面臨一些作聯表的可能,在聯表的時候,作過ENUM映射的表,聯的時候會比單純的字符串快不少
- 在使用 SHOW TABLE STATUS 展現表當前狀態的時候使用ENUM會比使用字符串 data_length 更低
1.6 日期時間類型
- DATETIME: 日期+時間
- TIMESTAMP: UNIX時間,開銷更小
- 與時區相關,好比TS=0在美國就會比在英國晚5小時
1.7 標識符 / 索引
- 標識符有點像一個鍵,能夠用來惟一的肯定一列
- 最好的選擇是使用整數類型做爲標識符。 與之相對的是避免使用字符串做爲標識符,由於它們會很消耗空間,大部分時候也挺慢
- 避免使用UUID - MD5 - SHA1等隨機字符串做爲索引,這些值會隨意分佈在很大空間內,從而致使INSERT SELECT 變慢
- 所謂的 "隨意分佈" / "很大空間" 是指咱們在索引生成之後,SHA1隨機生成的新值頗有可能會插入其中,變慢。 帶來的其餘影響則包含: 頁的中間插入 -> 頁分裂 / 磁盤隨機寫入行爲
- 徹底隨機字符串會致使 -> 內容寫入到內存塊徹底隨機的地方上,邏輯上相鄰的行事實上相距很是遠,從而致使SELECT變慢
- 內存訪問上有一種說法叫 "局部性原理", 內存里老是有一小片很"熱",老是被訪問,這種時候咱們選擇緩存這一小片,下次訪問緩存就頗有可能直接拿到想要的數據,總體是快的不行。 如今隨機數來了,全部地方都是同樣"熱",我緩存哪兒?我緩存哪兒對我都沒有明顯的好處
2. 設計一張表你最好這樣 :
(接下來可能會反覆補充設計表的一些東西)html
2.1 設計表的時候儘可能避免這些
- 包含有太多列
- 枚舉映射表太長
- 過多使用NULL, 儘可能避免使用null
- 你可使用一些符號代替 -1,0 均可以
- 可是使用NULL也表明必定是壞事,若是你的表裏有太多不可能發生的數字自己也很差
2.2 範式 & 反範式
- 使用範式
- 好處:
- 若是沒有範式這種東西,表內有太多冗餘的信息,你不能說他們是錯誤信息,只是太多餘,然而在你嘗試更新一個字段的時候,哪怕你忘記更新其中一處,這些冗餘信息就會變成錯誤信息
- 使用範式的狀況下更新屬性一般更清爽也更快
- 範式化的表一般更小,所以能直接把整表塞進內存,查詢很快
- 缺點:
- 使用反範式
- 總結
- 實際上純範式化的數據庫 & 純反範式化的數據庫都只是理論上的說說,生產環境下我認爲應該仍是酌情,以及結合數據庫測試的表現來講
- 例如你如今有user + message 表, 其中有個字段叫作 account_name_chinese,按照範式這個字段只應該在user表裏出現,可是message也會常常須要它,你能夠在數據庫的測試中的表現下,酌情使用
- 可是像如今針對 這個字段的更新,你須要更新兩張表,這也是你須要考量的點,你會不會常常更新它? 你能接受一次更新兩張表嗎?
- 避免這種問題,使用trigger解決這種麻煩事 ( 什麼是 trigger )
2.3 該不應用視圖
- 什麼是視圖:
- 什麼是物化視圖: 預先計算好的表,會根據一些手段更新
歡迎關注本站公眾號,獲取更多信息