SPL 实践:数据转存时的整数化
使用SPL进行性能优化,在数据转存时将字符串等数据类型转换成整数,可以减少存储空间并提升计算性能,下面我们通过一个实际例子学习如何实现整数化。
问题描述
某时空碰撞问题的数据结构如下
字段名称 |
字段类型 |
字段注释 |
备注 |
示例数据 |
no |
String |
对象标识 |
对象的唯一标识 |
100000000009 |
ct |
Int |
时间戳 |
Unix时间戳(秒) |
1690819200 |
lac |
String |
空间标记1 |
40000 |
|
ci |
String |
空间标记2 |
66000000 |
经了解业务知道,no由全数字构成,可以直接转成Long型整数。lac、ci总是一起出现,可以合并成一个字段,称为loc。loc去重计数的范围约27万,可以用Int型整数。
no在后续计算中只有对比,不需要定位计算,所以不需要序号化,简单转换成整数即可。而loc在后续计算中会用到定位,所以要做序号化处理,即将其转换成从1开始的自然数。
整数化转存
转存后的数据结构如下
字段名称 |
数据类型 |
字段含义 |
备注 |
示例数据 |
no |
Long |
对象标识 |
对象的唯一标识 |
100000000009 |
ct |
Int |
时间戳 |
Unix时间戳(秒) |
1690819200 |
loc |
Int |
空间标记 |
空间标记的序号 |
10282 |
相比原数据结构,转存时做了以下两点变动:
1、将lac、ci两个字段合并为loc字段,并转换成Int型序号。原lac、ci作为维表单独存储。
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对应的序号
A5至A9 将no、ct有序的结果保存到组表文件
编号化还原
转存好的事实表中丢失了原lac、ci信息,需要结合转存时保存的维表信息集文件来还原。例如,要还原某计算结果序表T(no,ct,loc)的lac、ci值,代码如下:
A |
|
1 |
=file("loc_list.btx").import@b() |
2 |
=T.new(string(no):no,ct,A1(loc).lac,A1(loc).ci) |
A1 读维表
A2 T中loc的值,对应的就是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")) |
英文版