PGX:Rust的postgresql扩展开发框架:1何为数据库扩展

2023-11-11 00:40

本文主要是介绍PGX:Rust的postgresql扩展开发框架:1何为数据库扩展,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

吃屎的牛对图片支持有问题,如果图挂了,请到我公众号或者知乎专栏去查看:

https://zhuanlan.zhihu.com/p/623058163

数据库的扩展开发

数据库与操作系统、编译器被并称为IT三大基础领域

目前因为开源圈子的风生水起,国产(重音)数据库这个问题基本上是被攻克了……

这里面重点表扬一下达梦,确实是国产之光……其他的嘛:

今天我们不讨论有关战略和形而上学的东西,今天我们来聊一个非常硬核的数据库核心技术问题:数据库的扩展开发

说道这里,估计有同学马上会跳出来说,虾神你还活在25年前么?会个Crud就敢说核心技术了?难道你不知道对于数据库的Crud Boy已经变成了骂人的话么?说一个码农是Crud boy,就像对一个人在球场上说:——你打球像他

 

……emmm……好吧,我这里不是想要讲不是其他语言连接到数据库上面进行应用开发,做已经被做成了坤坤的Crud,而是正儿八经的扩展开发:

如何编写直接运行在数据库引擎上的数据库扩展函数。

数据库的两种使用方式

我们都知道,使用数据库一共有两种方式:

  1. 使用数据库连接API(Database Connectivity),连接到数据库上,然后进行Crud,比如Java的JDBC或者微软推荐的ODBC,这种方式完全把数据库就当成了一个数据存储和查询工具来用,也就是数据库提供啥功能就用啥功能……这是标准的Crud……

  • 这种模式的优点就是不用关心数据库底层技术,只需要了解编码用的语言和技术就行,数据库对于crud boy来说,也就是个放数据的地方……
  • 缺点也是一样,基本上没有对于数据库底层的理解和使用能力,即数据库提供啥功能你就只能用啥功能,另外你的所有功能都必须运行在编程框架提供的应用基础上,而不是数据库的引擎上。

  1. 是正统的数据库开发:利用SQL来使用数据库功能,这样就不具体依赖与各种不同的语言与API了,所有的功能直接运行在数据库引擎上,在最贴近数据的地方进行计算。
  • 这种模式的优点就是不具体依赖于第三方语言的DBC API,直接在数据库引擎上编写功能,所有的功能都直接运行在数据库引擎上,具有极高的性能。
  • 缺点就是数据库官方支持的语言,就是SQL,而SQL作为第四代语言,优点缺点都非常突出,最主要的缺点有缺少标准库、语言不具备复杂多样性的语法规则和能力,无法编写复杂度高的业务逻辑代码等。

而通用的数据库函数,基本上都是以SQL模式进行调用了,下面举个例子:

例如,我们在单位的员工数据里面,需要查询业绩最大的员工,两种不同的模式的做法如下:

如果数据量少的话,两种方法实际上没有多大的差距,但是如果数据量极其巨大,两种方式的差距可能就天差地别了。

第一种方式要从数据库中把所有信息全部获取出来,然后通过总线或者网络传递到第三方APP的业务逻辑中进行处理,无论是对于网络传输和处理服务器的开销,都有很大的压力,而且应用服务器从数据库取到的数据,99%都是无效数据,可以说这是一种非常低效的解决方式;唯一节约只有数据库的CPU资源(但是IO资源还是浪费掉了)

第二种方式,把MAX计算的任务直接交给了数据库引擎,算完之后,直接把结果数据返回给了应用服务器,这样最大限度的节约了IO资源和应用服务器的CPU资源,但是运算的任务是直接放在数据库引擎上的,这样就会使用一部分数据库的计算资源。

所以两种方式在不同的模式下,都有它的优势:

第一种模式看起来很浪费资源,但是如果我们的业务逻辑不仅仅是求一个max,而是一系列比较复杂的迭代运算,要不断的在整份数据中循环、对比、计算,这种复杂的运算如果放在数据库引擎上,会严重影响数据库的性能,所以干脆一次性把所有数据都取到应用服务器上来进行复杂迭代了,反而效果更好。

但是对于我们大部分的应用来说,基本上都是IO密集型的,所以第二种模式在系统编码架构设计中占有绝对多数。所以,其中唯一的限制,就是类似于max这样的数据库函数有多少了……

数据库函数的开发方式之SQL:

数据库函数因为主要执行在数据库的引擎上,所以必须要以数据库引擎能够解析和使用的语言来进行编写开发,一般情况下,都是以SQL语言来进行编写的,如下所示:

正如上图所说的,SQL的能力实在有些弱,我随手一列就能列出一堆很常见一些功能,但是SQL干不干了的:

  • 读写文件(╯°Д°)╯︵ ┻━┻ 特么你要数据库读写文件干嘛……为什么不?如果需要快速导入特殊格式的文件呢?)
  • 爬虫(╯°Д°)╯︵ ┻━┻ 特么你家数据库直接爬数据啊)
  • 发送邮件(╯°Д°)╯︵ ┻━┻ ,特么你家数据库直接发送邮件想干嘛?监控还是偷数据?)
  • 加密与解密(╯°Д°)╯︵ ┻━┻ ,特么你家数据库直接加密解密数据么?)
  • 解析xml/json/yml/pbf……(╯°Д°)╯︵ ┻━┻ ,特么你家数据库直接解析这些文件干嘛?)
  • 自动更新Redis (╯°Д°)╯︵ ┻━┻ ,过分了啊,谁在数据库里面去对redis做更新的?)
  • ……
  • ……
  • ……

先别管这些需求合理不合理,这些功能几乎都是一些在基础开发中可以做,你也可以说,我在应用程序里面就可以做了,为什么要在数据库里面做,我们不在数据库里面去做,是因为不知道数据库可不可以做,也不知道如何在数据库里面做,但凡我们能够在数据库里面做到,那么离开就会打开一个新的世界!

所以,我们需要一种可以很快速、方便编写数据库扩展的方法。

实际上各个厂商都有自己的数据库扩展方法,比如Oracle可以用Java来写他的扩展,而SQL Server可以用C#来写,不过鉴于开源的数据库如Postgresql、MySQL啥的(包括国产数据库),都用的C语言写的,所以大部分数据库在一段时间内,都只能用C语言编写数据库的扩展。

例如Postgresql里面最出名的扩展PostGIS。

要用C来写个数据库扩展,那真心是不容易,如下所示:

一个非常简单的 generate_series 函数,它生成一个给定起止的列表。这样一个简单的功能,如果要用 extension 实现,核心代码大概就要 100 行,还不包括上百行的脚手架代码,这段代码充斥了 SRF,memory context,function context 等一大堆让人不明嚼栗的概念,如果你想要写对,必然要狠狠花上一番功夫。

那么有没有很简单的,让人一看就懂,一学就会,是个人有个手就能学会的数据库扩展开发呢?

继续往下看,这就是我今天要介绍的内容:

PGX 基于Rust的Postgresql扩展开发框架

在正式介绍PGX之前,我们先通过一个简单的例子,来看看用它来写数据库扩展是有多简单,比如要复述上面这个用了100多行的C语言来写的扩展,来创建一个可以生成一个整数序列的数据库扩展函数,在rust里面怎么写呢?

#[pg_extern] fn my_generate_series(start:i64,end:i64,step:i64) ->SetOfIterator<'static, i64>{ SetOfIterator::new((start..=end).step_by(step as usize).into_iter()) }

从代码上看,你几乎不需要有任何与数据库有关的系统知识,只需要编写业务逻辑代码就行,而且Rust的语法逻辑相对C来说,还是比较简单的……只要是个人,有个手就能看懂学会……

先来看看执行效果:

生成0-10的序列:

生成0-20的偶数序列:

然后在来换一个功能,比如我要生成一个随机表格,由name和value组成,name是随机的字符串,value是随机的浮点数,怎么写呢?

代码如下,全部加起来(不算回车的话,只要4行)

#[pg_extern] fn random_values2(num_rows: i32) -> TableIterator<'static, (name!(id,i32),name!(name, String), name!(value, f64))> { let mut rd = thread_rng(); TableIterator::new((1..=num_rows).map(move |i| (i, Alphanumeric.sample_iter(&mut rd).take(8).map(char::from).collect::<String>(), rand::random::<f64>()))) }

执行效果如下:

这个函数可以直接当成一个表格来用:

该有的查询能力,也是具备的:

用一个词来形容,简直就是:

