Kotlin 能取代 SQL 吗?

 

Kotlin 以 Stream 为基础并针对其缺点进行了改进,简化了 Lamda 语法,增加了集合计算,并补充了很多集合函数,代码更简短易懂。但 Kotlin 还是无法代替 SQL。

和 Stream 类似,一旦数据对象变成记录,不是简单数据类型,就不那么方便了。Kotlin 仍然没有提供专业的结构化数据对象,同样不支持动态数据结构,必须先定义结果的数据结构再计算,SQL 程序员很难适应这种死板的用法。相对的,SQL 是解释型语言,不必事先定义数据结构。

其实对于大多数习惯用 SQL 操作数据的程序员,如果使用Open-esProc计算包,在没有 SQL 时也能获得 SQL 的好处,只需在程序中调用其封装后 SPL 计算脚本,例如 “找出英语平均分低于 70 分的班级”,大多数数据库这样操作,“select CLASS,avg(English) as avg_En from students_scores group by CLASS having avg(English)<70”,用 SPL 代码实现如下:


A

1

=file(“E:/txt/Students_scores.csv”).import@tc()

2

=A1.groups(CLASS;avg(English):avg_En)

3

=A2.select(avg_En<70)

完成上述任务,直接用 Kotlin 其实也不复杂,但没有用 SPL 简单易学。将脚本文件(比如 condition.dfx)和 Java 存储在一起,通过 JDBC 接口在 JAVA 中调用,用法类似存储过程。这样,SPL 计算过程都是独立的,当遇到需求变动后,改动也非常方便。

…
 ResultSet result = statement.executeQuery("call condition.dfx");
…

SPL 也支持类似 SQL 的用法,无须脚本文件,直接将其嵌入 JAVA

…
 ResultSet result = statement.executeQuery("
=file(\“E:/txt/Students_scores.csv\”).import@tc()
.groups(CLASS;avg(English):avg_En).select(avg_En<70)");
…

SPL 中还提供了用 SQL 查询数据的方法,方便熟悉 SQL 的程序直接使用。比如:州信息,部门信息和员工信息分别存储在三个文本文件中(将三个文件换成三个 SPL 序表对象也同样成立),查询经理在 California 州的 New York 州员工。


A

1

$select   e.NAME as ENAME
from   E:/txt/EMPLOYEE.txt  as e
     join E:/txt/DEPARTMENT.txt as d on   e.DEPT=d.NAME
     join E:/txt/EMPLOYEE.txt  as emp on d.MANAGER=emp.EID
where   e.STATE='New York' and emp.STATE='California'

当数据很大时,内存大小就会形成处理的瓶颈,SPL 还通过游标读取的方式,类似数据库中的游标,做小批量读取,然后在游标上绑定计算,实现排序、关联和分组计算,这样就可以利用小内存完成大数据的计算。


A

1

=file("E:/txt/Employees.txt").cursor@t().sortx(EId)

2

=file("E:/txt/Orders.txt").cursor@t().sortx(SellerId)

3

=joinx(A2:O,SellerId; A1:E,EId)

4

=A3.groups(E.Dept;sum(O.Amount))

大数据处理经常需要加入并行计算提高计算效率,每个线程各自计算的方式处理一段数据,最后将各线程处理的结果进行汇总。

A
1 =file(“E:/txt/user_info_reg.csv”).cursor@tcm(;4)
2 =A1.groups(id_province;count(~):cnt)

在 SPL 中使用并行提速非常容易,@m 表示并行计算,参数 4 表示 4 路并行,与单线程代码相比,仅仅多一个游标选项与参数,让用户使用并行非常方便。

利用 SPL 可以极大简化 Java 程序中的结构化数据计算,示例总结整理如下:

集合上的循环运算

序号访问成员

有序集合上的定位计算

有序集合上的对位运算

TopN 运算

存在判断

从属判断

非常规聚合

对齐分组

选出运算

更多计算示例,参见 SPL 应用计算