学习RadonDB源码(三)
1. 所谓第四代语言
SQL是一种典型的第四代语言,即4GL,这种语言的突出特点是编写者不需要关注怎么做,只需要告诉系统我要什么就可以。
虽然4GL是这样的一种语言,大大简化了编写者的编写难度,其实底层还是数据库的编写者帮我们隐藏了具体的实现细节。
举个例子,你妈妈叫你去做一碗西红柿炒鸡蛋,但是并没有告诉你如何做,这个时候你查资料,发现了从洗菜到炒菜的所有过程,然后炒了一碗西红柿炒鸡蛋出来。
对于你的妈妈来说,她很简单的发出了一个命令,得到了结果,不过她也不知道具体如何实现的,具体的实现细节被你在厨房掩盖了。
2. RadonDB的查询优化器
你在厨房关上门来做的事情,其实就是数据库查询优化器做的事情,把你的指令分解成具体的执行过程,然后将结果返回给终端客户。
现在来看看查询优化器的实现。其代码在optimizer包下面,只有两个文件:
- optimizer.go 这个文件声明了一个接口
- simple_optimizer.go 这个文件则是具体的实现。
先看看接口实现:
package optimizer
import (
"planner"
)
// Optimizer interface.
type Optimizer interface {
BuildPlanTree() (*planner.PlanTree, error)
}
从这个接口上来看,查询优化器主要做的事情就是构建一颗查询计划树。接下来开始看看具体的实现过程,首先会看到一个结构体:
// SimpleOptimizer is a simple optimizer who dispatches the plans
type SimpleOptimizer struct {
log *xlog.Log
database string
query string
node sqlparser.Statement
router *router.Router
}
一般来说,执行一个SQL的时候总会遇到这样一个操作:
optimizer.NewSimpleOptimizer(log, database, query, node, router).BuildPlanTree()
都会新建一个Optimizer,然后新建一个计划树。其实就是新建了一个刚才的结构体,这是实现的代码:
// NewSimpleOptimizer creates the new simple optimizer.
func NewSimpleOptimizer(log *xlog.Log, database string, query string, node sqlparser.Statement, router *router.Router) *SimpleOptimizer {
return &SimpleOptimizer{
log: log,
database: database,
query: query,
node: node,
router: router,
}
}
注意这里的node,这是一个sqlparser.Statement,主要玩的就是这个东西。
好了,接下来就可以新建查询计划树了:
// BuildPlanTree used to build plan trees for the query.
func (so *SimpleOptimizer) BuildPlanTree() (*planner.PlanTree, error) {
log := so.log
database := so.database
query := so.query
node := so.node
router := so.router
plans := planner.NewPlanTree()
switch node.(type) {
case *sqlparser.DDL:
node := planner.NewDDLPlan(log, database, query, node.(*sqlparser.DDL), router)
plans.Add(node)
case *sqlparser.Insert:
node := planner.NewInsertPlan(log, database, query, node.(*sqlparser.Insert), router)
plans.Add(node)
case *sqlparser.Delete:
node := planner.NewDeletePlan(log, database, query, node.(*sqlparser.Delete), router)
plans.Add(node)
case *sqlparser.Update:
node := planner.NewUpdatePlan(log, database, query, node.(*sqlparser.Update), router)
plans.Add(node)
case *sqlparser.Select:
nod := node.(*sqlparser.Select)
selectNode := planner.NewSelectPlan(log, database, query, nod, router)
plans.Add(selectNode)
case *sqlparser.Checksum:
node := planner.NewOthersPlan(log, database, query, node, router)
plans.Add(node)
default:
return nil, errors.Errorf("optimizer.unsupported.query.type[%+v]", node)
}
// Build plantree.
if err := plans.Build(); err != nil {
return nil, err
}
return plans, nil
}
代码也不长,就全都贴出来了,其实很简单,就是对node的类型进行判断,根据不同的类型确定不同的plan。
今天这篇只是引导,所以大致看看就好,先看看其中一个分支的计划是怎么创建的:
// NewInsertPlan used to create InsertPlan
func NewInsertPlan(log *xlog.Log, database string, query string, node *sqlparser.Insert, router *router.Router) *InsertPlan {
return &InsertPlan{
log: log,
node: node,
router: router,
database: database,
RawQuery: query,
Typ: PlanTypeInsert,
Querys: make([]xcontext.QueryTuple, 0, 16),
}
}
这里只是返回一个结构体,没什么意思,有水平的地方在Build中,但是代码很长,所以今天就先不摊开来讲了。
留点悬念。
3. 小结
今天写的真轻松,因为要开始学习一个非常庞大的东西了。加油吧自己。
学习RadonDB源码(三)的更多相关文章
- 学习RadonDB源码(一)
1. 可能是开始也可能是结束 RadonDB是国内知名云服务提供商青云开源的一款产品,下面是一段来自官方的介绍: QingCloud RadonDB 是基于 MySQL 研发的新一代分布式关系型数据库 ...
- 学习RadonDB源码(二)
1. 为我新的一天没有放弃而喝彩 学习是一件很容易放弃的事情,因为就算是不学,我也能在现在的岗位上发光发热.可是人不就是一个热爱折腾的种群吗? 今天没有放弃不代表明天没有放弃,也许放弃的可能性大于坚持 ...
- 【菜鸟学习jquery源码】数据缓存与data()
前言 最近比较烦,深圳的工作还没着落,论文不想弄,烦.....今天看了下jquery的数据缓存的代码,参考着Aaron的源码分析,自己有点理解了,和大家分享下.以后也打算把自己的jquery的学习心得 ...
- DotNetty网络通信框架学习之源码分析
DotNetty网络通信框架学习之源码分析 有关DotNetty框架,网上的详细资料不是很多,有不多的几个博友做了简单的介绍,也没有做深入的探究,我也根据源码中提供的demo做一下记录,方便后期查阅. ...
- 学习 vue 源码 -- 响应式原理
概述 由于刚开始学习 vue 源码,而且水平有限,有理解或表述的不对的地方,还请不吝指教. vue 主要通过 Watcher.Dep 和 Observer 三个类来实现响应式视图.另外还有一个 sch ...
- 我该如何学习spring源码以及解析bean定义的注册
如何学习spring源码 前言 本文属于spring源码解析的系列文章之一,文章主要是介绍如何学习spring的源码,希望能够最大限度的帮助到有需要的人.文章总体难度不大,但比较繁重,学习时一定要耐住 ...
- 一起学习vue源码 - Object的变化侦测
作者:小土豆biubiubiu 博客园:www.cnblogs.com/HouJiao/ 掘金:https://juejin.im/user/58c61b4361ff4b005d9e894d 简书:h ...
- 手牵手,从零学习Vue源码 系列一(前言-目录篇)
系列文章: 手牵手,从零学习Vue源码 系列一(前言-目录篇) 手牵手,从零学习Vue源码 系列二(变化侦测篇) 手牵手,从零学习Vue源码 系列三(虚拟DOM篇) 陆续更新中... 预计八月中旬更新 ...
- 手牵手,从零学习Vue源码 系列二(变化侦测篇)
系列文章: 手牵手,从零学习Vue源码 系列一(前言-目录篇) 手牵手,从零学习Vue源码 系列二(变化侦测篇) 陆续更新中... 预计八月中旬更新完毕. 1 概述 Vue最大的特点之一就是数据驱动视 ...
随机推荐
- NoSql数据库Redis系列(1)——Redis简介
一.redis介绍 (一).Redis 简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点 ...
- Python自动化测试常用库
基本库: sys 程序和Python解析器的交互 os 启动新进程:操作文件和目录 re 正则表达式,字符串匹配 string 基本字符串操作 inspect 提供自省和反射功能 importlib ...
- 深度学习面试题10:二维卷积(Full卷积、Same卷积、Valid卷积、带深度的二维卷积)
目录 二维Full卷积 二维Same卷积 二维Valid卷积 三种卷积类型的关系 具备深度的二维卷积 具备深度的张量与多个卷积核的卷积 参考资料 二维卷积的原理和一维卷积类似,也有full卷积.sam ...
- html5中 input的pattern属性 和 details/summary元素
html5--3.21 课程小结与其他新增元素 一.总结 一句话总结: input的pattern属性可以设置正则验证,比如检测学号的位数和数字区间 details/summary元素配合起来可以做元 ...
- StringBuffer & StringBuilder的区别
StringBuffer是线程安全的,内部有锁.所以比StringBuilder慢一点. 在单线程生成字符串的情况下,优先使用StringBuilder. 这就是为啥有时候IntelliJ Idea会 ...
- leetcode 293.Flip Game(lintcode 914) 、294.Flip Game II(lintcode 913)
914. Flip Game https://www.cnblogs.com/grandyang/p/5224896.html 从前到后遍历,遇到连续两个'+',就将两个加号变成'-'组成新的字符串加 ...
- shell编程系列13--文本处理三剑客之sed利用sed追加文件内容
shell编程系列13--文本处理三剑客之sed利用sed追加文件内容 追加用法总结: .a 在匹配行后面追加 .i 在匹配行前面追加 .r 将文件内容追加到匹配行后面 .w 将匹配行写入指定文件 追 ...
- 九、postman的自带的鉴权demo
basic authentication https://postman-echo.com/basic-auth username:postman password:password
- Python - Django - ORM QuerySet 方法补充
models.py: from django.db import models class Employee2(models.Model): name = models.CharField(max_l ...
- C# .NET 杀进程
procName 是进程名,不带.exe . private bool IsAppKill(String procName) { try { ; System.Diagnostics.Process[ ...