程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> mysql在互聯網應用設計和開發中的注意事項

mysql在互聯網應用設計和開發中的注意事項

編輯:MySQL綜合教程

mysql在互聯網應用設計和開發中的注意事項


MySql是開源數據庫,在互聯網界非常受歡迎,有著極為廣泛的應用。這是由MySql的特點和互聯網公司的使用場景決定的。首先從MySql的特點上看,MySql簡單易用,有著極高的穩定性,同時簡單查詢時性能極高;MySql的功能很完備,常用的功能幾乎都有;開源,功能可自己定制,使用成本低廉;可以支持多種不同用途的存儲引擎,以應對不同的業務場景等。同時MySql又是脆弱的,一個復雜sql或者大表join就可能是MySql負載過重,資源耗盡。

互聯網公司往往有高並發、大數據量的特點,同時為了在和競品的競爭中占得先機,產品會不斷迭代,新產品不斷推出。從技術的角度講,面臨的問題往往很難預測;同時為了拉新用戶或者促銷,往往有大規模的運營推廣活動,例如著名的“雙十一”,活動期間訪問和交易流量往往是平時的幾倍甚至幾十倍,如果把系統容量擴展到活動的容量,因為平時的流量沒這麼大,會造成資源浪費;如果活動期間不擴展系統容量,系統又扛不住突增的流量,從技術的角度講,希望系統有伸縮能力,既能在活動期間擴容,可以應對突增的流量,又能在活動結束後縮容,不造成資源的浪費,所以互聯網公司往往對系統伸縮能力有著執著的追求。

結合MySql的特點和互聯網公司的特點,為什麼MySql會在互聯網界廣受歡迎呢,大體有以下幾點:
1. 免費:互聯網公司內部很多設施需要使用數據庫,有些系統會使用多個數據庫,如果使用強大的商用數據庫,按許可收費,成本高的驚人。國內互聯網公司往往走微利模式,創業前幾年幾乎沒有盈利能力,廣泛使用雖然強大但使用成本高昂的商用數據庫對絕大多數互聯網公司是不可承受之重,就算使用也往往只能在某些關鍵系統中使用;
2. 開源:互聯網公司面臨的場景和問題很復雜,如果依靠廠商提供技術支持,很難及時處理遇到的問題,影響自身業務的發展。而使用開源的mysql可以根據自身的業務特點和面臨的問題,自行開發需要的功能,解決資金的問題;
3. 互聯網公司普遍追求橫向擴展性:面臨高並發、大數據量難題時,互聯網公司普遍采用分庫分表的方式擴展容量,使用MySql時不需要考慮分庫時增加數據庫許可的成本;
4. 互聯網公司業務一般不復雜,而且讀遠多於寫,剛好是mysql擅長的場景;

在這裡提一下MySql的InnoDB存儲引擎。從MySql5.5之後,InnoDB成為默認的存儲引擎,InnoDB是個相當全面,而且均衡的存儲引擎,支持全面的ACID事務特性;引入行級鎖,大幅度提升了並發能力;使用MVCC方式也大幅提升並發性能;查詢性能與MyIsam相比並不差。

在互聯網公司高並發的場景下,對MySql的使用稍有失誤就可能讓MySql負載增加,速度降低,所以在設計和使用MySql時要比較小心,任何一個無用都可能帶來嚴重的後果。在高並發、大數據量的互聯網應用中,系統的擴展性是個至關重要的考量,基於這點考慮,往往把業務邏輯寫在容易擴展的應用代碼中,因為擴展數據庫的難度和代價遠遠大於擴展應用。只要應用是無狀態的,只要往應用集群中增加機器,應用就能線性擴展;而要擴展數據庫就就不得不做分庫分表了,而做分庫分表時不論是數據遷移,還是改造應用層或使用中間件都需要相當大的工作量。所以在設計互聯網應用時,在數據庫的設計和使用有相應的原則,下面就從核心設計原則和表,字段,索引的設計和使用Sql方面分別描述。

核心設計原則:

不要在數據庫裡做運算,不要使用存儲過程、觸發器等(原因:數據庫的擴展的能力遠不如應用程序強,一旦使用了存儲過程、觸發器,當數據庫遇到瓶頸,想擴展就非常難了。所以,設計互聯網應用時,在合適的地方做合適的事情。就讓數據庫做數據存儲和查詢吧,至於數據轉移、運算、業務邏輯都讓應用來做吧) 平衡范式和冗余。在互聯網應用中為了優化查詢性能,會將必要的信息冗余存放,冗余存儲的式違反了第三范式,在提高查詢性能的同時也會帶來數據一致性的問題,這需要在業務邏輯代碼中保證

