表工具是一个历史比较悠久的软件类产品了,已经有20年以上的发展历史了,在这20多年中,产品在不断的更新迭代,不断的随着需求的改变而进步完善,持续发挥着自己的价值
在这无数次的更新迭代中,又有两次比较大的变革,极具重要意义,可以算作是工具发展史上的两大里程碑式的革命,对软件的发展走向起到了决定性的作用
先回顾第一次革命
第一次革命发生在 表工具诞生的初期,当时基础类,工具类软件,基本都是国外软件的天下, 表工具似乎也不例外,外国人带着他们的 表工具进入中国,也想像数据库一样,占领和收割国内的庞大软件市场,但是这一次他们折戟了,国外的 表工具不仅没有成功,反而是被国产的工具打的落花流水,甚至连开源免费的也被打趴下了
为什么一向厉害的国外软件在 表领域却没有打败国产的呢/p>
刚进入国内的国外 表软件,其实在前期也打开了一定的市场,形成了一定的规模,知名度也挺高,比如水晶 表,但是很快就漏出疲态,由于产品处于初期阶段,而且欧美人的表格可能也比较简单,这些国外 表工具,使用上很不方便,只能做简单的表格
可以看看下面这俩,看着就有点蒙圈,不知道该怎么弄了,完全和我们平时看到的表格不一样,增加学习成本不说,即使学会了也不用,做不了复杂的表格
这时候, 表工具的第一次革命就来了
面对这些国外工具解决不了的难题,国内 表工具的代表厂商,润乾 表,在研究了无数复杂表样后,开发出了全新一代的类EXCEL的工具,创造出了独一无二的非线性 表模型,不仅学习简单,操作方便,而且可以轻松做出各类中国式复杂 表
这次革新,不仅让国产软件打败了国外软件,而且国产厂商也重新定义了 表软件的标准,此后的工具,就全都是好用的EXCEL方式的操作,和模仿非线性 表的复杂 表模型了
再来说第二次革命
一次革命后,复杂 表的制表方面的难题就基本都解决了
但随着行业的发展,我们又慢慢发现,虽然 表工具已经很牛,什么复杂表格都能做,但有些时候, 表开发还是很让人头疼,因为给 表准备数据有时候是一件更困难的事情
然而恰恰是这仅占 20% 的需要硬编码来做复杂数据准备的工作,却占了我们 80% 的工作量
SPL是一个中间计算层,类似于数据中台,它可以轻松解决项目中的数据准备开发难题,可以优化应用结构,提升运算性能
SPL做好数据准备后+ 表工具实现
一致的多样性数据源支持
如果采用SPL准备数据,则可以直接用这些非数据库数据作为数据源去生成 表,不需要导入数据库的过程,减少开发工作量
比如:json文件存储了客户名单及其销售额,要找出销售额累计占到一半的前n个大客户,并按销售额从大到小排序
A | B | |
---|---|---|
1 | =json(file(“d:sales.json”).read()).sort(amount:-1) | 取数并逆序排序 |
2 | =A1.cumulate(amount) | 计算累计序列 |
3 | =A2.m(-1)/2 | 最后的累计值即是总和 |
4 | =A2.pselect(~>=A3) | 超过一半的位置 |
5 | =A1(to(A4)) | 按位置取值 |
更多例子可以参考: 表工具怎样使用 Json/XML 的数据
而且一般 表工具使用的数据集都是类似SQL返回的那种单层二维表,碰到象json或XML这类多层数据只能先转换成多个单层数据集,再在 表模板中关联运算拼接成多层 表。而SPL可以直接支持多层数据集计算,不需要做这个转换,减少工作量,润乾 表也可以接受SPL返回的多层数据集直接按层次呈现,不需要在 表中再做关联
类似地,MongoDB也支持多层数据,也可以用SPL直接计算并返回给润乾 表
另外数据库还包括NoSQL数据库、文件包括HDFS文件,对于SPL来讲都是数据源。SPL自有的计算能力可以使这些计算能力不一的多样性数据获得通用一致的计算能力。比如文件几乎没有计算能力,MongoDB对JOIN和GROUP运算支持不足,各家数据库对窗口函数的支持程度不同、日期与字串处理能力也普遍不足且风格迥异。采用SPL后可以用相对一致的方案来计算,而这将意味着更低的移植成本以及学习难度
而且用SPL辅助计算后还可以保留非关系数据库原有的优势。比如MongoDB的对追加型日志数据的吞吐能力就远远超过普通关系数据库,但结构化计算能力较弱,用SPL来弥补后,数据可以继续留在MongoDB中,即获得其高吞吐性能也有了结构化计算能力。
优化 表应用结构
集算器SPL的设计初衷是提升数据准备过程的开发效率,但实际应用下来我们发现,SPL不仅提升了数据准备的效率,同时还优化了应用的结构,这个能力,也非常有意义
解释执行降低应用耦合度
我们知道,JAVA应用大多数情况是事先编译并静态加载的,也就是要把所有模块一起编译打包后部署,在运行过程中代码就不再改变了。其实JAVA也有动态编译和加载的技术,但难度和复杂度都高很多,一般应用程序员很少使用。而且即使采用了动态加载技术,也不能替换已经加载进内存的类,只能不断新增新的类
这种机制下,用JAVA编写的 表数据准备算法就需要和主应用程序一起打包发布,这会导致 表模块与主应用之间的高耦合性
如果用SPL来实现数据准备算法,就能有效地降低主应用程序与 表功能的耦合度了
SPL写出来的脚本也是类似 表模板的外置文件,不需要和主应用程序一起编译打包,而且它是解释执行的动态语言,在修改时不会涉及主应用程序,只要把SPL脚本替换就可以,天然就支持热切换
那么为什么要把这些中间结果存到数据库中,而不能存放到文件系统中呢/p>
这是因为我们不可能为每个 表的每种参数组合事先计算中间结果,在生成 表时还需要根据参数进行计算,也就是要求这些中间结果仍有计算能力,而目前只有数据库有这种计算能力,文件是没有计算能力的,于是中间数据就只能变成中间表
中间数据一般都是由不再改变的历史数据计算出来的,完全不需要数据库的事务一致性能力,因为都是导出的冗余数据,也不需要很高的稳定要求,数据坏了重算一次就行了,存放在数据库中仅仅为了获得计算能力,实在是划不来的
有了SPL后,就可以将中间数据外置到文件系统中,由SPL提供针对文件的计算能力,可以有效地减少中间表,不必再让这些冗余数据继续占用昂贵并且低效的数据库空间
外置的中间数据文件还可以使用文件系统的树形结构管理,与 表模板及数据准备算法统一存储。这不仅管理简单方便,而且,由于不考虑写入和一致性的需求,文件还会比数据库有更好的IO吞吐性能,整体提高 表的运算速度
混合运算实现T+0 表
关系数据库的事务一致性能力目前尚没有有效的替代者,交易系统仍然有必要使用关系数据库来建设
这种情况下,要实现T+0全数据量的实时 表,我们就得把历史数据继续存放在当期的交易数据库中一起计算,历史数据常常要庞大得多,这会要求我们建设更大容量的数据库,成本当然会很高。而且即使愿意支付成本,这个数据量也不可能一直增长,太大了会影响到交易业务的性能,这就不可容忍了
通常的办法是把部分历史数据被移出来做个分数据库,这样可以保证交易系统的正常运转,但要实现T+0 表就麻烦得多,会涉及到跨库运算
许多数据库都支持跨库运算,但一般都要求同类型的数据库,但历史数据和当期交易数据的要求不同,数据量更大但不要求事务一致性,很可能使用另一种数据仓库来存储
而且,即使是同构的数据库,数据库的跨库运算的方法一般也是将另一个库中的数据表映射成本库数据表,实际运算还是一个数据库在做,而且还多出许多数据传递的通讯成本,性能和稳定性都不好
使用SPL就可以很好地完成这个混合计算任务了
而恰恰这两个环节又都是 表工具无能为力的地方
提升数据准备的性能
前面我们已经说到,在数据准备方面,很多场景下SPL比大段的SQL,存储过程以及JAVA要写起来更容易,降低了数据准备的开发难度
事实上,SPL不仅可以降低开发难度,还可以提升数据准备的效率和性能
我们通过一个简单小例来看一下 SPL 比 SQL 的算法高效在哪里
比如要在 1 亿条数据中取出前 10 名,用 SQL 算就会涉及大排序,大排序就会影响性能, 其实我们是可以想出不用大排序的算法的,但 SQL 无法描述,那就只能指望数据库优化器了,简单情况下,很多商用数据库确实都能优化,使用不必大排序的算法,性能通常也很好,但情况稍微变复杂一些,比如要在每个分组中取前 10 名,要用到窗口函数和子查询,这时候优化器就又无能为力了,又得乖乖去大排序,慢慢的算了
SPL 则不然,SPL 离散数据集中有普遍集合的概念,TopN 这种运算被认为是和 SUM 和 COUNT 一样的聚合运算,只不过返回值是个集合,用 SPL 去做个这个计算的时候就不需要做大排序了
这只是一个简单的例子,其他的SPL比SQL性能好的高级函数还有很多
除了新的高效的算法以外,数据的存储对于性能也非常重要,好算法要有合适的存储机制配合才能生效,SPL 也有自己更高效的存储方式,高性能二进制文件存储,相对于普通的数据库存储,SPL 的二进制存储和 SPL 的高效算法配合,性能会更好,使用 SPL 存储后,可以把原来需要缓存的计算过程变成不需要了,原来要遍历多遍的运算变成只遍历一次甚至不用遍历了,减少硬盘访问量也是非常有效的性能提升手段
SPL不仅可以优化前两个环节,对 表工具本身的计算能力也可以起到辅助提升的作用
辅助 表计算提升性能
表内的计算,主要得依靠 表工具的基本功,基本功好,可以保证大部分表内计算都不出问题,但万事总有例外,即使是以性能见长的润乾 表,也会遇到跑不快的情况
举个最简单的例子,比如要在 表里做多源关联,我们需要写一个类似这样的表达式 ds2.select(ID==ds1.ID),表达式很简单,但是计算复杂度却是平方级的,数据量不大时,都没问题,数据量稍大时,到几千行,那性能就会急剧下降了,再好的工具处理这样的运算也会有问题
但如果把这个关联放到 表外来做,用SPL来做,则可以使用低复杂的 HASH 算法(而在 表工具中无法对多个数据源先统一处理,实现不了这种算法),那性能就会大幅度的提升了
以下是我们在数据量比较大时,用润乾 表单独运算和 SPL+ 润乾 表协同运算的性能对比,可以看出, 表内的计算性能问题,如果挪到外部计算引擎解决,效果是非常好的
更好的方式是,取数和呈现做成两个异步线程,取数线程发出 SQL 后就不断取出数据后缓存到本地存储中,呈现线程根据页数计算出行数到本地缓存中去获取数据显示,如下图所示
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!