[pgrx开发postgresql数据库扩展]6.返回序列的函数编写(1)单值序列

news2024/11/17 19:30:51

上篇文章是中规中矩的标准计算函数,就算不用pgrx,也是可以正常理解的,所以基本上没有什么对于pgrx框架有关系的东西(唯一有关系的东西,应该就是Rust的时间类型与pgrx的时间类型的计算了)。

这篇文章会讲一个pgrx对于postgresql或者说对于任何数据库扩展来说都比较有用的开发内容:返回序列以及表的函数的编写。

针对上篇文章,用了一个概念,就是:单值输入与单值输出,那么相对来说,这篇文章描写的就是单值输入与多值输出。

所谓的多值输出,就是可以输出超过一行的函数。

如下所示,这个Python函数,就是单值输入,多值输出的例子:我们输入1个整数,然后函数根据我们输入的整数,去生成一个list。

例如我们输入的是5,得到的结果就是[0,1,2,3,4]。

def generate_list(x:int):
    return [i for i in range(0,x)]

在本系列的第一篇文章里面,大家可能还记得我给出来的这样一个效果:

那么在pgrx里面,如何来实现呢?

pgrx对于这种集合类型的支持,有很多种,例如Vec、range这些个类型都是支持的,但是对于数据库来说,这种返回超过一行序列的方法被称之为srf,即:Set Returning Functions。

在Postgresql里面,本身就内置了很多srf,例如generate_series()这个就是最著名的内置srf。

而在pgrx里面,如果要实现srf,需要包装的类型分别是:

  • SetOfIterator
  • TableIterator

注意:这两个类型是pgrx 0.7.0之后版本才推出的,如果你看的旧版本的介绍,发现是没有这两个类型的。

首先我们来看如何使用SetOfIterator来实现一个生成自定义序列的srf:

表示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())
}

不过这种写法编程,对于没有接触过函数式编程的同学感觉非常痛苦,所以我们写成传统的过程化编程风格:

#[pg_extern] fn my_generate_series2(start:i64,end:i64,step:i64) ->SetOfIterator<'static, i64>{ //初始化一个集合 let mut series:Vec<i64> = vec![]; //迭代从start - end的所有数值 for x in start..=end{ //如果有setp,则满足条件在放入集合中 if x % step ==0{ series.push(x); } } //把生成的集合,放入SetOfIterator 包装类型中,返回出来 SetOfIterator::new(series) }

我们可以来看看两种不同的写法,实际上结果是一样的:

生成50000个数值,效率也是差不多的:

不过对于写过函数式编程的同学来说,第一种写法更加简洁明了……起码对于我来说,我还是喜欢第一种写法的:

下面我们来看一个小案例:

第一个是定制一个我们自己的UUID函数:

做数据库设计的时候,最头疼的问题之一是如何设计一个有意义、高性能其能保证在一定程度上不会冲突的ID。 其中一种方案就是用UUID:UUID 是 通用唯一识别码(Universally Unique Identifier)的缩写,他可以保证生成在时间和空间上的唯一编码。

虽然从PG13的版本开始,就已经提供了uuid的生成函数,但是它只能生成UUID V4版本的序列:

常用的自增 ID 缺乏随机性,且会暴露数据细节(黑客可以通过 id 的规律爬到大量数据);UUID v4 是基于随机数的,具备足够随机性,但其最大的问题就是无法排序。

而最新的UUID 7版本,已经支持了排序和大小比较,所以我们想在postgresql里面使用UUID V7版本,怎么做呢?

首先在cargo里面把需要的包导入进来:

uuid7 = "0.6.2"

然后编写一个方法:

#[pg_extern]
fn my_uuid7() -> String {
    uuid7::uuid7().to_string()
}

然后可以阔以了:

下面我们来看看效果:

生成出来的表是这样的:

做一个查询:

简单得让人难以置信……真是太残暴了……

下面来做一个数据分析中常用的操作:抽样。

例如上面那个表,我做了20万条数据数据进去,现在需要对它进行随机抽样,而且要求抽样满足各种分布,例如正态分布、均匀分布或者泊松分布以及伯努利分布……

如果仅仅是做随机抽样,那么SQL原生提供的RAND()函数就可以搞定了:

注意前面那么一堆代码,是我给这个表加了个行号,用来标识信息,否则uuid更本看不出效果来,ORDER BY random()的意思就是随机排序。

如果要做正态分布(高斯)的话,postgresql也提供了一个扩展模块:tabfunc中的normal_rand 函数:

