數據庫知識點總結1

當年肥工的DB課講的其實還挺好的...就用當時的筆記叭html

(因此當年爲何不整理呢?仍是懶叭mysql

 

關係數據庫的一些概念

完整性防止DB中存在不符合規定的數據(eg:性別只能是男或女)git

實體完整性:primary key中的屬性取值必須惟一且不能爲空github

參照完整性:若F是R的外碼(foreign key),K是S的主碼(primary key),F鏈接K。那麼對於R中的每一個元祖,R.F必須是 在S.K中出現過的值 或者 NULL算法

用戶定義的完整性:用戶本身在具體的DB中指定的約束(定義:NOT NULL / UNIQUE / CHECK)sql

觸發器:用於實現用戶定義的完整性        CREATE TRIGGER ON ... AFTER ...數據庫

存儲過程用SQL語句實現一些用戶定義的業務邏輯緩存

關係模型服務器

(略)網絡

 

SQL

(略)

 

索引

B+Tree

B Tree 指的是 Balance Tree,也就是平衡樹。平衡樹是一顆查找樹,而且全部葉子節點位於同一層。

B+ Tree 是基於 B Tree 和葉子節點順序訪問指針進行實現,它具備 B Tree 的平衡性,而且經過順序訪問指針來提升區間查詢的性能。

在 B+ Tree 中,一個節點中的 key 從左到右非遞減排列,若是某個指針的左右相鄰 key 分別是 keyi 和 keyi+1,且不爲 null,則該指針指向節點的全部 key 大於等於 keyi 且小於等於 keyi+1

進行查找操做時,首先在根節點進行二分查找,找到一個 key 所在的指針,而後遞歸地在指針所指向的節點進行查找。直到查找到葉子節點,而後在葉子節點上進行二分查找,找出 key 所對應的 data。

插入刪除操做會破壞平衡樹的平衡性,所以在插入刪除操做以後,須要對樹進行一個分裂、合併、旋轉等操做來維護平衡性。

與紅黑樹的比較

紅黑樹等平衡樹也能夠用來實現索引,可是文件系統及數據庫系統廣泛採用 B+ Tree 做爲索引結構,主要有如下兩個緣由:

(一)更少的查找次數

平衡樹查找操做的時間複雜度和樹高 h 相關,O(h)=O(logdN),其中 d 爲每一個節點的出度。

紅黑樹的出度爲 2,而 B+ Tree 的出度通常都很是大,因此紅黑樹的樹高 h 很明顯比 B+ Tree 大很是多,查找的次數也就更多。

(二)利用磁盤預讀特性

爲了減小磁盤 I/O 操做,磁盤每每不是嚴格按需讀取,而是每次都會預讀。預讀過程當中,磁盤進行順序讀取,順序讀取不須要進行磁盤尋道,而且只須要很短的磁盤旋轉時間,速度會很是快。

操做系統通常將內存和磁盤分割成固定大小的塊,每一塊稱爲一頁,內存與磁盤以頁爲單位交換數據。數據庫系統將索引的一個節點的大小設置爲頁的大小,使得一次 I/O 就能徹底載入一個節點。而且能夠利用預讀特性,相鄰的節點也可以被預先載入。

B+ Tree、LSM Tree:http://www.javashuo.com/article/p-dozobccc-kc.html

MYSQL:http://blog.codinglabs.org/articles/theory-of-mysql-index.html

Hash:http://www.javashuo.com/article/p-tmiclehe-cv.html

紅黑樹:https://www.jianshu.com/p/e136ec79235c

索引的優勢

  • 大大減小了服務器須要掃描的數據行數。
  • 幫助服務器避免進行排序和分組,以及避免建立臨時表(B+Tree 索引是有序的,能夠用於 ORDER BY 和 GROUP BY 操做。臨時表主要是在排序和分組過程當中建立,不須要排序和分組,也就不須要建立臨時表)。
  • 將隨機 I/O 變爲順序 I/O(B+Tree 索引是有序的,會將相鄰的數據都存儲在一塊兒)。

索引的使用條件

  • 對於很是小的表、大部分狀況下簡單的全表掃描比創建索引更高效;
  • 對於中到大型的表,索引就很是有效;
  • 可是對於特大型的表,創建和維護索引的代價將會隨之增加。這種狀況下,須要用到一種技術能夠直接區分出須要查詢的一組數據,而不是一條記錄一條記錄地匹配,例如可使用分區技術。

 

事務

咱們在寫Java程序,遇到併發問題時,會想到用鎖來解決。數據庫遇到併發問題怎麼解決呢?答案就是事務,事務的本質就是鎖和併發的結合體(能夠理解成在數據庫系統上執行的一個函數。好比在銀行數據庫中,把A的100元錢轉給B)

事務指的是知足 ACID 特性的一組操做,能夠經過 Commit 提交一個事務,也可使用 Rollback 進行回滾。一個事務包含了多個命令,服務器在執行事務期間,不會改去執行其它客戶端的命令請求。事務是併發控制的基本單位

事務中的多個命令被一次性發送給服務器,而不是一條一條發送,這種方式被稱爲流水線,它能夠減小客戶端與服務器之間的網絡通訊次數從而提高性能。

ACID特性

  • Atomicity    事務被視爲不可分割的最小單元,事務的全部操做要麼所有提交成功,要麼所有失敗回滾。回滾能夠用回滾日誌來實現,回滾日誌記錄着事務所執行的修改操做,在回滾時反向執行這些修改操做便可。
  • Consistency    數據庫在事務執行先後都保持一致性狀態。在一致性狀態下,全部事務對一個數據的讀取結果都是相同的。
  • Isolation    一個事務所作的修改在最終提交之前,對其它事務是不可見的。換句話說就是併發執行的事務不會相互影響,其對數據庫的影響和它們串行執行時同樣。
  • Durability    一旦事務提交,則其所作的修改將會永遠保存到數據庫中。即便系統發生崩潰,事務執行的結果也不能丟失。使用重作日誌來保證持久性。
  • 只有知足一致性,事務的執行結果纔是正確的。
  • 在無併發的狀況下,事務串行執行,隔離性必定可以知足。此時只要能知足原子性,就必定能知足一致性。
  • 在併發的狀況下,多個事務並行執行,事務不只要知足原子性,還須要知足隔離性,才能知足一致性。
  • 事務知足持久化是爲了能應對數據庫崩潰的狀況。
  • 併發控制技術保證了事務的隔離性,使數據庫的一致性狀態不會由於併發執行的操做被破壞。
  • 日誌恢復技術保證了事務的原子性,使一致性狀態不會因事務或系統故障被破壞。同時使已提交的對數據庫的修改不會因系統崩潰而丟失,保證了事務的持久性。

恢復

 

併發控制

事務是併發控制的基本單位。

併發一致性問題

在併發環境下,事務的隔離性很難保證,所以會出現不少併發一致性問題。解決方法是經過併發控制來保證隔離性。併發控制能夠經過封鎖來實現,可是封鎖操做須要用戶本身控制,至關複雜。數據庫管理系統提供了事務的隔離級別,讓用戶以一種更輕鬆的方式處理併發一致性問題。

併發控制主要技術:封鎖、時間戳、樂觀控制法、多版本併發控制等。

封鎖:至關於分佈式中的加鎖/解鎖。基本封鎖類型:排他鎖(X 鎖 / 寫鎖)、共享鎖(S 鎖 / 讀鎖)。

  • 寫鎖:對A加寫鎖以後,其餘事務不可再讀寫A
  • 讀鎖:對A加讀鎖以後,其餘事務只能讀A

封鎖協議:規定加鎖解鎖的規則

兩段鎖協議:全部事務必須分兩個階段對數據項加鎖/解鎖:

  • 準備階段:在對任何數據進行讀、寫操做以前,首先要申請並得到對該數據的封鎖(此時能夠申請任何鎖,但不能釋放鎖)
    • 具體實現中,在準備階段會有一個協調者,向參與者申請資源並鎖定資源,執行事務操做。可是並無commit或者rollback
  • 提交階段:在釋放一個封鎖以後,事務再也不申請和得到任何其餘封鎖(此時能夠釋聽任何鎖,但不能再申請鎖)
    • 這一步才真正commit或者rollback。若是協調者發現全部參與者都返回yes就commit,只要有一我的返回no就rollback

若併發執行的全部事務都遵循兩段鎖協議,則對這些事務的任何併發調度策略都是可串行化的。

可是對於分佈式事務,2pc有可能出現數據不一致的問題。若是要完全解決這一問題就要用paxos或者Raft了。

封鎖粒度:具體對哪一個對象加鎖

MySQL 中提供了兩種封鎖粒度:行級鎖以及表級鎖。
應該儘可能只鎖定須要修改的那部分數據,而不是全部的資源。鎖定的數據量越少,發生鎖爭用的可能就越小,系統的併發程度就越高。
可是加鎖須要消耗資源,鎖的各類操做(包括獲取鎖、釋放鎖、以及檢查鎖狀態)都會增長系統開銷。所以封鎖粒度越小,系統開銷就越大。
在選擇封鎖粒度時,須要在鎖開銷和併發程度之間作一個權衡。

活鎖:某個事務等待時間太長,可經過先來先服務的策略避免。

死鎖:事務永遠沒法完成,同OS中的死鎖

  • 預防:一次封鎖法(每一個事務必須一次將全部要使用的數據所有加鎖)、順序封鎖法;
  • 診斷:超時法、等待圖法;
  • 解除:撤銷處理死鎖代價最小的事務,並釋放此事務的全部的鎖,使其餘事務得以繼續運行下去。

可串行化調度:可串行性是併發事務正確調度的準則。表示併發調度的結果和徹底串行執行的結果是一致的。

隔離級別事務具備隔離性,理論上來講事務之間的執行不該該相互產生影響,其對數據庫的影響應該和它們串行執行時同樣。然而徹底的隔離性會致使系統併發性能很低,下降對資源的利用率,於是實際上對隔離性的要求會有所放寬,這也會必定程度形成對數據庫一致性要求下降。事務的隔離級別越低,可能出現的併發異常越多,可是一般而言系統能提供的併發能力越強。

  • 未提交讀(READ UNCOMMITTED):事務中的修改,即便沒有提交,對其它事務也是可見的。        最低級別,任何狀況都沒法保證。
  • 提交讀(READ COMMITTED):一個事務只能讀取已經提交的事務所作的修改。換句話說,一個事務所作的修改在提交以前對其它事務是不可見的。       可避免髒讀的發生
  • 可重複讀(REPEATABLE READ):保證在同一個事務中屢次讀取一樣數據的結果是同樣的。       可避免髒讀、不可重複讀的發生。
  • 可串行化(SERIALIZABLE):強制事務串行執行。須要加鎖實現,而其它隔離級別一般不須要。       可避免髒讀、不可重複讀、幻讀的發生。

MVCC

在分佈式數據庫中,爲了提升事務執行的並行度,會使用MVCC進行併發控制。MYSQL中就用MVCC進行併發控制

 

分佈式數據庫技術

切分

水平切分:水平切分又稱爲 Sharding,它是將同一個表中的記錄拆分到多個結構相同的表中。
當一個表的數據不斷增多時,Sharding 是必然的選擇,它能夠將數據分佈到集羣的不一樣節點上,從而緩存單個數據庫的壓力。

垂直切分:將一張表按列切分紅多個表,一般是按照列的關係密集程度進行切分,也能夠利用垂直切分將常常被使用的列和不常常被使用的列切分到不一樣的表中。
在數據庫的層面使用垂直切分將按數據庫中表的密集程度部署到不一樣的庫中,例如將原來的電商數據庫垂直切分紅商品數據庫、用戶數據庫等。

Sharding 策略
    哈希取模:hash(key) % N;
    範圍:能夠是 ID 範圍也能夠是時間範圍;
    映射表:使用單獨的一個數據庫來存儲映射關係。
Sharding 存在的問題
1. 事務問題    使用分佈式事務來解決,好比 XA 接口。
2. 鏈接    能夠將原來的鏈接分解成多個單表查詢,而後在用戶程序中進行鏈接。
3. ID 惟一性    使用全局惟一 ID(GUID)、爲每一個分片指定一個 ID 範圍、分佈式 ID 生成器 (如 Twitter 的 Snowflake 算法)

主從複製

主要涉及三個線程:binlog 線程、I/O 線程和 SQL 線程。

  • binlog 線程 :負責將主服務器上的數據更改寫入二進制日誌(Binary log)中。
  • I/O 線程 :負責從主服務器上讀取二進制日誌,並寫入從服務器的中繼日誌(Relay log)。
  • SQL 線程 :負責讀取中繼日誌,解析出主服務器已經執行的數據更改並在從服務器中重放(Replay)。

 

讀寫分離

主服務器處理寫操做以及實時性要求比較高的讀操做,而從服務器處理讀操做。讀寫分離能提升性能的緣由在於:

  • 主從服務器負責各自的讀和寫,極大程度緩解了鎖的爭用;
  • 從服務器可使用 MyISAM,提高查詢性能以及節約系統開銷;
  • 增長冗餘,提升可用性。

讀寫分離經常使用代理方式來實現,代理服務器接收應用層傳來的讀寫請求,而後決定轉發到哪一個服務器。

 

 

 

 

 


 

https://github.com/CyC2018/CS-Notes/blob/master/notes/%E6%95%B0%E6%8D%AE%E5%BA%93%E7%B3%BB%E7%BB%9F%E5%8E%9F%E7%90%86.md

https://github.com/huihut/interview#-%E6%95%B0%E6%8D%AE%E5%BA%93

https://github.com/CyC2018/CS-Notes/blob/master/notes/MySQL.md

https://github.com/CyC2018/CS-Notes/blob/master/notes/Redis.md

相關文章
相關標籤/搜索