三種常見的MySQL數據庫設計最佳實踐
曾經有一位開發者說過一句話,很有道理:一個功能的實現,在數據量或并發量比較小的時候,怎么樣都可以,但一旦將數據量和并發量逐步擴大,問題就會逐步顯現出來了。
這篇文章,就帶大家梳理一下,在MySQL的數據庫表設計中常見的三類錯誤。
選擇適合數據類型和長度
當我們把一個表的ID列定義為INT數據類型時,那么就要思考一個問題,這個表的數據量是否會隨著業務的發展而快速增長。
當這個表只是一個簡單的配置表或基礎數據表時,設置為INT類型或許沒有問題。當一個表存儲的是歷史記錄或日志記錄時,數據量必然會隨著業務的發展而快速增長,該列的空間會很快被耗盡,導致系統部分功能不可用。
針對此種情況,可提前預測業務發展,將ID字段設置為BIGINT類型。
這一條規則不僅適用于數值類型,還適用于字符串類型。例如,如果試圖在一個VARCHAR(255) 的列中寫入一個包含300個字符的字符串,而MySQL正處于嚴格模式(Strict Mode,默認為開啟狀態),那么MySQL會返回錯誤并拒絕寫入。如果MySQL沒有開啟嚴格模式,超過長度的數據會被截斷,從而導致可能重要的數據丟失。
與數據不足問題相反,列數據的存儲空間過多也可能是問題所在。雖然不會像存儲空間不足的情況那樣嚴重,但過度預留空間會帶來存儲和性能方面的影響。
比如,假設我們需要存儲一個五位的編碼,這種情況可以使用 INT 數據類型(存儲 32 位整數)來存儲,但這樣分配的存儲遠遠超過實際需求。此時,使用 SMALLINT 會是更好的選擇,因為它存儲的是 16 位整數,足夠存儲這個五位的編碼。
存儲分配過多會引起的兩方面問題:
- 存儲空間:過度分配類型對單個字段來說存儲成本變化可能不是非常顯著,但對于大型表、高頻讀取或寫入的場景來說,會對磁盤 I/O 和緩存效率產生影響。
- 索引性能:當字段被用于索引時,字段的存儲類型大小直接影響索引的存儲和查詢性能。使用較小的數據類型能提高索引效率。
所以,在選擇數據類型時我們需要考慮:不僅要滿足當前數據量的需求,還要能支持未來潛在的增長。
缺失索引或冗余索引
索引在 MySQL 中通過構建一個經過優化的結構來加速數據訪問,使查詢更快地返回符合條件的數據。如果沒有利用索引,當執行未分頁或未定義LIMIT的查詢時,MySQL 會對表執行掃描操作。這意味著它會從表的第一行開始逐行讀取,直到找到匹配條件的所有行。如果某個被頻繁訪問的大表沒有使用索引,從表掃描會帶來巨大的性能損失。
但與此同時,如果索引過多也會帶來另一方面的問題。
創建的每個索引都會占用額外的存儲空間,因此冗余或未使用的索引會直接增加存儲成本。此外,當表中的數據被更新或插入時,MySQL 會更新這些索引及其相關統計信息,以確保索引的準確性。這可能是一項耗時的操作,可能導致不良的用戶體驗。
選擇合適的存儲結構
過去十多年,越來越多的公司選擇使用NoSQL來存儲半結構化數據,以滿足快速處理大量數據的需求。這類數據存儲已經有很多專業解決方案,但實際上 MySQL 在這方面也很有能力。當隔壁字段需要采用半結構化數據存儲,又沒必要引入NoSQL時,可考慮采用MySQL提供的能力來存儲。
大多數存儲在數據庫中的半結構化數據通常是以JSON的形式表示。最簡單的方式是將JSON字符串存儲在TEXT類型的列中,但這并不是最佳選擇。
MySQL支持一種專門用于存儲JSON的列類型:JSON。這種類型會將JSON數據以高效的二進制格式存儲。
使用JSON而非TEXT類型有兩個關鍵好處:
- 第一,最為廣泛使用的MySQL存儲引擎 InnoDB 原生支持基于JSON對象內容的查詢和過濾,這避免了在應用代碼中手動過濾結果的需求。
- 第二,MySQL還支持基于JSON數據創建索引,使得查詢更加高效,可以加速基于JSON數據返回結果的操作。
小結
有一定開發經驗的朋友都知道,數據庫是系統最容易形成性能瓶頸問題的點,因此,針對數據庫的設計和深思熟慮絕對是值得在前期投入的事。否則,一旦有大量線上數據,再進行修改將是一件非常復雜和有風險的事。希望這篇文章能夠為大家提供幫助,同時也能啟發大家去思考更多的數據庫設計優化。