在互聯網應用中,數據庫訪問頻率很高,CPU、內存、IO、網絡都是緊缺資源,因此在滿足業務的前提下,降低SQL尤其是高頻SQL的資源消耗就是個非常重要的優化原則了,在設計表結構時,應該考慮哪些是高頻執行的SQL從而采取針對性措施。

庫表設計原則:

單表字段數應控制在20個以內。一個表的字段越多,面臨的業務場景就會越復雜,面臨可能的變化也越多。當查詢時,也會因為需要過濾的字段過多,導致更多的IO消耗。這個原則也可以用另外用另外一種形式表達:拆分表中字段來分離冷熱數據。大字段和訪問頻率低的字段都會降低查詢的效率,分離冷熱數據後,能提示熱數據的訪問性能,降低IO消耗,提高緩存命中概率 控制表的數據量。當數據量超過千萬級別後,即使硬件性能強大,sql執行時間也會下降 選擇字段類型時,在滿足正確存儲業務數據要求的前提下,選擇最短的。越小的字段,訪問效率越高。不要使用TEXT、BLOB類型;不得不使用TEXT、BLOB類型時,拆分到單獨表中;用DECIMAL代替FLOAT和DOUBLE存儲精確浮點數;使用整數替代浮點數:比如用分為單位表示以元為單位的金額;使用數字或ENUM代替字符或字符串 如果可能的話所有字段均定義為not null,因為null值使索引失效。對於數據量比較大的表而言,索引失效時查詢將是災難性的低效

索引對於性能來說非常關鍵,尤其是數據量非常越大時。查詢時使用到索引可以減少查詢時掃描的數據量、避免排序、將隨機IO轉為順序IO。代價就是修改或刪除數據時,索引需要重新排序,降低了性能。索引還能使查詢條件命中的索引作為行鎖的條件

索引設計使用原則:

將索引建立在高區分度字段上。索引是按照字段內容排序的,如果字段值區分度不高,在索引中將有很多大段的相同值,用這樣的索引查詢時,過濾效果非常不明顯,所以不要在區分度低的字段上創建索引。字段值區分度高時可以根據查詢值迅速定位查詢結果,提示查詢效率 索引應該建立在短字段上。盡量不要建在長字符串上,如果不可避免,可以選擇字符串的開頭幾位。建立索引時要把字段內容保存到索引中,所以字段越長,索引占得硬盤空間也就越大,查詢時消耗的硬盤IO資源也就越大,耗時越長 創建復合索引時索引的列順序至關重要。查詢有多個條件時,適合使用復合索引查詢。如果有多種查詢組合條件,復合索引建立得當的話,復合索引可以復用。建立復合索引時,自個字段的順序仍然優先按照區分度,其次再考慮索引復用 不要在索引列上進行數學運算、函數運算(會使索引失效) 單張表中索引數量不超過5個,單個索引中的字段數不超過5個,通常將選擇性最高的列放在最前面。如果一個表的索引太多,最可能的原因是開始時這個表擔負了太多的職責,考慮將此表的職責拆分。

SQL使用原則:

拒絕大sql,盡可能不做表之間的join操作
原因:
 - mysql更擅長簡單查詢,尤其是單表主鍵或二級索引查詢;mysql一條sql只能使用一個cpu,有大表join的情況下,性能下降明顯
 - 大sql不僅慢,而且會大幅度降低數據庫的並發能力,甚至拖垮數據庫
 - 使用多條簡單sql,使緩存命中率更高,還可以使用多核
 - 高並發場景下,不要使用兩個或以上的表join
限制返回結果條數,否則返回滿足條件的所有記錄。大多數情況下這是不必要的,應用在處理返回的大量結果時可能崩潰 不要使用select *,只查詢需要的列
a、select * 消耗了更多的cpu,內存,io,網絡資源;
b、使用具體字段除了減少資源消耗,還減小了表增加字段時的影響; 避免關聯子查詢。mysql的關聯子查詢實現非常糟糕,除非有非常高深的優化功力,否則不要寫關聯子查詢。 避免負向查詢,不要使用NOT、!=、<>、!<、!>、NOT EXISTS、NOT IN、 NOT LIKE等。不能使用索引,導致全表掃描,效率低下。 避免使用count。除非是非常小的表,否則盡可能使用冗余字段計數或其他方式。 分頁時避免傳統的limit offset, size方式分頁。這種方式隨著偏移量大,性能越來越差,可以考慮把分頁轉換成條件查詢。 使用in代替or,in的值不超過200個。IN的效率(O(log n))比OR的效率(O(n))高很多。 使用預編譯的sql。使用預編譯的sql不僅能防sql注入攻擊,還可以避免mysql服務器編譯的開銷。

本文的內容相當比例來自附件的《MySql36條軍規》,並結合公司目前現狀做了補充和刪減。

                                                        杏樹林研發 劉亞輝

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved