开源SPL
专业数据处理程序语言

SQL乱、JAVA繁,SPL代码真精妙!

高性能、大数据,集算神器有绝招!

01SPL是什么

SPL(Structured Process Language)专门用于结构化数据计算的程序语言
  • 1、超越数据库的计算能力
  • 2、开放的计算体系
  • 3、敏捷语法

结构化数据计算的广泛性

  • 结构化数据无处不在
  • 结构化数据计算一直是数据处理的主流
数据库
NoSQL
日常数据
工业数据
...
结构化数据是数据处理的重中之重

开源SPL竞争技术

当前处理结构化数据的程序语言主要有三类:

SQL 关系数据库的主流程序语言
Java/C#/C++ 更基础的高级语言
Python 新兴数据处理与人工智能语言
  • SQL vs 开源SPL
  • JAVA vs 开源SPL
  • Python vs 开源SPL
SQL基于50年前的 关系代数 理论 SPL基于自创 离散数据集 理论
缺乏离散性、集合化不彻底 离散与集合的充分结合
有序计算支持得很不好 超强有序计算
不提倡分步计算 提倡分步计算
➥对于复杂运算的代码冗长难写 ➥擅长实现复杂运算
难以实现高性能算法 高性能基础算法和存储机制
➥无法充分利用硬件能力 ➥充分利用硬件能力
封闭,只能计算数据库中的数据 开放,可以计算任意数据源

02SPL应用场景

数据处理与计算无处不在,而当前并没有很好的技术来解决这些问题,SPL应用场景非常多。主要分以下六个方面

Got SQL

SQL有一定的计算能力,但很多场景下没有SQL用,只能编写复杂的Java代码。SPL提供了不依赖于数据库的轻量级计算能力,可以在任意场景处理数据:

  • 结构化文本(txt/csv)计算
  • Excel计算
  • 在文件上执行SQL
  • 多层json数据计算
  • 多层xml数据计算
  • Java计算类库,超越Stream/Kotlin/Scala
  • 取代ORM实现业务逻辑
  • Mongodb上的SQL式计算,关联运算
  • WebService/Restful的后计算
  • Salesforce的后计算,SAP的后计算
  • 各种数据源的后计算:HBase,Cassandra,Redis,ElasticSearch,Kafka,…

文件计算

可以通过SPL原生语法进行文件计算,同时支持SQL查文件,简单方便

  • 提供两种文件计算方式
  • 熟悉SQL可以零成本上手

MongoDB计算

SPL可以强化MongoDB计算能力,
简化计算过程

  • 使得MongoDB达到或强于RDB的计算能力
  • 增强计算能力后,充分发挥MongoDB原有优势

多样性数据源计算

SPL提供不依赖数据库的计算能力,完成各类数据源的后计算工作

Beyond SQL

对于复杂的集合和有序运算很难处理,常常还要读出来再用Java计算。SPL有彻底的集合化能力,特别支持有序和分步计算,可以简化这些运算:

  • 有序集合
  • 位置引用
  • 分组子集
  • 非等值分组
  • 多层关联运算
  • 静态和动态转置
  • 递归与迭代计算
  • 分步及循环运算
  • 集合式文字运算和日期时间运算

SQL与SPL对比

集合化
SQL集合化不够彻底
  • 无法描述集合的集合
  • 字段取值不能再是集合

SPL提供更丰富的
  • 集合运算库
  • 支持lambda语法
  • 支持动态数据结构
离散性
SQL缺乏离散性
  • 没有天然序号,引用集合指定成员很麻烦
  • 只有单行记录的表,没有游离记录

SPL提供更丰富的
  • 只有单行记录的表,没有游离记录
  • 方便单独引用
更彻底集合化
SPL离散性支持下的集合化
  • 彻底的集合化需要离散性的支持
  • 允许游离成员组成新集合
  • 有序计算是集合化与离散性的结合物

SQL与SPL对比举例

计算目标:某支股票最长连续涨了多少交易日
select max(continuousDays)-1
from (select count(*) continuousDays
	from (select sum(changeSign) over(order by tradeDate) unRiseDays
		from (select tradeDate,
			case when closePrice>lag(closePrice) over(order by tradeDate)
			then 0 else 1 end changeSign
		from stock) )
	group by unRiseDays)
SQL解法

SQL在使用窗口函数的情况下嵌套三层完成;

前面读懂了吗?


A
1 =stock.sort(tradeDate)
2 =0
3 =A1.max(A2=if(closePrice>closePrice[-1],A2+1,0))
SPL解法

其实这个计算很简单,按照自然思维:先按交易日排序(行1),然后比较当天收盘价比前一天高就+1,否则就清零,最后求个最大值(行3)

举例:返回集合的聚合

计算任务:列出每个用户最近一次登录间隔
WITH TT AS
	(SELECT RANK() OVER(PARTITION BY uid ORDER BY logtime DESC) rk, T.*  FROM t_loginT)
SELECT uid,(SELECT TT.logtime FROM TT where TT.uid=TTT.uid and TT.rk=1)
		-(SELET TT.logtim FROM TT WHERE TT.uid=TTT.uid and TT.rk=2) interval
FROM t_loginTTTT GROUP BY uid

聚合函数返回值不一定是单值,也可以返回一个集合

彻底的集合化后很容易针对分组子集实施返回集合的聚合运算

A
1 =t_login.groups(uid;top(2,-logtime)) 最后2个登录记录
2 =A1.new(uid,#2(1).logtime-#2(2).logtime:interval) 计算间隔

举例:跨行引用

计算任务:计算每月前后各一个月的销售额移动平均值
WITH B AS
	(SELECT LAG(amount) OVER (ORDER BY 月份) f1, LEAD(amount) OVER (ORDER BY smonth) f2,   A.* FROM orders A)
SELECT smonth,amount,
	(NVL(f1,0)+NVL(f2,0)+amount)/(DECODE(f1,NULLl,0,1)+DECODE(f2,NULL,0,1)+1) moving_average
FROM B

窗口函数只有简单的跨行引用,涉及集合要用成员去拼

有序集合上可提供跨行集合引用方案

A
1 =orders.sort(smonth).derive(amount[-1,1].avg()):moving_average)

举例:有序分组

计算任务:一支股票最长连续上涨了多少天
SELECT max(consecutive_days)-1 FROM 
	(SELECT count(*) consecutive_days FROM 
		(SELECT SUM(updown_flag) OVER ( ORDER BY trade_date) nonrising_days FROM 
		( SELECT trade_date,
			CASE WHEN  close_price>LAG(close_price) OVER( ORDER BY trade_date THEN 0 ELSE 1 END updown_flag
		FROM stock ))
	GROUP BY nonrising_days )

另一种和次序有关的分组,条件成立时产生新组

A
1 =stock.sort(trade_date).group@i(close_price<close_price [-1]).max(~.len())

Cooperate DB

数据库的计算能力是封闭的,无法处理数据库外的数据,常常需要先做ETL导入同一个数据库后才能处理。 SPL提供了开放简易的计算能力,可以直接读取多个数据库实现混合数据计算,协助数据库做更好的运算。

  • 并行取数加速JDBC
  • 不同类型数据库的SQL移植
  • 跨数据库的运算
  • T+0统计查询
  • 替代存储过程运算,提高代码可移植性、降低耦合性
  • 避免ETL做成ELT甚至LET
  • 多样数据源的混合计算
  • 减少数据库中的中间表
  • 报表数据源开发,支持热切换、多样数据源、提高开发效率
  • 微服务实现,占用更少资源,可热切换

RDB协助

SPL辅助RDB计算,提升RDB能力

  • SQL迁移将标准SQL转化为各类数据库“方言”
  • 并行取数提升性能
  • 跨库/异构库计算进一步增强RDB能力

替代存储过程

存储过程的目的
  • 数据整理
  • 呈现准备
存储过程的问题
  • 造成应用内与应用间耦合
  • 安全性低
  • 移植性差

数据库解耦

  • 将存储过程和中间表外置到应用中
  • 数据库仅承担存储和少量(通用)计算
  • 应用与数据库解耦,易维护,易扩展

跨库集群

借助SPL的跨库与并行能力实现多数据库集群计算


T+0查询

T+0问题
  • 交易一致性要求关系数据库
  • 历史与当期同库,数据量太大
  • 历史与当期异库,跨库计算困难
并行跨库计算实现T+0
  • 历史数据还可文件化

ETL

传统ETL往往先L再ET,费时费力;通过SPL可以实现真正的ETL过程

ETL复杂计算
  • 库外处理,为数据库减负
  • 减少IO,缩短时间窗口
  • 实现简单灵活
  • 允许多源混合处理

微服务协助

微服务的数据处理往往要依靠Java硬编码,复杂计算实现困难。
SPL与微服务框架结合实施数据处理比其他开发语言更简洁、高效。

Surpass DB

SQL难以实现高性能算法,大数据运算性能只能指望数据库的优化引擎,但复杂情况常常靠不住。
SPL提供大量基础高性能算法(有许多是业界创新)以及高效的存储格式,同等硬件环境下可以获得远超过数据库的运算性能,可以全面替代大数据平台与数据仓库

  • 内存查找:二分法、序号定位、位置索引、哈希索引、多层序号定位
  • 外存数据集: 文本文件并行、二进制存、倍增分段、列存组表、有序存储与更新
  • 外存查找:二分法、哈希索引、排序索引、行存和带值索引、索引预加载、批量查找与集合查找、多索引归并、全文检索
  • 遍历技术:游标后过滤、遍历复用、并行遍历与多路游标、聚合扩展、有序遍历、程序游标、半序分组与排序、序号分组与可控分段
  • 关联技术:外键地址化、外键序号化、索引复用、对位序列、大维表查找、单边分堆、有序归并、关联定位、附表
  • 多维分析:预汇总与时间段预汇总、对位序列、标签位维度
  • 分布式:自由计算与数据分布、集群复组表、集群维表、冗余式容错、备胎式容错、Fork-Reduce、多作业负载均衡

计算性能的决定性因素

  • 计算效率取决于硬件和软件两方面
  • 软件性能就是算法效率
  • 算法效率由算法设计和算法实现共同决定
  • 好算法只想得出,实现不了也是徒劳
  • 缺乏高性能机制的编程语言会限制好算法的实现

没有火药,无论如何也造不出枪炮

根本原因

结构化数据是重点

  • 当前数据计算仍以业务系统产生的结构化数据为主
  • 业界在提升结构化数据计算性能时主要依靠大内存、大集群
  • 大内存、大集群的实质是纵向或横向提升硬件能力
  • 而软件核心仍然使用SQL为主的关系代数体系
  • SQL过于粗线条,很多高性能算法都无法实现

SQL很难实现高性能结构化数据计算

重点问题

数据库为什么跑不快?

  • SQL难以实现高效算法的原因在于其理论体系(关系代数)
  • 理论上的缺陷很难通过工程实现来弥补
【举例】1亿行数据取前10名在SQL下会怎么做?
  • SQL语句的原理是将所有数据大排序,然后取前10名,效率很低
  • 有不必大排序的办法实现这个运算,却无法用SQL表达
  • 只能用指望数据库引擎自动优化,但复杂情况时数据库并不会优化

好算法不光要想出来,还要能实现

高性能的本质是开发效率问题,要能想得到、方便写得出

高性能算法与存储方案

内存查找
  • 二分法
  • 序号定位
  • 位置索引
  • 哈希索引
  • 多层序号定位
外存数据集
  • 文本文件的分段
  • 集文件及倍增分段
  • 数据类型
  • 组表与列存
  • 有序与补文件
  • 数据更新及复组表
外存查找
  • 二分法
  • 哈希索引
  • 排序索引
  • 行存和带值索引
  • 索引预加载
  • 批量查找
  • 返回集合的查找
  • 多索引归并
  • 全文检索
遍历技术
  • 延迟游标
  • 遍历复用
  • 并行遍历
  • 数据库并行加载
  • 多路游标
  • 分组汇总
  • 聚合理解
  • 冗余分组键
有序遍历
  • 有序分组汇总
  • 有序分组子集
  • 程序游标
  • 前半序分组
  • 后半序分组
  • 序号分组与可控分段
  • 索引排序
外键关联
  • 外键地址化
  • 临时地址化
  • 外键序号化
  • 内连接语法
  • 索引复用
  • 对位序列
  • 大维表查找
  • 单边分堆
归并与连接
  • 有序归并
  • 分段归并
  • 关联定位
  • 附表
多维分析
  • 部分预汇总
  • 时间段预汇总
  • 冗余排序
  • 对位序列
  • 标签位维度
  • 内存标签异动
集群
  • 计算与数据分布
  • 集群复组表
  • 复写维表
  • 分段维表
  • 冗余式容错
  • 备胎式容错
  • 多作业负载均衡

这里许多算法都是开源SPL的发明!

高性能算法举例

聚合理解
  A  
1 =file("data.ctx").create().cursor()  
2 =A1.groups(;top(10,amount)) 金额在前10名的订单
3 =A1.groups(area;top(10,amount)) 每个地区金额在前10名的订单

高复杂度的排序转换为低复杂度的聚合

遍历复用
  A  
1 =file("order.ctx").create().cursor() 准备遍历
2 =channel(A1).groups(product;count(1):N) 配置复用计算
3 =A1.groups(area;sum(amount):amount) 遍历,并获得分组结果
4 =A2.result() 取出复用运算的结果

一次遍历可返回多个结果集

SPL性能表现

硬件配置:Intel3014 1.7G/12核/64G内存;ARM/16核/32G内存

同等硬件环境SPL性能远超Oracle;
甚至SPL使用低端芯片都可以超越高端芯片的Oracle

【应用案例】手机银行:活期明细大并发有关联查询优化

并发访问巨大

手机银行、网银几十万、上百万并发明细查询

ES不支持关联

明细与机构等维表关联无法实现,要宽表冗余

维表更新耗时长

维表数据调整,要全量更新宽表数据

利用客户数据特征按照客户号有序存储;维表内存;横向扩展简便、低成本

【应用案例】用户画像:客群交叉统计实时计算提速

数据量巨大

上亿客户与几千客群多对多关系,几十个维度

无法预计算

几千个客群,任选几个交叉,排列组合太多

实时计算困难

数据库实时算交集并维度过滤,不能秒级响应

有序按位存储:1个字段存16个客群;一次遍历完成客群交集、维度过滤计算

For Excel

分析处理Excel的三种方式

BI工具
  • 只能实施规整计算
  • 无法完成数据准备
数据工具
  • 只能处理模式化的计算
  • 无法完成灵活的复杂计算
编程
  • 可以处理所有情况

八成以上数据处理和计算的需求无法用可视化工具完成

结论:编程是处理结构化数据很有效的方式,但Python等编程语言并不好用

SPL提供面向Excel的集合运算

格值与汇总值计算

  • 使用相邻行和区间计算
  • 可能提前终止的累计
  • 同类数据连续时使用同类相邻行计算
  • 同类数据不连续时使用同类相邻行计算
  • 使用同类数据的汇总信息
  • …….

集合运算和从属判断

  • 简单成员的交并差
  • 行式数据求交并差
  • 不确定数量的集合求交并差
  • 集合相等与从属判断
  • 次序无关的集合相等与从属判断
  • ……

重复判断、计数与去除

  • 判断是否有与自己重复的数据
  • 统计重复次数
  • 不确定多列一起统计重复次数
  • 行式数据去重
  • 简单数据去重
  • …….

排序与排名

  • 按指定次序对齐排列
  • 指定次序有重复值的对齐
  • 将并列排名的成员拼接起来
  • 在相同分类内排序
  • 分类下的排名
  • ……

特殊分类和汇总方法

  • 每N个成员分成一组
  • 使用相邻数据作为分组条件
  • 碰到空行或非空行时分组
  • 按数据值的间隔分组
  • 将分类内的数据拼接成文字
  • ……

关联与比对

  • 关联表引用
  • 区间关联
  • 二维关联表
  • 使用区间范围倒查关联表
  • 关联多行数据
  • ……

行列转换

  • 固定列的行转列
  • 行式表与交叉表互换
  • 行列的高层分类互转
  • 分类内数据横向拼入列
  • 分类数据拼入列时要再分类或排序
  • ……

扩展与补齐

  • 生成连续的区间
  • 根据数值将一行扩展出多行
  • 拆分文字后扩展成多行
  • 在连续值中补足缺失部分
  • 每隔N行补足若干空行
  • ……

Excel配合举例

SPL与Excel配合可以增强Excel计算能力,降低计算实施难度

使用剪贴板

通过SPL的Excel插件可以在Excel中使用SPL函数进行计算,也可以在VBA中调用SPL脚本

Excel加载SPL插件
Excel中使用SPL函数实施计算
VBA中调用SPL脚本完成计算

For Industry

工业场景中有大量时序数据,而时序数据库常常只提供SQL,SQL的有序计算能力本来很弱,结果只用于取数,无法协助计算。
工业场景中还常常会涉及许多基础数学运算,SQL缺乏这些函数,只能读出来再处理。
SPL能很好地支持有序计算,而且提供了丰富的数学函数,如矩阵、拟合等,能够更方便地应对工业场景的计算需求。

  • 时序游标:按粒度聚合、平移、相邻引用、关联合并
  • 历史数据压缩固化,透明引用
  • 向量与矩阵运算
  • 各种线性拟合:最小二乘、偏最小二乘、lasso、ridge、…

工业算法常常需要反复实验,SPL开发效率极高,同时间内可以尝试更多:

  • 仪表异常发现算法
  • 异常测量样本定位
  • 曲线升降及振荡模式识别
  • 有约束线性拟合
  • 管道传输调度算法
  • ...

应用举例:有约束的线性拟合

背景:炼油厂希望从历史数据中学到相对准确的产品收率,并利用它来制定第二天或者未来一段时间的原料加工及产品产量计划

目标:使用线性拟合的方式在有约束条件的情况下,利用历史生产数据拟合出一套系数(称为收率),使拟合收率计算得到的产品产量与实际产量的误差尽量小

使用SPL可以快速准确地实现该算法,从而预测产量

应用举例:特征筛选曲线

时间序列走势在一定程度上反应实际生产状况,称为工况。如曲线走势平稳表示正常,快速上升或快速下降表示可能有异常情况发生。将曲线走势与工况对应,有助于分析生产活动中存在的问题,提高生产效率

使用SPL可以快速准确地实现该算法,从而准确识别各种特征曲线

应用举例:异常发现

炼油厂通常有几十套装置,每套装置的仪表数量是成百上千的,无法依靠人工观察发现异常,需要相应算法来识别

使用SPL可以快速准确地实现该算法,从而准确识别出各类异常值

03SPL技术介绍

  • 1、简洁易用的开发环境
  • 2、专门设计的语法体系
  • 3、丰富的运算类库
  • 4、多样性数据源
  • 5、外部数据接口
  • 6、集成性
  • 7、热切换
  • 8、多线程并行
  • 9、高性能存储
  • 10、分布式计算

简洁易用的开发环境


专门设计的语法体系

SPL特别适合复杂过程运算

丰富的运算类库

专门针对结构化数据表设计


多样性数据源

直接使用多个数据源混合计算,无需后台先将数据统一(ETL)后再计算

外部数据接口

  • 商用 RDBMS:Oracle、MS SQL Server、DB2、Informix
  • 开源 RDBMS:MySQL、PostgreSQL
  • 开源 NOSQL:MongoDB、Redis、Cassandra、ElasticSearch
  • Hadoop家族:HDFS、HIVE、HBase
  • 应用软件:SAP ECC、BW
  • 文件:Excel、Json、XML、TXT
  • 其他:Http Restful、Web Services、OLAP4j 、...
内置接口,即装即用

集成性

SPL使用JAVA开发,提供标准应用接口可无缝集成到应用中


热切换

SPL解释执行,支持不停机热切换


多线程并行

方便地针对单任务实施多线程计算

高性能存储

高性能数据存储

私有数据存储格式,集文件、组表

文件系统存储形式

支持以树状目录方式按业务分类存储数据

集文件

  • 倍增分段方式支持任意数量并行
  • 自有高效压缩编码(减少空间;CPU占用少;安全)
  • 泛型存储,允许集合数据

组表

  • 行列混合存储
  • 有序存储提高压缩率和定位性能
  • 高效智能索引
  • 倍增分段方式支持任意数量并行
  • 主子表合一减少存储与关联
  • 排号键值实现高效定位关联

分布式计算

数据容错和计算容错

提供内外存两种数据容错机制,外存冗余式容错,内存备胎式容错

支持计算容错,节点故障时自动将该节点计算任务迁移掉其他节点继续完成

可控数据分布

用户可根据数据和计算任务的特点灵活定制数据分布及冗余方案,有效减少节点间数据传输量,以获得更高性能

无中心架构,避免单点失效

集群没有永久的中心主控节点,程序员用代码控制参与计算的节点

负载均衡能力

根据每个节点空闲程度(线程数量)决定是否分配任务,实现负担和资源的有效平衡

结构化数据新代数

离散数据集超越关系代数

自主创新程序语言

SPLoverSQL