安装好这个扩展之后,可以看见有如下函数:

例如我们可以用这个函数生成10个均值为10万,标准差为1万的数值:

然后可以用于抽样:

但是其他的分布,SQL就比较麻烦了,所以我们针对此需求,来编写一个伯努利抽样的扩展,代码如下:

  1. 直接导入Rust的随机数工具包rand(Rust的随机数包)和rand_distr(这个包用来生成泊松分布抽样),写在工程的cargo.toml配置文件里面:

  1. 编写扩展函数,代码如下:
use rand_distr::{Poisson};
#[pg_extern]
fn my_generate_possion(lambda:f64,cnt:i64) -> SetOfIterator<'static,i64>{
    let poi = Poisson::new(lambda).unwrap();
    let v = poi.sample(&mut rand::thread_rng());

    SetOfIterator::new((0..cnt).into_iter()
    .map(move |x| poi.sample(&mut rand::thread_rng()) as i64))
}

编译运行,

测试结果如下:

现在我们配合这个函数做一个泊松抽样:

打完收工

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/517678.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java面试(1)Java概述

文章目录 Java 概述1.什么是Java2. JDK1.5 之后的三大版本3. Jdk和Jre和JVM的区别4. 什么是跨平台性&#xff1f;原理是什么5. Java 语言有哪些特点?6. 什么是字节码&#xff1f;采用字节码的最大好处是什么7. 为什么不全部使用 AOT&#xff08;since JDK9&#xff09; 呢&…

马赛克处理

去取马赛克的网址&#xff1a; Redact • Photo - Free And Private Image Redaction In The Browser https://redact.photo/ REDACT.PHOTO &#xff08;照片马赛克处理在线工具&#xff09;简介 REDACT.PHOTO是一个照片马赛克处理在线工具&#xff0c;能够帮助我们非常方便…

2023自动化测试的10个最佳实践(建议收藏)

虽然大家都知道坚果是非常健康和有营养的&#xff0c;但是&#xff0c;当你尝试吃它的时候&#xff0c;我猜测过程都不会很顺利。现实就是那么相似&#xff0c;我们都知道测试自动化对软件开发有好处&#xff08;就像坚果对我们的身体一样&#xff01;&#xff09;&#xff0c;…

arcgis插件-带属性TXT转SHP数据(支持独立图层、追加到图层)

20230512记录更新 arcgis插件-带属性TXT转SHP数据&#xff08;支持独立图层、追加到图层&#xff09; 这个版本省略掉新建面图层&#xff0c;再在界面进行选择图层的操作。 界面简化到只需要一步操作&#xff0c;选择&#xff08;或者复制&#xff09;TXT文件所在路径&#x…

机器学习(二)决策树原理剖析及python实现

本篇介绍第二个机器学习算法&#xff1a;决策树算法&#xff0c;我们经常使用决策树处理分类问题&#xff0c;近来的调查表明决策树也是最经常使用的数据挖掘算法。 图1所示的流程图就是一个决策树&#xff0c;长方形代表判断模块&#xff08;decision block&#xff09;&…

[Android]AsyncChannel介绍

背景 在WifiManager.java中&#xff0c;随处可见这样的方法调用实现&#xff1a; 代码路径&#xff1a;frameworks/base/wifi/java/android/net/wifi/WifiManager.java public void connect(int networkId, ActionListener listener) {...getChannel().sendMessage(CONNECT_NE…

你真的会跟 ChatGPT 聊天吗?(下)

接《你真的会跟 ChatGPT 聊天吗&#xff1f;&#xff08;上&#xff09;》&#xff0c;本文下半部分没有无毛猫那么搞笑的内容啦&#xff01;即使如此&#xff0c;哪怕你对文中提及的技术不大了解&#xff0c;也可以毫无压力地看完这篇&#xff0c;描述如何更好地获得 ChatGPT …

视频怎么压缩到20M以内

视频怎么压缩到20M以内&#xff1f;我们知道在很多聊天软件中是限制传输的内容大小的&#xff0c;比如说视频大小会限制20M以内。还有就是我们在发一些邮件时&#xff0c;我们在上传附件的时候也是限制视频大小在20M以内。所以说我们有需要把视频压缩到20M以内的情况。那么针对…

记录一次Windows7操作系统渗透测试

#本文档仅用于实验&#xff0c;请勿用来使用恶意攻击&#xff01; 《中华人民共和国网络安全法》中&#xff0c;恶意破坏计算机信息系统罪在第二十七条被明确规定&#xff0c;规定内容为&#xff1a; 第二十七条 任何单位和个人不得为达到破坏计算机信息系统安全的目的&#x…

