MySQL數據庫詳解:揭祕億級高併發數據庫調優與最佳實踐法則

作業務,要懂基本的SQL語句;

作性能優化,要懂索引,懂引擎;mysql

作分庫分表,要懂主從,懂讀寫分離...面試

數據庫的使用,是開發人員的基本功,對它掌握越清晰越深刻,你能作的事情就越多。sql

今天咱們用10分鐘,重點梳理一遍如下幾方面:數據庫

數據庫知識點彙總;
數據庫事務特性和隔離級別;
詳解關係型數據庫、索引與鎖機制;
數據庫調優與最佳實踐;
面試考察點及加分項。

知識點彙總

在這裏插入圖片描述

1、數據庫的不一樣類型

1.經常使用的關係型數據庫緩存

  • Oracle:功能強大,主要缺點就是貴
  • MySQL:互聯網行業中最流行的數據庫,這不只僅是由於MySQL的免費。能夠說關係數據庫場景中你須要的功能,MySQL都能很好的知足,後面詳解部分會詳細介紹MySQL的一些知識點
  • MariaDB:是MySQL的分支,由開源社區維護,MariaDB雖然被看做MySQL的替代品,但它在擴展功能、存儲引擎上都有很是好的改進
  • PostgreSQL:也叫PGSQL,PGSQL相似於Oracle的多進程框架,能夠支持高併發的應用場景,PG幾乎支持全部的SQL標準,支持類型至關豐富。PG更加適合嚴格的企業應用場景,而MySQL更適合業務邏輯相對簡單、數據可靠性要求較低的互聯網場景。

2.NoSQL數據庫(非關係型數據庫)性能優化

  • Redis:提供了持久化能力,支持多種數據類型。Redis適用於數據變化快且數據大小可預測的場景。
  • MongoDB:一個基於分佈式文件存儲的數據庫,將數據存儲爲一個文檔,數據結構由鍵值對組成。MongoDB比較適合表結構不明確,且數據結構可能不斷變化的場景,不適合有事務和複雜查詢的場景。
  • HBase:創建在HDFS,也就是Hadoop文件系統之上的分佈式面向列的數據庫。相似於谷歌的大表設計,HBase能夠提供快速隨機訪問海量結構化數據。在表中它由行排序,一個表有多個列族以及每個列族能夠有任意數量的列。
    HBase依賴HDFS能夠實現海量數據的可靠存儲,適用於數據量大,寫多讀少,不須要複雜查詢的場景。
  • Cassandra:一個高可靠的大規模分佈式存儲系統。支持分佈式的結構化Key-value存儲,以高可用性爲主要目標。適合寫多的場景,適合作一些簡單查詢,不適合用來作數據分析統計。
  • Pika:一個可持久化的大容量類Redis存儲服務,
    兼容五種主要數據結構的大部分命令。Pika使用磁盤存儲,主要解決Redis大容量存儲的成本問題。

3.NewSQL數據庫(新一代關係型數據庫)服務器

  • TiDB:開源的分佈式關係數據庫,幾乎徹底兼容MySQL,可以支持水平彈性擴展、ACID事務、標準SQL、MySQL語法和MySQL協議,具備數據強一致的高可用特性。既適合在線事務處理,也適合在線分析處理。
  • OceanBase:OceanBase是螞蟻金服的數據庫,OB是能夠知足金融級的可靠性和數據一致性要求的數據庫系統。當你須要使用事務,而且數據量比較大,就比較適合使用OB。不過目前OB已經商業化,再也不開源。
2、事物特性及事物類型

後面的詳解知識點會展開介紹數據結構

3、數據庫的範式

前關係數據庫有六種範式:第一範式、第二範式、第三範式、巴斯-科德範式(BCNF)、第四範式和第五範式。範式級別越高對數據表的要求越嚴格。併發

  • 第一範式要求最低,只要求表中字段不可用在拆分。
  • 第二範式在第一範式的基礎上要求每條記錄由主鍵惟一區分,記錄中全部屬性都依賴於主鍵。
  • 第三範式在第二範式的基礎上,要求全部屬性必須直接依賴主鍵,不容許間接依賴。

通常說來,數據庫只需知足第三範式就能夠了。框架

詳解知識點一:數據庫事務

知識點

▌1.數據庫事務特性

數據庫的特性是面試時考察頻率很是高的題目,共4個特性:

  • 原子性:是指事務由原子的操做序列組成,全部操做要麼所有成功,要麼所有失敗回滾。
  • 一致性:是指事務的執行不能破壞數據庫數據的完整性和一致性,一個事務在執行以前和執行以後,數據庫都必須處以一致性狀態。好比在作多表操做時,多個表要麼都是事務後新的值,要麼都是事務前的舊值。
  • 隔離性:是指多個用戶併發訪問數據庫時,數據庫爲每一個用戶執行的事務,不能被其餘事務的操做所幹擾,多個併發事務之間要相互隔離。事務的隔離級別咱們稍後介紹。
  • 持久性:是指一個事務一旦提交併執行成功,那麼對數據庫中數據的改變就是永久性的,即使是在數據庫系統遇到故障的狀況下也不會丟失提交事務的操做。

▌2.事物併發問題與隔離級別
在這裏插入圖片描述
a.事務併發問題

  • 髒讀:髒讀是指在一個事務處理過程裏讀取了另外一個未提交的事務中的數據,例如,帳戶A轉賬給B500元,B餘額增長後但事務尚未提交完成,此時若是另外的請求中獲取的是B增長後的餘額,這就發生了髒讀,由於事務若是失敗回滾時,B的餘額就不該該增長。
  • 不可重複讀:不可重複讀是指對於數據庫中某個數據,一個事務範圍內屢次查詢返回了不一樣的數據值,這是因爲在屢次查詢之間,有其餘事務修改了數據並進行了提交。
  • 幻讀:是指一個事務中執行兩次徹底相同的查詢時,第二次查詢所返回的結果集跟第一個查詢不相同。與不可重複讀的區別在於,不可重複讀是對同一條記錄,兩次讀取的值不一樣。而幻讀是記錄的增長或刪除,致使兩次相同條件獲取的結果記錄數不一樣。

b:事務的四種隔離級別

能夠用於解決這幾種併發問題。如圖右面,由上到下的4種隔離級別由低到高。

  • 級別1讀未提交:也就是能夠讀取到其餘事務未提交的內容,這是最低的隔離級別,這個隔離級別下,前面提到的三種併發問題都有可能發生。
  • 級別2讀已提交:就是隻能讀取到其餘事務已經提交的數據。這個隔離級別能夠解決髒讀問題。
  • 級別三可重複讀:能夠保證整個事務過程當中,對同數據的屢次讀取結果是相同的。這個級別能夠解決髒讀和不可重複讀的問題。MySQL默認的隔離級別就是可重複讀。
  • 級別四串行化:這是最高的隔離級別,全部事務操做都依次順序執行。這個級別會致使併發度降低,性能最差。不過這個級別能夠解決前面提到的全部併發問題。

▌3.事務分類
在這裏插入圖片描述
共分5大類:

  • 扁平化事務:在扁平事務中,全部的操做都在同一層次,這也是咱們平時使用最多的一種事務。它的主要限制是不能提交或者回滾事務的某一部分,要麼都成功,要麼都回滾。
  • 帶保存點的扁平事務:爲了解決第一種事務的弊端,就有了第二種帶保存點的扁平事務。它容許事務在執行過程當中回滾到較早的狀態,而不是所有回滾。經過在事務中插入保存點,當操做失敗後,能夠選擇回滾到最近的保存點處。
  • 鏈事務:能夠看作是第二種事務的變種。它在事務提交時,會將必要的上下文隱式傳遞給下一個事務,當事務失敗時就能夠回滾到最近的事務。不過,鏈事務只能回滾到最近的保存點,而帶保存點的扁平化事務是能夠回滾到任意的保存點。
  • 嵌套事務:由頂層事務和子事務構成,相似於樹的結構。通常頂層事務負責邏輯管理,子事務負責具體的工做,子事務能夠提交,但真正提交要等到父事務提交,若是上層事務回滾,那麼全部的子事務都會回滾。
  • 分佈式事務:是指分佈式環境中的扁平化事務。

其中,經常使用的分佈式事務解決方案共4種

a.XA協議:是保證強一致性的剛性事務。實現方式有兩段式提交和三段式提交。兩段式提交須要有一個事務協調者來保證全部的事務參與者都完成了第一階段的準備工做。若是協調者收到全部參與者都準備好的消息,就會通知全部的事務執行第二階段提交。通常場景下兩段式提交已經可以很好得解決分佈式事務了,然而兩階段在即便只有一個進程發生故障時,也會致使整個系統存在較長時間的阻塞。三段式提交經過增長Pre-commit階段來減小前面提到的系統阻塞的時間。三段式提交不多在實際中使用,簡單瞭解就能夠了。

b.TCC:是知足最終一致性的柔性事務方案。TCC採用補償機制,核心思想是對每一個操做,都要註冊對應的確認和補償操做。它分爲三個階段:Try階段主要對業務系統進行檢測及資源預留;Confirm階段對業務系統作確認提交。Cancel階段是在業務執行錯誤,執行回滾,釋放預留的資源。

c.消息事務:第三種方案是消息一致性方案。基本思路是將本地操做和發送消息放在一個事務中,保證本地操做和消息發送要麼都成功要麼都失敗。下游應用訂閱消息,收到消息後執行對應操做。

d.GTS/Fescar:阿里雲中的全局事務服務GTS,對應的開源版本是Fescar。Fescar基於兩段式提交進行改良,剝離了分佈式事務方案對數據庫在協議支持上的要求。使用Fescar的前提是分支事務中涉及的資源,必須是支持ACID事務的關係型數據庫。分支的提交和回滾機制,都依賴於本地事務來保障。 Fescar的實現目前還存在一些侷限,好比事務隔離級別最高支持到讀已提交級別。

詳解知識點二:MySQL數據庫

在這裏插入圖片描述

▌1.經常使用SQL語句

須要能手寫經常使用SQL語句,這裏沒有什麼特殊的技巧,根據如圖列出的語句類型多作一些練習

▌2.數據類型

要知道MySQL都提供哪些基本都數據類型,不一樣數據類型佔用的空間大小。

▌3.MySQL中主要的存儲引擎

MyISAM是MySQL官方提供的存儲引擎,其特色是支持全文索引,查詢效率比較高,缺點是不支持事務、使用表級鎖。InnoDB在5.5版本後成爲了Mysql的默認存儲引擎,特色是支持ACID事務、支持外鍵、支持行級鎖提升了併發效率。TokuDB是第三方開發的開源存儲引擎,有很是快的寫速度,支持數據的壓縮存儲、能夠在線添加索引而不影響讀寫操做。可是由於壓縮的緣由,TokuDB很是適合訪問頻率不高的數據或歷史數據歸檔,不適合大量讀取的場景。

▌4.MySQL中的鎖

MyIASAM使用表級鎖,InnoDB使用行級鎖。表鎖開銷小,加鎖快,不會出現死鎖;可是鎖的粒度大,發生鎖衝突的機率高,併發訪問效率比較低。行級鎖開銷大,加鎖慢,有可能會出現死鎖,不過由於鎖定粒度最小,發生鎖衝突的機率低,併發訪問效率比較高。

注:

共享鎖也就是讀鎖,其餘事務能夠讀,但不能寫。MySQL能夠經過Lock In Share Mode語句顯示使用共享鎖。

排他鎖就是寫鎖,其餘事務不能讀取,也不能寫。對於Update、Delete和INSERT語句,InnoDB會自動給涉及的數據集加排他鎖,或者使用select for update顯示使用排他鎖。

▌5.索引

後文重點講解

▌6.MySQL的存儲過程與函數

存儲過程和函數均可以免開發人員重複編寫相同的SQL語句,而且存儲過程和函數都是在MySQL服務器中執行的,能夠減小客戶端和服務器端的數據傳輸。

存儲過程可以實現更復雜的功能,而函數通常用來實現針對性比較強的功能,例如特殊策略求和等。存儲過程能夠執行包括修改表等一系列數據庫操做,而用戶定義函數不能用於執行修改全局數據庫狀態的操做。

存儲過程通常是做爲一個獨立的部分來執行,而函數能夠做爲查詢語句的一個部分來調用。SQL語句中不能使用存儲過程,但可使用函數。

不過存儲過程通常與數據庫實現綁定,使用存儲過程會下降程序的可移植性,應謹慎使用。

▌7.新特性

能夠了解MySQL8.0的一些新特性,例如默認字符集格式改成了UTF8;增長了隱藏索引的功能,隱藏後的索引不會被查詢優化器使用,可使用這個特性用於性能調試;支持了通用表表達式,使複雜查詢中的嵌入表語句更加清晰;新增了窗口函數的概念,它能夠用來實現新的查詢方式。窗口函數與 SUM、COUNT等集合函數相似,但不會將多行查詢結果合併,而是將結果放在多行中。即窗口函數不須要GROUP BY。

▌8.MySQL調優

後文重點講解。

➔重點講解一:MySQL索引

在這裏插入圖片描述

索引能夠大幅增長數據庫的查詢的性能,在實際業務場景中,或多或少都會使用到。

可是索引是有以下2個代價的:

a.須要額外的磁盤空間來保存索引

b.對於插入、更新、刪除等操做因爲更新索引會增長額外的開銷

所以索引比較適合用在讀多寫少的場景。

▌1.MySQL索引類型

如左面的模塊,共分爲5類:

  • 惟一索引:就是索引列中的值必須是惟一的,可是容許出現空值。這種索引通常用來保證數據的惟一性,好比保存帳戶信息的表,每一個帳戶的id必須保證惟一,若是重複插入相同的帳戶id時會MySQL返回異常。
  • 主鍵索引:是一種特殊的惟一索引,可是它不容許出現空值。
  • 普通索引:與惟一索引不一樣,它容許索引列中存在相同的值。例如學生的成績表,各個學科的分數是容許重複的,就可使用普通索引。
  • 聯合索引:就是由多個列共同組成的索引。一個表中含有多個單列的索引並非聯合索引,聯合索引是對多個列字段按順序共同組成一個索引。應用聯合索引時須要注意最左原則,就是Where查詢條件中的字段必須與索引字段從左到右進行匹配。好比,一個用戶信息表,用姓名和年齡組成了聯合索引,若是查詢條件是姓名等於張三,那麼知足最左原則;若是查詢條件是年齡大於20,因爲索引中最左的字段是姓名不是年齡,因此不能使用這個索引。
  • 全文索引:前面提到了,MyISAM引擎中實現了這個索引,在5.6版本後InnoDB引擎也支持了全文索引,而且在5.7.6版本後支持了中文索引。全文索引只能在CHAR,VARCHAR,TEXT類型字段上使用,底層使用倒排索引實現。要注意對於大數據量的表,生成全文索引會很是消耗時間也很是消耗磁盤空間。

▌2.索引實現

如右面的模塊,索引實現共分4種形式:

B+樹實現:b+樹比較適合用做'>'或'<'這樣的範圍查詢,是MySQL中最常使用的一種索引實現。

R-tree:是一種用於處理多維數據的數據結構,能夠對地理數據進行空間索引。不過實際業務場景中使用的比較少。

Hash:是使用散列表來對數據進行索引,Hash方式不像Btree那樣須要屢次查詢才能定位到記錄,所以Hash索引的效率高於B-tree,可是不支持範圍查找和排序等功能.實際使用的也比較少。

FullText:就是咱們前面提到的全文索引,是一種記錄關鍵字與對應文檔關係的倒排索引。

➔重點講解二:MySQL調優

在這裏插入圖片描述

MySQL的調優也是研發人員須要掌握的一項技能

通常MySQL調優有圖中的4個緯度:

針對數據庫設計、表結構設計以及索引設置緯度進行的優化;

對業務中使用的SQL語句進行優化,例如調整Where查詢條件;

對mysql服務的配置進行優化,例如對連接數的管理,對索引緩存、查詢緩存、排序緩存等各類緩存大小進行優化;

對硬件設備和操做系統設置進行優化,例如調整操做系統參數、禁用Swap、增長內存、升級固態硬盤等等。

這四個緯度從優化的成本角度來說,從左到右優化成本逐漸升高;從優化效果角度來看,從右到左優化的效果更高。

對於研發人員來講,前兩個緯度與業務息息相關,所以須要重點掌握,後兩個緯度更適合DBA進行深刻學習,簡單瞭解就好。

本文將重點關注前兩個緯度

▌1.表結構和索引的優化

在這裏插入圖片描述

如左面的模塊,應該掌握以下6個原則:

第1個原則:要在設計表結構時,考慮數據庫的水平與垂直擴展能力,提早規劃好將來1年的數據量、讀寫量的增加,規劃好分庫分表方案。好比設計用戶信息表,預計1年後用戶數據10億條,寫QPS約5000,讀QPS30000,能夠設計按UID緯度進行散列,分爲4個庫每一個庫32張表,單表數據量控制在KW級別;

第2個原則:要爲字段選擇合適的數據類型,在保留擴展能力的前提下,優先選用較小的數據結構。例如保存年齡的字段,要使用TINYINT而不要使用INT;

第3個原則:能夠將字段多的表分解成多個表,必要時增長中間表進行關聯。假如一張表有四、50個字段顯然不是一個好的設計;

第4個原則:是設計關係數據庫時須要知足第三範式,但爲了知足第三範式,咱們可能會拆分出多張表。而在進行查詢時須要對多張表進行關聯查詢,有時爲了提升查詢效率,會下降範式的要求,在表中保存必定的冗餘信息,也叫作反範式。但要注意反範式必定要適度;

第5個原則:要擅用索引,好比爲常常做爲查詢條件的字段建立索引、建立聯合索引時要根據最左原則考慮索引的複用能力,不要重複建立索引;要爲保證數據不能重複的字段建立惟一索引等等。不過要注意索引對插入、更新等寫操做是有代價的,不要濫用索引。好比像性別這樣惟一不好的字段就不適合創建索引;

第6個原則:列字段儘可能設置爲Not Null,MySQL難以對使用Null的列進行查詢優化,容許Null會使索引、索引統計和值更加複雜。容許Null值的列須要更多的存儲空間,還須要MySQL內部進行特殊處理。

▌2.SQL語句進行優化的原則

如右面的模塊,共分5個原則:

  • 第1個原則:要找的最須要優化的SQL語句。要麼是使用最頻繁的語句,要麼是優化後提升最明顯的語句,能夠經過查詢MySQL的慢查詢日誌來發現須要進行優化的SQL語句;
  • 第2個原則:要學會利用MySQL提供的分析工具。例如使用Explain來分析語句的執行計劃,看看是否使用了索引,使用了哪一個索引,掃描了多少記錄,是否使用文件排序等等。或者利用Profile命令來分析某個語句執行過程當中各個分步的耗時;
  • 第3個原則:要注意使用查詢語句是要避免使用Select
    *,而是應該指定具體須要獲取的字段。緣由一是能夠避免查詢出不須要使用的字段,二是能夠避免查詢列字段的元信息;
  • 第4個原則:是儘可能使用Prepared Statements,一個是性能更好,另外一個是能夠防止SQL注入;
  • 第5個原則:是儘可能使用索引掃描來進行排序,也就是儘可能在有索引的字段上進行排序操做。

以上爲數據庫操做須掌握的內容,能夠進行差缺補漏,但願對研發人員有必定的幫助

面試考察點

1.必須瞭解數據庫的基本原理、使用場景以及經常使用隊列、數據庫的特色。MySQL提供了多種引擎能夠支持事務型與非事務型的關係對象庫服務等等。

2.要深入理解數據庫事務的ACID特性,瞭解併發事務可能致使的併發問題和不一樣的數據庫隔離級別如何解決這些併發問題。

3.要掌握經常使用的MySQL語句,好比WHERE條件查詢語句、JOIN關聯語句、ORDER BY排序語句等等。還要熟悉經常使用的自帶函數,例如SUM、COUNT等等。

4.要了解MySQL數據庫不一樣引擎的特色及不一樣類型的索引實現。好比最長使用的InnoDB很是擅長事務處理,MyISAM比較適合非事務的簡單查詢場景。好比知道MySQL的惟一索引、聯合索引、全文索引等不一樣索引類型,以及最長使用等B+樹索引實現等等。

面試加分項

1.要了解新特性,例如MySQL8.0中提供了窗口函數來支持新的查詢方式;支持通用表表達式,使複雜查詢中的嵌入表語句更加清晰等等。

2.要知道數據庫表設計原則,若是有過線上業務數據庫的設計經驗就更好了,你可以知道如何對容量進行評估,也知道適當分庫分表來保證將來服務的可擴展性,這會對面試起到積極的影響。

3.最好有過數據庫調優經驗,例如明明創建了索引的語句,可是查詢效率仍是很慢,經過Explain分析發現表中有多個索引,MySQL的優化器選用了錯誤的索引,致使查詢效率偏低,而後經過在SQL語句中使用Use
Index來指定索引解決。

以上內容摘取自《32個Java面試必考點》 第09講(下):MySQL調優與最佳實踐
主講人:新浪微博技術專家 張雷,點此瞭解更多

相關文章
相關標籤/搜索