对于还在用C来写扩展的程序员来说,简直就是降维打击……那么这个神奇的pgx到底是怎么用呢?

请听下回分解……

(不是我想中断,是因为写到这里,没纸了……或者墨水用完了……你们一定要相信我……)

这篇关于PGX:Rust的postgresql扩展开发框架:1何为数据库扩展的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/386387

相关文章

数据库oracle用户密码过期查询及解决方案

《数据库oracle用户密码过期查询及解决方案》:本文主要介绍如何处理ORACLE数据库用户密码过期和修改密码期限的问题,包括创建用户、赋予权限、修改密码、解锁用户和设置密码期限,文中通过代码介绍... 目录前言一、创建用户、赋予权限、修改密码、解锁用户和设置期限二、查询用户密码期限和过期后的修改1.查询用

mysql数据库分区的使用

《mysql数据库分区的使用》MySQL分区技术通过将大表分割成多个较小片段,提高查询性能、管理效率和数据存储效率,本文就来介绍一下mysql数据库分区的使用,感兴趣的可以了解一下... 目录【一】分区的基本概念【1】物理存储与逻辑分割【2】查询性能提升【3】数据管理与维护【4】扩展性与并行处理【二】分区的

IDEA如何切换数据库版本mysql5或mysql8

《IDEA如何切换数据库版本mysql5或mysql8》本文介绍了如何将IntelliJIDEA从MySQL5切换到MySQL8的详细步骤,包括下载MySQL8、安装、配置、停止旧服务、启动新服务以及... 目录问题描述解决方案第一步第二步第三步第四步第五步总结问题描述最近想开发一个新应用,想使用mysq

基于Python开发电脑定时关机工具

《基于Python开发电脑定时关机工具》这篇文章主要为大家详细介绍了如何基于Python开发一个电脑定时关机工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 简介2. 运行效果3. 相关源码1. 简介这个程序就像一个“忠实的管家”,帮你按时关掉电脑,而且全程不需要你多做

Rust 数据类型详解

《Rust数据类型详解》本文介绍了Rust编程语言中的标量类型和复合类型,标量类型包括整数、浮点数、布尔和字符,而复合类型则包括元组和数组,标量类型用于表示单个值,具有不同的表示和范围,本文介绍的非... 目录一、标量类型(Scalar Types)1. 整数类型(Integer Types)1.1 整数字

Oracle数据库使用 listagg去重删除重复数据的方法汇总

《Oracle数据库使用listagg去重删除重复数据的方法汇总》文章介绍了在Oracle数据库中使用LISTAGG和XMLAGG函数进行字符串聚合并去重的方法,包括去重聚合、使用XML解析和CLO... 目录案例表第一种:使用wm_concat() + distinct去重聚合第二种:使用listagg,

Java中的Opencv简介与开发环境部署方法

《Java中的Opencv简介与开发环境部署方法》OpenCV是一个开源的计算机视觉和图像处理库,提供了丰富的图像处理算法和工具,它支持多种图像处理和计算机视觉算法,可以用于物体识别与跟踪、图像分割与... 目录1.Opencv简介Opencv的应用2.Java使用OpenCV进行图像操作opencv安装j

Java读取InfluxDB数据库的方法详解

《Java读取InfluxDB数据库的方法详解》本文介绍基于Java语言,读取InfluxDB数据库的方法,包括读取InfluxDB的所有数据库,以及指定数据库中的measurement、field、... 首先,创建一个Java项目,用于撰写代码。接下来,配置所需要的依赖;这里我们就选择可用于与Infl

详谈redis跟数据库的数据同步问题

《详谈redis跟数据库的数据同步问题》文章讨论了在Redis和数据库数据一致性问题上的解决方案,主要比较了先更新Redis缓存再更新数据库和先更新数据库再更新Redis缓存两种方案,文章指出,删除R... 目录一、Redis 数据库数据一致性的解决方案1.1、更新Redis缓存、删除Redis缓存的区别二

oracle数据库索引失效的问题及解决

《oracle数据库索引失效的问题及解决》本文总结了在Oracle数据库中索引失效的一些常见场景,包括使用isnull、isnotnull、!=、、、函数处理、like前置%查询以及范围索引和等值索引... 目录oracle数据库索引失效问题场景环境索引失效情况及验证结论一结论二结论三结论四结论五总结ora