学习RadonDB源码(三)

作者 : 开心源码 本文共2795个字,预计阅读时间需要7分钟 发布时间: 2022-05-12 共241人阅读

1. 所谓第四代语言

SQL是一种典型的第四代语言,即4GL,这种语言的突出特点是编写者不需要关注怎样做,只要要告诉系统我要什么即可以。

尽管4GL是这样的一种语言,大大简化了编写者的编写难度,其实底层还是数据库的编写者帮我们隐藏了具体的实现细节。

举个例子,你妈妈叫你去做一碗西红柿炒鸡蛋,但是并没有告诉你如何做,这个时候你查资料,发现了从洗菜到炒菜的所有过程,而后炒了一碗西红柿炒鸡蛋出来。

对于你的妈妈来说,她很简单的发出了一个命令,得到了结果,不过她也不知道具体如何实现的,具体的实现细节被你在厨房掩盖了。

2. RadonDB的查询优化器

你在厨房关上门来做的事情,其实就是数据库查询优化器做的事情,把你的指令分解成具体的执行过程,而后将结果返回给终端用户。

现在来看看查询优化器的实现。其代码在optimizer包下面,只有两个文件:

  • optimizer.go 这个文件公告了一个接口
  • simple_optimizer.go 这个文件则是具体的实现。

先看看接口实现:

package optimizerimport (    "planner")// Optimizer interface.type Optimizer interface {    BuildPlanTree() (*planner.PlanTree, error)}

从这个接口上来看,查询优化器主要做的事情就是构建一颗查询计划树。接下来开始看看具体的实现过程,首先会看到一个结构体:

// SimpleOptimizer is a simple optimizer who dispatches the planstype 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 InsertPlanfunc 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. 小结

今天写的真轻松,由于要开始学习一个非常庞大的东西了。加油吧自己。

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 学习RadonDB源码(三)

发表回复