㈠ 怎樣將一個sql語句轉化為相應的語法樹
token就是把程序的語句進行類似分詞得到的單詞。
它是下步語法分析的輸入。
typedef struct Token
{
int label;
char name[buf];
int code;
}Token;
是一個結構體。
C語言中單詞可以分為
保留字,就是int,while等。
標識符,例如int m;m就是標識符。
數字,有整數和小數
字元,+,-,.,*,;等字元,其中也包括++,--,!=等。
label應該標識token的類型。
name表示的就是程序中對應的字元序列。例如:int等。
最後code的意思,看不出來。。。,不過個人認為,上面的兩項就可以表示
token的信息。
㈡ MySql中Sql的執行過程
如果查詢緩存沒有命中,那麼SQL請求會進入分析器,分析器是用來分辨SQL語句的執行目的,其執行過程大致分為兩步:
表1 語法分析關鍵字然後再通過語法規則解析,判斷輸入的SQL 語句是否滿足MySQL語法,並且生成圖5的語法樹。由SQL語句生成的四個單詞中,識別出兩個關鍵字,分別是select 和from。根據MySQL的語法Select 和 from之間對應的是fields 欄位,下面應該掛接username;在from後面跟隨的是Tables欄位,其下掛接的是userinfo。
優化器的作用是對SQL進行優化,生成最有的執行方案。如圖6所示,前面提到的SQL解析器通過語法分析和語法規則生成了SQL語法樹。這個語法樹作為優化器的輸入,而優化器(黃色的部分)包含了邏輯變換和代價優化兩部分的內容。在優化完成以後會生成SQL執行計劃作為整個優化過程的輸出,交給執行器在存儲引擎上執行。
所處的位置如上圖所示,這節的重點在優化器中的邏輯變換和代價優化上。
邏輯變換也就是在關系代數基礎上進行變換,其目的是為了化簡,同時保證SQL變化前後的結果一致,也就是邏輯變化並不會帶來結果集的變化。其主要包括以下幾個方面:
這樣講概念或許有些抽象,通過圖7 來看看邏輯變化如何在SQL中執行的吧。
如圖7所示,從上往下共有4個步驟:
1. 針對存在的SQL語句,首先通過「否定消除」,去掉條件判斷中的「NOT」。語句由原來的「or」轉換成「and」,並且大於小於符號進行變號。藍色部分為修改前的SQL,紅色是修改以後的SQL。2. 等值傳遞,這一步很好理解分別降」t2.a=9」 和」t2.b=5」分別替換掉SQL中對應的值。3. 接下來就是常量表達式計算,將「5+7」計算得到「12」。4. 最後是常量表達式計算後的化簡,將」9<=10」化簡為」true」帶入到最終的SQL表達式中完成優化。
代價優化是用來確定每個表,根據條件是否應用索引,應用哪個索引和確定多表連接的順序等問題。為了完成代價優化,需要找到一個代價最小的方案。因此,優化器是通過基於代價的計算方法來決定如何執行查詢的(Cost-based Optimization)。簡化的過程如下:
這里將配置操作的代價分為MySQL 服務層和MySQL 引擎層,MySQL 服務層主要是定義CPU的代價,而MySQL 引擎層主要定義IO代價。MySQL 5.7 引入了兩個系統表mysql.server_cost和mysql.engine_cost來分別配置這兩個層的代價。如下:MySQL 服務層代價保存在表server_cost中,其具體內容如下:
由上可以看出創建臨時表的代價是很高的,尤其是內部的myisam或innodb臨時表。MySQL 引擎層代價保存在表engine_cost中,其具體內容如下:
目前io_block_read_cost和memory_block_read_cost默認值均為1,實際生產中建議酌情調大memory_block_read_cost,特別是對普通硬碟的場景。MySQL會根據SQL查詢生成的查詢計劃中對應的操作從上面兩張代價表中查找對應的代價值,並且進行累加形成最終執行SQL計劃的代價。再將多種可能的執行計劃進行比較,選取最小代價的計劃執行。
當分析器生成查詢計劃,並且經過優化器以後,就到了執行器。執行器會選擇執行計劃開始執行,但在執行之前會校驗請求用戶是否擁有查詢的許可權,如果沒有許可權,就會返回錯誤信息,否則將會去調用MySQL引擎層的介面,執行對應的SQL語句並且返回結果。例如SQL:「SELECT * FROM userinfo WHERE username = 'Tom';「假設 「username「 欄位沒有設置索引,就會調用存儲引擎從第一條開始查,如果碰到了用戶名字是」 Tom「, 就將結果集返回,沒有查找到就查看下一行,重復上一步的操作,直到讀完整個表或者找到對應的記錄。需要注意SQL語句的執行順序並不是按照書寫順序來的,順序的定義會在分析器中做好,一般是按照如下順序:
如果命中的記錄比較多,應用會從MySql Server一批批獲取數據
本文從MySQL中SQL語句的執行過程作為切入點,首先介紹了查詢請求的執行流程,其中將MySQL的處理分為MySQL Server層和MySQL存儲引擎層。通過介紹SQL語句的流轉,引出了後面要介紹的5大組件,他們分別是:連接器、查詢緩存、分析器、優化器、執行器。後面的內容中對每個組件進行了詳細的介紹。連接器,負責身份認證和許可權鑒別;查詢緩存,將查詢的結果集進行緩存,提高查詢效率;分析器,對SQL語句執行語法分析和語法規則,生成語法樹和執行計劃;優化器,包括邏輯變換和代價優化;執行器,在檢查用戶許可權以後對數據進行逐條查詢,整個過程遵守SQL語句的執行順序。
㈢ mybatis中動態sql執行原理
解釋器模式: 初始化過程中構建出抽象語法樹,請求處理時根據參數對象解釋語法樹,生成sql語句。
工廠模式: 為動態標簽的處理方式創建工廠類(SqlTagHandlerFactory),根據標簽名稱獲取對應的處理方式。
策略模式: 將動態標簽處理方式抽象為介面,針對不同標簽有相應的實現類。解釋抽象語法樹時,定義統一的解釋流程,再調用標簽對應的處理方式完成解釋中的各個子環節
㈣ Hive入門概述
1.1 什麼是Hive
Hive:由Facebook開源用於解決海量結構化日誌的數據統計。
Hive是基於Hadoop的一個數據倉庫工具,可以將結構化的數據文件映射為一張表,並提供類SQL查詢功能。本質是:將HQL轉化成MapRece程序
Hive處理的數據存儲在HDFS
Hive分析數據底層的實現是MapRece
執行程序運行在Yarn上
1.2 Hive的優缺點
1.2.1 優點
操作介面採用類SQL語法,提供快速開發的能力(簡單、容易上手)。
避免了去寫MapRece,減少開發人員的學習成本。
Hive的執行延遲比較高,因此Hive常用於數據分析,對實時性要求不高的場合。
Hive優勢在於處理大數據,對於處理小數據沒有優勢,因為Hive的執行延遲比較高。
Hive支持用戶自定義函數,用戶可以根據自己的需求來實現自己的函數。
1.2.2 缺點
1.Hive的HQL表達能力有限
(1)迭代式演算法無法表達
(2)數據挖掘方面不擅長
2.Hive的效率比較低
(1)Hive自動生成的MapRece作業,通常情況下不夠智能化
(2)Hive調優比較困難,粒度較粗
1.3 Hive架構原理
1.用戶介面:Client
CLI(hive shell)、JDBC/ODBC(java訪問hive)、WEBUI(瀏覽器訪問hive)
2.元數據:Metastore
元數據包括:表名、表所屬的資料庫(默認是default)、表的擁有者、列/分區欄位、表的類型(是否是外部表)、表的數據所在目錄等;
默認存儲在自帶的derby資料庫中,推薦使用MySQL替代derby存儲Metastore
3.Hadoop
使用HDFS進行存儲,使用MapRece進行計算。
4.驅動器:Driver
(1)解析器(SQL Parser):將SQL字元串轉換成抽象語法樹AST,這一步一般都用第三方工具庫完成,比如antlr;對AST進行語法分析,比如表是否存在、欄位是否存在、SQL語義是否有誤。
(2)編譯器(Physical Plan):將AST編譯生成邏輯執行計劃。
(3)優化器(Query Optimizer):對邏輯執行計劃進行優化。
(4)執行器(Execution):把邏輯執行計劃轉換成可以運行的物理計劃。對於Hive來說,就是MR/Spark。
Hive通過給用戶提供的一系列交互介面,接收到用戶的指令(SQL),使用自己的Driver,結合元數據(MetaStore),將這些指令翻譯成MapRece,提交到Hadoop中執行,最後,將執行返回的結果輸出到用戶交互介面。
1.4 Hive和資料庫比較
由於 Hive 採用了類似SQL 的查詢語言 HQL(Hive Query Language),因此很容易將 Hive 理解為資料庫。其實從結構上來看,Hive 和資料庫除了擁有類似的查詢語言,再無類似之處。本文將從多個方面來闡述 Hive 和資料庫的差異。資料庫可以用在 Online 的應用中,但是Hive 是為數據倉庫而設計的,清楚這一點,有助於從應用角度理解 Hive 的特性。
1.4.1 查詢語言
由於SQL被廣泛的應用在數據倉庫中,因此,專門針對Hive的特性設計了類SQL的查詢語言HQL。熟悉SQL開發的開發者可以很方便的使用Hive進行開發。
1.4.2 數據存儲位置
Hive 是建立在 Hadoop 之上的,所有 Hive 的數據都是存儲在 HDFS 中的。而資料庫則可以將數據保存在塊設備或者本地文件系統中。
1.4.3 數據更新
由於Hive是針對數據倉庫應用設計的,而數據倉庫的內容是讀多寫少的。因此,Hive中不建議對數據的改寫,所有的數據都是在載入的時候確定好的。而資料庫中的數據通常是需要經常進行修改的,因此可以使用 INSERT INTO … VALUES 添加數據,使用 UPDATE … SET修改數據。
1.4.4 索引
Hive在載入數據的過程中不會對數據進行任何處理,甚至不會對數據進行掃描,因此也沒有對數據中的某些Key建立索引。Hive要訪問數據中滿足條件的特定值時,需要暴力掃描整個數據,因此訪問延遲較高。由於 MapRece 的引入, Hive 可以並行訪問數據,因此即使沒有索引,對於大數據量的訪問,Hive 仍然可以體現出優勢。資料庫中,通常會針對一個或者幾個列建立索引,因此對於少量的特定條件的數據的訪問,資料庫可以有很高的效率,較低的延遲。由於數據的訪問延遲較高,決定了 Hive 不適合在線數據查詢。
1.4.5 執行
Hive中大多數查詢的執行是通過 Hadoop 提供的 MapRece 來實現的。而資料庫通常有自己的執行引擎。
1.4.6 執行延遲
Hive 在查詢數據的時候,由於沒有索引,需要掃描整個表,因此延遲較高。另外一個導致 Hive 執行延遲高的因素是 MapRece框架。由於MapRece 本身具有較高的延遲,因此在利用MapRece 執行Hive查詢時,也會有較高的延遲。相對的,資料庫的執行延遲較低。當然,這個低是有條件的,即數據規模較小,當數據規模大到超過資料庫的處理能力的時候,Hive的並行計算顯然能體現出優勢。
1.4.7 可擴展性
由於Hive是建立在Hadoop之上的,因此Hive的可擴展性是和Hadoop的可擴展性是一致的(世界上最大的Hadoop 集群在 Yahoo!,2009年的規模在4000 台節點左右)。而資料庫由於 ACID 語義的嚴格限制,擴展行非常有限。目前最先進的並行資料庫 Oracle 在理論上的擴展能力也只有100台左右。
1.4.8 數據規模
由於Hive建立在集群上並可以利用MapRece進行並行計算,因此可以支持很大規模的數據;對應的,資料庫可以支持的數據規模較小。
㈤ Hive 怎麼將HQL轉換為MR作業
Shark為了實現Hive兼容,在HQL方面重用了Hive中HQL的解析、邏輯執行計劃翻譯、坦信羨執行計劃優化等邏輯,可以近似認為僅將物理執行計劃從MR作業替換成了Spark作業(輔以內存列式存儲等各種和Hive關系不大的優化);
同時還依賴Hive Metastore和Hive SerDe(用於兼容現有的各種Hive存儲格式)。這一策略導致了兩個問題,
第一是執行計劃優化完全依賴於Hive,不方便添加新的優化策略;
二是因為MR是進程級並行,寫代碼的時候不是很注意線程安全問題,導致Shark不得不使用另外一套獨立維護的打了補丁的Hive源碼分支(至於為何相關修改沒有合並到Hive主線,我也不太清楚)。
Spark SQL解決了這兩個問題。第一,坦顫Spark SQL在Hive兼容層面僅依賴HQL parser、Hive Metastore和Hive SerDe。也就是說,從HQL被解析成抽象語法樹(AST)起,就全部由Spark SQL接管了。執行計劃生成和優化都由Catalyst負責。藉助Scala的模式匹配等函數式語言特性,利用Catalyst開發讓拍執行計劃優化策略比Hive要簡潔得多。
㈥ flink血緣解析原理分析
參考dlink實現血緣解析程序流程圖
對於經過parse階段解析出的AST語法樹結果需要進行有效性校驗,SqlToOperationConverter.convert(planner, this.catalogManager, parsed)方法負責校驗sql語句,並將其轉為Operation。該方法內部首先會對解析後的SQL語法樹進行校驗。具體驗證的方面主要包括以下兩方面,1.表名、欄位名、函數名是否正確,如在某個查詢的欄位在當前SQL位置上是否存在或有歧義;2.特定類型操作自身的合法性,如group by聚合中的聚合函數是否存在嵌套調用,使用AS重命名時,新名字是否是x.y的形式等。使用flinkPlanner.validate(sqlNode)方法會拿到校驗後的SqlNode變數,會判斷SqlNode的類型,採用不同的轉換邏輯最終獲得需要的Operation對象。
rel階段是將SqlNode組成的一棵抽象語法樹轉化為一棵由RelNode和RexNode組成的關系代數樹,並且此階段只處理DML與DQL,因為DDL實際上可以認為是對元數睜態好據的修改,不涉及復雜關系查詢,也就不用進行關系代數轉換來優悉鉛化執行,所以也無需轉換為表示,根據對應的SqlNode中保存的信息已經可以直接執行了。對於DML語句會執行converter.convertSqlQuery(validated),該方法內部會先創建出Rel轉換器,由Calcite轉換為Relation tree,最終生成一個PlannerQueryOperation。將Calcite轉換成的reletional tree包裝在其中,對於轉換過程本身並不涉及很復雜的演算法,大部分過程都是提取已有SqlNode節點中記錄的信息,然後生成對應的RelNode和RexNode,並設置RelNode間的父子關系。
在Translate階段,通過Blink Planner 的translateToRel、optimize、StreamGraph和ObjectNode四個階段:將Operation轉換成 ObjectNode。從operation開始,先將ModifyOperation通過translateToRel方法閉橡轉換成Calcite RelNode邏輯計劃樹。在Explainer#translateObjectNode()方法內部可以會先將modifyOperations數組組裝出來,然後通過PlannerBase#translate(modifyOperations)方法獲取到Transformation數組。並將其作為參數傳入ExecutorUtils#generateStreamGraph()方法獲取到StreamGraph。在Executor#getStreamGraph()方法中通過使用JSONGenerator,ObjectMapper進行封裝最後返回ObjectNode。然後通過TransGenerator(plan).translateTrans()獲取ObjectNode里的節點信息最後組裝成Trans數組,以便後續得到最終的實體對象LineageColumnGenerator。
㈦ hive核心組件及流程(一)
依賴第三方組件: Meta store(mysql),hdfs,MapRece
hive:
Client客戶端 CLI、JDBC
Driver連接客戶端與服務端的橋梁
SQL Pareser解析器,將SQL轉換為抽象語法樹AST
1.將HQL語句轉換為Token
2.對Token進行解析,生成AST
Physical Plan編譯器將AST編譯生成邏激虛帆輯譽磨執行計劃
Query Optimizer優化器,對邏輯執行計劃進行優化
1.將AST轉換為QueryBlock
2.將QueryBlock轉換為OperatorTree
3.OperatorTree進行邏輯優化
4.生成TaskTree
5.TaskTree執行物理優化
Execution執行器把邏輯執行計劃轉換成可以運行的物理計劃
1.獲取MR臨時工作目錄
3.定義Mapper和Recer
2.定義Partitioner
4.實例化Job
5.提交Job
1.以Antlr定義的語法規則,對SQL完成詞法解析,將SQL轉換為AST
2.遍歷AST,抽象出查詢基本組成單元QueryBlock。
3.遍歷QueryBlock,將其轉換為OperatorTree,邏輯執行單元
4.利用邏輯優化器對OperatorTree進行邏輯優化。
5.遍歷OperatorTree轉換為TaskTree,將邏輯執行計劃轉化為物理執行計劃
6.使用物理優化器對TaskTree進行物理優化
7.生成最終的執行計劃,提交執行
$HIVE_HOME/bin/hive可以進入客戶端
$HIVE_HOME/bin/hive -e "{SQL語句}"可以執行SQL語句
$HIVE_HOME/bin/hive -f {SQL文件名.sql}可以執行sql文件
開啟hiveserver2服務,可以通過JDBC提交SQL
創建Driver
創建OptionsProcessor
初始化log4j
標准輸入輸出以及錯誤輸出流的定義,後續需要輸入 SQL 以及列印控制台信息
解析輸入的參數,包含"-e -f -v -database"
讀取輸入的sql
按照";"分割的方式解析
解析單行SQL
遇到為"quit"或者"exit"退出
遇到為"source"開頭,執行 SQL 文件,讀取文件並解析
如果命令以"!"開頭,則表示用戶需要執行 shell命令
以上三種都不是的情況下執行SQL,進行SQL解析
獲取當前系統時間
獲取系統結束時間
編譯SQL語句
SQL生成AST,構建詞法解析器,將關鍵詞替換為TOKEN,明雹進行語法解析,生成最終AST
處理AST,轉換為QueryBlock然後轉換為OperatorTree,對Operator進行邏輯優化,然後轉換為任務樹,然後進行物理優化。
根據任務樹構建MrJob
添加啟動任務,根據是否可以並行來決定是否並行啟動Task
設置MR任務的InputFormat、OutputFormat 等等這些 MRJob 的執行類
構建執行MR任務的命令
向yarn提交任務
列印頭信息
獲取結果集並獲取抓取到的條數
列印SQL執行時間及數據條數
㈧ sql關系代數表達式改為語法樹減法怎麼寫
首先先介紹概念,對於查詢處理,一般分為三個步驟:
對SQL語句進行語法分析,即將查詢語句轉換成按照某種有用方式表示查詢語句結構的語法樹
把語法分析樹轉換成關系代數表達式樹(或某種類似標記),一般稱之為邏輯查詢計劃
邏輯查詢計劃必須轉換成物理查詢計劃,物理查詢計劃不僅指明了要執行的操作,而且也找出了這些操作執行的順序、執行每步所用的演算法,獲得所存儲數據的方式以及數據從一個操作傳遞給另一個操作的方式,除此之外,還必須估計每個可能選項的預計代價。
以下是詳細的步驟。
查詢的編譯
1:語法分析與預處理
語法分析與語法分析樹
原子
語法類
SQL簡單子集的語法(語法分析)
查詢
㈨ 急求設計SQL語言的語法樹
看是用在asp中或是易語言中,abc是變數還是常量,另外是不是模糊查詢,這樣一來就要分好幾種情況了(以下代碼不含模糊查詢,如果要用需要加%號):
一、abc為常量
不分易語言和asp
如果欄位1-4是文本內容,sql語句如下:
"select
*
from
表1
where
欄位1
like
'abc'
and
欄位2
like
'abc'
and
欄位3
like
'abc'
and
欄位4
like
'abc'"
如果欄位1-4是數值內容,sql語句如下:
"select
*
from
表1
where
欄位1=abc
and
欄位2=abc
and
欄位3=abc
and
欄位4=abc"
二、abc為變數
如果欄位1-4是文本內容,sql語句如下:
asp中:
「select
*
from
表1
where
欄位1
like
'」&abc&"'
and
欄位2
like
'」&abc&"'and
欄位3
like
'」&abc&"'and
欄位4
like
'」&abc&"'"
易語言中:
」select
*
from
表1
where
欄位1
like
'「+abc+」'
and
欄位2
like
'「+abc+」'
and
欄位3
like
'「+abc+」'
and
欄位4
like
'「+abc+」'
"
如果欄位1-4是數值內容,sql語句如下:
asp中:
「select
*
from
表1
where
欄位1
=」&abc&"and
欄位2
=」&abc&"and
欄位3=」&abc&"and
欄位4=」&abc&"
易語言中:
「select
*
from
表1
where
欄位1
=」+abc+"and
欄位2
=」+abc+"and
欄位3=」+abc+"and
欄位4=」+abc+"
㈩ 如何獲取SQL2005下的SQL語句的語義分析
我想獲取一段sql語句在 mssql2005下解析成的語句,
主要是想獲取這個sql所用到的所有的表的名字。(ps:復雜的sql語句的)
請高手幫忙 在線等~
我的意思是要從用戶輸入的sql語句中提取該語句中所用的表
或者是:
sql 執行的步驟
1. 解析器
第 1 階段是解析器階段,它將 SQL 文本轉換成語法樹。這個階段不查找系統目錄中的任何信息,不訪問資料庫。
2. 語義分析
第 2 階段分析由解析器創建的語法樹,並產生用於查詢的查詢控制塊和表達式樹。要構建這些內部數據結構,它執行以下操作:
驗證對象
解析 UDR
如果可能的話,消除常量
驗證對象
第 2 階段訪問資料庫中不同的系統目錄,以驗證查詢所引用的所有資料庫對象(諸如表、列、視圖、類型、UDR 等等)是否都存在。它在資料庫中找到這些對象的標識,然後創建查詢控制塊和表達式樹。
我要的就是驗證對象步驟里的表的信息