自己动手做数据库系统:解释执行 update 和 delete 对应的 sql 语句

这篇具有很好参考价值的文章主要介绍了自己动手做数据库系统:解释执行 update 和 delete 对应的 sql 语句。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在上一节我们完成了 select 语句的解释执行,本节我们看看 Update 和 Delete 对应的语句如何解释执行,当然他们的实现原理跟我们前面实现的 select 语句执行大同小异。无论是 update还是 delete 都是对数据表的修改,因此他们的实现方法基本相同。

假设我们要执行如下 sql 语句:

update STUDENT set MajorId=20 where MajorId=30 and GradYear=2020

delete from STUDENT where MajorId=30 and GradYear=2020

要完成上面的代码,我们需要 scan底层的文件块,找到所有满足 where 条件的记录,如果语句是 update,那么把找到的记录修改掉,如果是 delete,那么把找到的记录给删除掉。我们看看具体的代码实现,首先我们添加 UpdatePlanner 的接口定义,在 planner 的 interface.go 文件中增加代码如下:

package planner

import (
    "parser"
    "record_manager"
    "tx"
)

type Plan interface {
    Open() interface{}
    BlocksAccessed() int               //对应 B(s)
    RecordsOutput() int                //对应 R(s)
    DistinctValues(fldName string) int //对应 V(s,F)
    Schema() record_manager.SchemaInterface
}

type QueryPlanner interface {
    CreatePlan(data *parser.QueryData, tx *tx.Transation) Plan
}

type UpdatePlanner interface {
    /*
        解释执行 insert 语句,返回被修改的记录条数
    */
    ExecuteInsert(data *parser.InsertData, tx *tx.Transation) int

    /*
        解释执行 delete 语句,返回被删除的记录数
    */
    ExecuteDelete(data *parser.DeleteData, tx *tx.Transation) int

    /*
        解释执行 create table 语句,返回新建表中的记录数
    */
    ExecuteCreateTable(data *parser.CreateTableData, tx *tx.Transation) int

    /*
        解释执行 create index 语句,返回当前建立了索引的记录数
        TODO
    */
    //ExecuteCreateIndex(data *parser.CreateIndexData, tx *tx.Transation) int
}

在 planner 目录下新建文件 update_planner.go,输入代码如下:

package planner

import (
    metadata_manager "metadata_management"
    "parser"
    "query"
    "tx"
)

type BasicUpdatePlanner struct {
    mdm *metadata_manager.MetaDataManager
}

func NewBasicUpdatePlanner(mdm *metadata_manager.MetaDataManager) *BasicUpdatePlanner {
    return &BasicUpdatePlanner{
        mdm: mdm,
    }
}

func (b *BasicUpdatePlanner) ExecuteDelete(data *parser.DeleteData, tx *tx.Transation) int {
    /*
        先 scan 出要处理的记录,然后执行删除
    */
    tablePlan := NewTablePlan(tx, data.TableName(), b.mdm)
    selectPlan := NewSelectPlan(tablePlan, data.Pred())
    scan := selectPlan.Open()
    updateScan := scan.(*query.SelectionScan)
    count := 0
    for updateScan.Next() {
        updateScan.Delete()
        count += 1
    }
    updateScan.Close()
    return count
}

func (b *BasicUpdatePlanner) ExecuteModify(data *parser.ModifyData, tx *tx.Transation) int {
    /*
        先 scan 出选中的记录,然后修改记录的信息
    */
    tablePlan := NewTablePlan(tx, data.TableName(), b.mdm)
    selectPlan := NewSelectPlan(tablePlan, data.Pred())
    scan := selectPlan.Open()
    updateScan := scan.(*query.SelectionScan)
    count := 0
    for updateScan.Next() {
        val := data.NewValue().Evaluate(scan.(query.Scan))
        updateScan.SetVal(data.TargetField(), val)
        count += 1
    }
    return count
}

func (b *BasicUpdatePlanner) ExecuteInsert(data *parser.InsertData, tx *tx.Transation) int {
    tablePlan := NewTablePlan(tx, data.TableName(), b.mdm)
    updateScan := tablePlan.Open().(*query.TableScan)
    updateScan.Insert()
    insertFields := data.Fields()
    insertedVals := data.Vals()

    for i := 0; i < len(insertFields); i++ {
        updateScan.SetVal(insertFields[i], insertedVals[i])
    }

    updateScan.Close()
    return 1
}

func (b *BasicUpdatePlanner) ExecuteCreateTable(data *parser.CreateTableData, tx *tx.Transation) int {
    b.mdm.CreateTable(data.TableName(), data.NewSchema(), tx)
    return 0
}

func (b *BasicUpdatePlanner) ExecuteView(data *parser.ViewData, tx *tx.Transation) int {
    b.mdm.CreateView(data.ViewName(), data.ViewDef(), tx)
    return 0
}

func (b *BasicUpdatePlanner) ExecuteIndex(data *parser.IndexData, tx *tx.Transation) int {
    //b.mdm.CreateIndex
    //TODO

    return 0
}

