SPL 实践:数据转存时的整数化

使用SPL进行性能优化,在数据转存时将字符串等数据类型转换成整数,可以减少存储空间并提升计算性能,下面我们通过一个实际例子学习如何实现整数化。

问题描述

某时空碰撞问题的数据结构如下

字段名称

字段类型

字段注释

备注

示例数据

no

String

对象标识

对象的唯一标识

100000000009

ct

Int

时间戳

Unix时间戳(秒)

1690819200

lac

String

空间标记1


40000

ci

String

空间标记2


66000000

经了解业务知道,no由全数字构成,可以直接转成Long型整数。lacci总是一起出现,可以合并成一个字段,称为locloc去重计数的范围约27万,可以用Int型整数。

no在后续计算中只有对比,不需要定位计算,所以不需要序号化,简单转换成整数即可。而loc在后续计算中会用到定位,所以要做序号化处理,即将其转换成从1开始的自然数。

整数化转存

转存后的数据结构如下

字段名称

数据类型

字段含义

备注

示例数据

no

Long

对象标识

对象的唯一标识

100000000009

ct

Int

时间戳

Unix时间戳(秒)

1690819200

loc

Int

空间标记

空间标记的序号

10282

相比原数据结构,转存时做了以下两点变动:

1、将lacci两个字段合并为loc字段,并转换成Int型序号。原lacci作为维表单独存储。

2、将数字串no的数据类型变为Long型整数。

代码如下:


A

1

=connect@l("oracle12c")

2

=loc_list=A1.query("SELECT DISTINCT lac,ci FROM testdata").keys@i(lac,ci)

3

=file("loc_list.btx").export@b(A2)

4

=A1.cursor@x("SELECT no,ct,lac,ci FROM testdata").new(long(no):no,int(ct):ct,loc_list.pfind(lac,ci):loc)

5

=file("tmp.btx").export@b(A4)

6

=file("tmp.btx").cursor@b().sortx(no,ct)

7

=file("1.day.ctx").create@y(#no,#ct,loc)

8

>A7.append@i(A6)

9

=movefile(file("tmp.btx"))

A1 连数据库,@l选项代表返回的字段名和表名为小写

A2 从数据库取出空间标记去重的结果,并建立索引

A3 将空间标记维表信息保存到集文件

A4 从数据库取数的同时,将no转为长整型,利用索引从loc_list中查出loc,ci对应的序号

A5A9 noct有序的结果保存到组表文件

编号化还原

转存好的事实表中丢失了原lacci信息,需要结合转存时保存的维表信息集文件来还原。例如,要还原某计算结果序表T(no,ct,loc)lacci,代码如下:


A

1

=file("loc_list.btx").import@b()

2

=T.new(string(no):no,ct,A1(loc).lac,A1(loc).ci)

A1 读维表

A2 Tloc的值,对应的就是A1中维表记录的序号,所以直接A1(loc).对应的字段即可

新增数据处理

数据会不断增加,新增数据上的空间标记也可能是新的,要在原维表上追加新的空间标记数据,如下:


A

1

=file("loc_list.btx").import@b().keys@i(lac,ci)

2

=connect@l("oracle12c")

3

=A2.query@x("SELECT DISTINCT lac,ci FROM testdata where ct >="/(long(date(now()))\1000))

4

=A3.select(!A1.find(lac,ci))

5

=file("loc_list.btx").export@ab(A4)

这样,在新一天的数据转存时,使用追加后的维表集文件loc_list.btx即可,不会影响原空间标记序号的对应关系,代码如下:


A

1

=connect@l("oracle12c")

2

=loc_list=file("loc_list.btx").import@b().keys@i(lac,ci)

3

=A1.cursor@x("SELECT no,ct,lac,ci FROM testdata where ct >="/(long(date(now()))\1000)).new(long(no):no,int(ct):ct,loc_list.pfind(lac,ci):loc)

4

=file("tmp.btx").export@b(A3)

5

=file("tmp.btx").cursor@b().sortx(no,ct)

6

=file("2.day.ctx").create@y(#no,#ct,loc)

7

>A6.append@i(A5)

8

=movefile(file("tmp.btx"))