Linux发行版新秀:基于Ubuntu、系统核心 “不可变”

Vanilla OS 是近期才公开发布的 Linux 发行版&#xff0c;基于 Ubuntu 构建&#xff0c;免费且开源&#xff0c;默认桌面环境是 GNOME。虽然 Vanilla OS 的底层是 Ubuntu&#xff0c;但它并不是简单地基于 Ubuntu 进行 "remix"&#xff0c;而且外观看起来也不像 Ubun…

FreeRTOS:列表和列表项

要想看懂 FreeRTOS 源码并学习其原理&#xff0c;有一个东西绝对跑不了&#xff0c;那就是 FreeRTOS 的列表和列表项。列表和列表项是FreeRTOS的一个数据结构&#xff0c; FreeRTOS 大量使用到了列表和列表项&#xff0c;它是 FreeRTOS 的基石。要想深入学习并理解 FreeRTOS&am…

【LeetCode】环形链表II+结论证明

题目链接&#xff1a;环形链表II 题目&#xff1a;给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表…

Grafana系列-统一展示-7-ElasticSearch数据源

系列文章 Grafana 系列文章 ElasticSearch 数据源 Grafana内置了对Elasticsearch的支持。你可以进行多种类型的查询&#xff0c;以可视化存储在Elasticsearch中的日志或指标&#xff0c;并使用存储在Elasticsearch中的日志事件对图表进行注释。 配置 ES 数据源 关键的几项…

在两道多线程基础题“顺序打印”中对比一下Java中的wait()和join()

目录 一、基础 二、进阶 一、基础 有三个线程&#xff0c;线程名称分别为&#xff1a;a&#xff0c;b&#xff0c;c&#xff0c;每个线程打印自己的名称。 需要让他们同时启动&#xff0c;并按 c&#xff0c;b&#xff0c;a的顺序打印。 这道题要求打印 cba&#xff0c;且只打…

开发中proc文件系统的简单使用

使用proc文件系统 文章目录 使用proc文件系统1.meminfo文件2. free命令3、创建 /proc 节点4、使用 file_operations 实现 proc 文件读写 导向内核信息5、使用 seq_file 实现 proc 文件的读取 在Linux系统中&#xff0c; “/proc”文件系统十分有用&#xff0c; 它被内核用于向用…

可视化图表API格式要求有哪些?Sugar BI详细代码示例(4)

Sugar BI中的每个图表可以对应一个数据 API&#xff0c;用户浏览报表时&#xff0c;选定一定的过滤条件&#xff0c;点击「查询」按钮将会通过 API 拉取相应的数据&#xff1b;前面说过&#xff0c;为了确保用户数据的安全性&#xff0c;Sugar BI上的所有数据请求都在Sugar BI的…

进击数据基础设施新蓝海,厂商如何“择木而栖”?

文 | 螳螂观察 作者 | 李永华 多样的应用需求&#xff0c;倒逼底层存储能力不断升级&#xff1b; 复杂的数据状况&#xff0c;要求存储能够“兼容并蓄”&#xff1b; 客户企业在数字化方面的战略转型升级&#xff0c;总是触及到存储…… 当数据基础设施成为新的蓝海&#…

大学计算机基础-题库刷题-精选

题库刷题&#xff1a; 写在前面&#xff1a; 这个是我准备应对学校转专业考试而刷的题库&#xff0c; 也是大学计算机的题库&#xff0c;同样适用于大学计算机这门课的期末考试。 精选了一些重要的题目。 目录 题库刷题&#xff1a; 写在前面&#xff1a; 题目1&#x…

内卷时代,大厂产品经理仅用3步破局

本文首发自「慕课网」&#xff0c;想了解更多IT干货内容&#xff0c;程序员圈内热闻&#xff0c;欢迎关注"慕课网"&#xff01; 作者&#xff1a;申悦|慕课网讲师 在当下互联网环境下&#xff0c;产品经理究竟要如何破局&#xff1f; 我认为&#xff0c;既然要破局…

RocketMQ学习笔记:生产者Producer

DefaultMQProducer 根据上文&#xff1a;RocketMQ学习笔记&#xff1a;消息Message - 掘金 (juejin.cn)&#xff0c;我们定位到Producer中的这一行代码&#xff1a; java 复制代码 DefaultMQProducer producer new DefaultMQProducer("ProducerGroupName"); pro…