在上面代码中BasicUpdatePlanner用于负责实现与数据库表内容修改相关的操作,例如插入,修改和删除,它导出的接口 ExecuteDelete, ExecuteModify, ExecuteInsert 分别负责表的删除,修改和插入,删除和修改的逻辑类似,首先都是通过 TablePlan 和 SelectPlan 找出要修改的记录,然后进行相应的操作,在上面代码实现中我们留有与索引相关的操作没有实现,因为索引是我们后续章节的一个重要内容。

完成了上面代码后,我们看看如何调用他们然后检验一下实现效果,在 main.go 中增加代码如下:

package main

import (
    bmg "buffer_manager"
    fm "file_manager"
    "fmt"
    lm "log_manager"
    metadata_manager "metadata_management"
    "parser"
    "planner"
    "query"
    "tx"
)

func PrintStudentTable(tx *tx.Transation, mdm *metadata_manager.MetaDataManager) {
    queryStr := "select name, majorid, gradyear from STUDENT"
    p := parser.NewSQLParser(queryStr)
    queryData := p.Query()
    test_planner := planner.CreateBasicQueryPlanner(mdm)
    test_plan := test_planner.CreatePlan(queryData, tx)
    test_interface := (test_plan.Open())
    test_scan, _ := test_interface.(query.Scan)
    for test_scan.Next() {
        fmt.Printf("name: %s, majorid: %d, gradyear: %d\n",
            test_scan.GetString("name"), test_scan.GetInt("majorid"),
            test_scan.GetInt("gradyear"))
    }
}

func CreateInsertUpdateByUpdatePlanner() {
    file_manager, _ := fm.NewFileManager("student", 2048)
    log_manager, _ := lm.NewLogManager(file_manager, "logfile.log")
    buffer_manager := bmg.NewBufferManager(file_manager, log_manager, 3)
    tx := tx.NewTransation(file_manager, log_manager, buffer_manager)
    mdm := metadata_manager.NewMetaDataManager(false, tx)

    updatePlanner := planner.NewBasicUpdatePlanner(mdm)
    createTableSql := "create table STUDENT (name varchar(16), majorid int, gradyear int)"
    p := parser.NewSQLParser(createTableSql)
    tableData := p.UpdateCmd().(*parser.CreateTableData)
    updatePlanner.ExecuteCreateTable(tableData, tx)

    insertSQL := "insert into STUDENT (name, majorid, gradyear) values(\"tylor\", 30, 2020)"
    p = parser.NewSQLParser(insertSQL)
    insertData := p.UpdateCmd().(*parser.InsertData)
    updatePlanner.ExecuteInsert(insertData, tx)
    insertSQL = "insert into STUDENT (name, majorid, gradyear) values(\"tom\", 35, 2023)"
    p = parser.NewSQLParser(insertSQL)
    insertData = p.UpdateCmd().(*parser.InsertData)
    updatePlanner.ExecuteInsert(insertData, tx)

    fmt.Println("table after insert:")
    PrintStudentTable(tx, mdm)

    updateSQL := "update STUDENT set majorid=20 where majorid=30 and gradyear=2020"
    p = parser.NewSQLParser(updateSQL)
    updateData := p.UpdateCmd().(*parser.ModifyData)
    updatePlanner.ExecuteModify(updateData, tx)

    fmt.Println("table after update:")
    PrintStudentTable(tx, mdm)

    deleteSQL := "delete from STUDENT where majorid=35"
    p = parser.NewSQLParser(deleteSQL)
    deleteData := p.UpdateCmd().(*parser.DeleteData)
    updatePlanner.ExecuteDelete(deleteData, tx)

    fmt.Println("table after delete")
    PrintStudentTable(tx, mdm)
}

func main() {
    CreateInsertUpdateByUpdatePlanner()
}

在上面代码实现中,CreateInsertUpdateByUpdatePlanner函数先创建BasicUpdatePlanner对象,然后调用其 ExecuteCreateTable接口创建 STUDENT 表,接着使用 sql 解释器解析 insert 语句后创建 InsertData 对象,然后调用ExecuteInsert接口将记录插入数据库表,接下来以同样的方式调用ExecuteModify, ExecuteDelete接口来实现对数据库表中有关记录的修改和删除,完成上面代码后 运行go run main.go,执行起来效果如下:

able after insert:
name: tylor, majorid: 30, gradyear: 2020
name: tom, majorid: 35, gradyear: 2023
table after update:
name: tylor, majorid: 20, gradyear: 2020
name: tom, majorid: 35, gradyear: 2023
table after delete
name: tylor, majorid: 20, gradyear: 2020

从运行结果可以看到,我们对数据库表的建立,插入,修改和删除等操作的基本结果是正确的。更多内容和调试演示视频请在 b 站搜索:Coding 迪斯尼。代码下载:

https://github.com/wycl16514/database_SQL_execute_create_insert_update_delete.git
文章来源地址https://www.toymoban.com/news/detail-815872.html

