天天看點

資料庫核心基礎

本文簡單介紹了資料庫通用的核心基礎以及和分布式的一些類比

(1)經常使用資料庫的疑問

經常使用資料庫,有一個疑問,假如在資料庫中輸入select * from table,那麼資料庫如何把這條語句識别成可執行狀态?

資料庫核心基礎

(2)資料庫内部解析主要步驟

SQL---->Parser

用戶端輸入一條SQL字元串後,例如select,create等語句,首先會進入Parser子產品,對于Parser子產品,使用者輸入的是一條字元串,經過Parser子產品會解析成資料庫能夠識别的狀态,它會申請結構體或者一個記憶體空間把字元串給存起來。

例如select * from tb1。Parser子產品會把這條SQL拆分成select、*、from、tb1,然後分别存入相應的記憶體空間中。

目前主要的Parser主要有兩個架構,分别是Yacc和Lex。

2.Parser--->Analyzer

經過Parser子產品的初步解析後轉換成語句,還要經過Analyzer進一步解析,例如tb1有哪些屬性,tb1是分區表還是非分區表,是視圖還是物化視圖。這些解析都會在Analyzer子產品中進行。如果Parser是文法解析器,那麼Analyzer子產品就是語義解析器。

3.Analyzer--->Query

經過了Analyzer子產品後,會進入Query子產品,Query子產品會把Analyzer子產品解析後的表達式或者表或者視圖定義轉化成内部可以識别的初步的樹結構,但這隻是一個初步的樹還沒有形成二叉樹等複雜結構。

4.Query--->Optimizer

Optimizer即所謂的優化器。在資料庫中輸入一條語句為什麼會走索引掃描,為什麼兩張表做join的時候為什麼會走hashjoin,這些都會Optimizer中決定。優化器會決定表的連接配接方式比如走索引還是順序掃描;如果是索引是走普通索引還是别的方式,是僅僅通路索引還是要通路實體表;而且優化器還會決定表的連接配接順序,n張表做連接配接是MergeJoin、嵌套循環連接配接還是hash連接配接。優化器決定這些連接配接的算法有兩種,動态規劃算法和遺傳算法。一般10張表以下的都是動态規劃算法,10張表以上的基本上是遺傳算法。計劃生成後如果表還有分區表的話需不需要根據表的連接配接條件對分區進行裁剪。

5.Optimizer--->Plan

Optimizer輸入的是Plan,Plan就是一個計劃樹,這個樹是二叉的形式。

(3)一些看法

可以看到從SQL到Parser到Analyzer到Optimizer生成Plan對比Hive也是生成計劃交給MapReduce來執行,是以資料庫的原理都是通用的。

資料庫核心基礎
資料庫核心基礎

(4)疑問又來了,得到Plan之後呢?

資料庫核心基礎

執行流程如下:

資料庫核心基礎

得到計劃後會交給執行器,首先執行器會進行初始化操作(Open),申請記憶體如給tc1+tc2這個表達式賦予一下函數,是用哪個函數來計算,根據tc1,tc2是int還是float分别選擇不同的函數進行計算。然後交給Next,Next會向下層去要資料。資料庫首先會向Access去取資料,Access裡面本身是沒有資料的,他會向底層存儲去取資料(Storage),Storage是一個子產品,但細分過後會分為sBuffer和sSF/OS,sBuffer代表一個記憶體塊,sSF代表緩存管理檔案。整個過程就是Next會向Access要一條元祖,Access沒有,它會向Storage去申請,但本身Storage也沒有,于是會找Buffer,Buffer會向記憶體中申請一段記憶體,然後把Buffer傳入SF,SF通知檔案系統打開檔案,檔案系統會檔案通過二級制的形式拷貝到Buffer中。Buffer中的檔案可能很多,但每次Access隻拿8K的資料,Access經過一些計算就會把8K中的一條元祖取出交給Next,此時Next拿到元祖會計算,如果滿足的話傳回給使用者,如果不滿足會循環去取,直到取完後進入Close退出。

(5)執行器總結以及和分布式的類比

通過類比分析Executor和Access屬于計算子產品,而Storage輸入檔案存儲子產品,這些可以和Hadoop相類比。

資料庫核心基礎

(6)執行器優化考慮圖

資料庫核心基礎