前文再续,书接上一回。
上一回我们解析了如何通过pgrx编写srf,返回一个TableIterator,但是在具体应用的时候,我们还是针对一条记录返回了一行数据(多个字段的一行,也还是一行),并没有实现通过一行数据库记录,实现多行表序列的转换,今天我们就来写几个示例,来表现一下这pgrx的这个能力。
测试数据如下:
例如,其中values每天的平均空气质量(随机模拟数据,不要在意这些细节)
需求:给每天的value上面,编上日期编号,也就是原始库中的一条数据,会被平铺成28-31条不等。
代码如下:
#[pg_extern]
fn get_day_value(value:Vec<i32>) ->
TableIterator<'static,(name!(day,i32),name!(value,i32))>{
let mut res:Vec<(i32,i32)> = Vec::new();
for idx in 0..value.len(){
res.push((idx as i32+1,value[idx]))
}
TableIterator::new(res)
}
测试效果如下:
用真实数据来跑一下:
效果完全么得问题,下面就可以直接通过数据库函数来做一些计算了,比如求每个站点每个月的最大值:
其实就具体工作来说,很少把数据直接存成这个样子,然后还要直接使用SQL来进行花式操作的——SQL的全称就叫做“Structured Query Language”,结构化查询语言,只有数据满足结构化范式,才能发挥出SQL的最佳效果,虽然数据库支持各种ARRAY或者JSON,只要搞成了非结构化,SQL效果肯定不是那么好用的。
当然,如果有人要问,SQL不是最好的选择,那么真实的要处理这种情况,啥是最好选择呢?当然是DBC……直接通过数据库连接读到具体的程序应用中来进行更复杂的一些操作和逻辑处理……
属于是ETL基本功了。
不过这个方法,我经常用来做模拟数据……因为我很多时候都在做算法示例,模拟数据对我的工作有至关重要的作用:
下面我用TableIterator来做一个模拟数据生成函数:
代码如下:
/**
* 随机生成一个5个字段的表格
*
*/
#[pg_extern]
fn get_random_table(num_rows: i32) ->
TableIterator<'static, (
name!(id,i32),
name!(gid,String),
name!(username, String),
name!(age,i32),
name!(sale, f32)
)> {
let mut rd = thread_rng();
//使用函数式编程实现
TableIterator::new((1..=num_rows).map(move |i| (i,
uuid7::uuid7().to_string(),
Alphanumeric.sample_iter(&mut rd).take(8).map(char::from).collect::<String>(),
rd.sample(Uniform::new(25, 50)) as i32,
rand::random::<f32>())))
}
结果如下:
当然,每次运行这个函数结果都不一样,所以我们可以通过这个函数来生成一个模拟数据的表格,下面就可以生成一个1000条记录的模拟数据表格:
之后需要的话,就可以在这个表格上进行测试工作了。
感觉怎么说的呢?
对了:
造假一时爽……
一直造假一直爽……
打完收工。