到了这里,关于自己动手做数据库系统:解释执行 update 和 delete 对应的 sql 语句的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • MySQL数据库——MySQL UPDATE:修改数据(更新数据)

    在 MySQL 中,可以使用 UPDATE 语句来修改、更新一个或多个表的数据。 使用 UPDATE 语句修改单个表,语法格式为: 语法说明如下: 表名 : 用于指定要更新的表名称。 SET  子句: 用于指定表中要修改的列名及其列值。其中,每个指定的列值可以是表达式,也可以是该列对应的

    2024年02月12日
    浏览(10)
  • 微信小程序数据库更新update的使用

            微信小程序数据库的update功能不可以直接使用db.collection.update,此功能虽然在collection的使用说明文档中有,但是经过实际操作之后是无法成功更新的,必须使用db.collection.doc.update才可以完成。         使用db.collection.doc.update方式时,数据记录则应由add功能添加

    2024年02月03日
    浏览(10)
  • Mysql 数据库DML 数据操作语言—— 对数据库表中的数据进行更改UPDATE 和删除DELETE

    Mysql 数据库DML 数据操作语言—— 对数据库表中的数据进行更改UPDATE 和删除DELETE

        delete语句可以有条件,也可以没有,如果没有条件的话就是删除整张表 delete不可以删除表中某一个字段的值,但是update可以; 

    2024年01月19日
    浏览(9)
  • 数据库update语句到底是行锁还是表锁?

    数据库update语句到底是行锁还是表锁?

    先说结论: 无索引的情况下,如果不走主键,那么update为表锁;有索引的情况下,走索引或者走主键(效果一样),那么update变为行锁。 大致把问题分为两种情况:有索引或者没有索引 先建一个没有索引的表,模拟一些数据,并且把事务自动提交关掉。 我们先在第一个查询

    2023年04月09日
    浏览(11)
  • Oracle数据库update语句用法,多表批量更新对应的字段值

    Oracle数据库update语句用法,多表批量更新对应的字段值

    日常工作经常会遇到参照某个表格,更新主表对应字段的值 一般可以用excel的VLOOKup函数进行查找匹配,但是这种方法需要将表从数据库中导出,更新完了之后再导回数据库中。 我们用update语句可以很方便在数据库里完成更新。 语句: update 要修改数据的表名 set 修改的列1=(

    2024年02月06日
    浏览(11)
  • MySQL 数据库全局变量中文解释

    Name Value auto_increment_increment AUTO_INCREMENT 字段值的自增长步长值。 auto_increment_offset AUTO_INCREMENT 字段值的初始值。 autocommit 指示新连接的默认提交模式是否启用。 automatic_sp_privileges 控制是否在存储过程上创建或更改时自动分配特定权限。 back_log 在开始拒绝新连接之前,等待处理

    2024年02月07日
    浏览(11)
  • 数据库管理-第七十期 自己?自己(20230425)

    数据库管理-第七十期 自己?自己(20230425)

    来到70了,最近有点卷,写的稍微多了些。 吐槽一下五一调休,周末砍一天,连6天,放5天,上3天,周末又砍一天。 今天刷抖音看到现在是如何看伍佰演唱会的:“花500买票,去伍佰的演唱会,唱伍佰的歌给伍佰听,伍佰只要起个头,插不上嘴”。突然回忆起伍佰的《突然的

    2023年04月26日
    浏览(91)
  • mysql-DBA(1)-数据库备份恢复-导入导出-日志解释

    mysql-DBA(1)-数据库备份恢复-导入导出-日志解释

    log: hdd data :ssd  ,备份和导出都慢,缓冲池有污染。 逻辑备份:把所有的命令转换成sql语句。 修改配置文件: -A 备份所有 -B 备份哪个数据库 --master-data=1 同步 内容: 备份参数: 1.备份成文件,里面就是sql语句 2.routine: 3.trigger 触发器 4.event: 定时任务 5.-B 数据库 1.有-B 表

    2024年03月09日
    浏览(38)
  • 基于向量数据库搭建自己的搜索引擎

    基于向量数据库搭建自己的搜索引擎

    前言【基于chatbot】 厌倦了商业搜索引擎搜索引擎没完没了的广告,很多时候,只是需要精准高效地检索信息,而不是和商业广告“斗智斗勇”。以前主要是借助爬虫工具,而随着技术的进步,现在有了更多更方便的解决方案,向量数据库就是其中之一【chatGPT也需要它的支撑

    2024年04月11日
    浏览(10)
  • 四种数据库执行脚本文件导入数据的方式

    mysql执行sql脚本文件的方法: 1、在命令行输入mysql -uroot -h10.235.5.55 -p’123456’ -P3306 F:helloniuzi.sql 2、在命令行输入【source F:helloniuzi.sql】 mysql -uroot -h10.235.5.55 -p’123456’ -P3306 -e \\\"source test.sql \\\" test.log psql -Upostgres -dzxin -h10.235.5.55 -p6789 -f test.sql upgrade.log isql -Uzxin_smap -P’123456’

    2024年02月04日
    浏览(8)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包