FunDA(0)- Functional Data Access accessible to all

   大数据、多核CPU驱动了函数式编程模式的兴起。因为函数式编程更适合多线程、复杂、安全的大型软件编程。但是,对许多有应用软件开发经验的编程者来说,函数式编程模式是一种全新的、甚至抽象的概念,可能需要很长时间的学习、积累才能完全掌握和适应。对一些不算FP编程专家的人来说,如何用他们习惯的方式来使用现成的函数式软件如Slick,Spark等可能就变得是件很迫切的事情了。设计FunDA的想法就是希望那些惯用ORM(Object Relational Mapper)开发MIS系统的编程人员们能快速轻松地使用像Slick这样的FRM(Functional Relation Mapper)。更重要的是能通过FunDA来进入数据库编程的最新境界:并行数据运算(Parallel Data Access),这就代表FunDA必须具备至少两条特性:简单通用的API和对并行运算的支持。

  可以说,FunDA是从零开始设计的。而且最终它应该是某种中间件:在FRM和应用软件中间的一层工具库。由于FunDA是基于函数式编程模式的,通过函数组合可以实现某种安全可维护的大型软件工具库。但设计主题又要求必须屏蔽这个库的复杂函数式编程特性,使传统的数据库应用软件编程人员很容易掌握使用。

FunDA包括两项重大功能:

一、提供按行处理数据功能的支持:FRM最强大的功能之一就是能够实现Query的函数组合,然后产生SQL语句来对后台数据库进行操作,返回结果是一个集合。这样编程人员就可以像使用普通的函数式集合一样用现成的集合操作函数来操作返回结果。首先,SQL语言是一种批次型的数据处理语言,如果用来逐行处理数据会严重影响效率,甚至无法实现对于某些特定数据的处理功能,如图像处理。再者函数式的集合操作函数对于不熟悉函数式编程模式的编程人员来说比较抽象,使用起来不顺手,会影响用户使用体验。如果把FRM产生的Query结果集合变成如同JDBC的resultset,可以把resultset的每行(row)在内存中进行处理,就能解决FRM逐行处理功能缺失的问题,而且传统的数据库编程人员都比较熟悉JDBC的这种逐行处理数据模式。实际上这项功能的主题思想就是提供一种数据格式转换函数实现:StoreData -> MemoryRow -> DataStore 这样的转换。StoreData -> MemoryRow转换是指把从数据库选出的数据逐条record载入内存进行处理。MemoryRow -> DataStore转换则是把内存中record内容转换成SQL语句再发送给后台数据库处理。

二、提供并行数据处理功能:对于大数据和多核CPU风行的时代,如何能充分利用多核CPU硬件技术来应对大数据应该是一种迫切的想法。可以说,并行运算应该是一种核心的解决方案。在传统数据库编程模式中实现并行运算很困难,或者说是很难做好做对。通过函数式编程模式来解决并行运算是可行解决方法之一。希望FunDA所提供的并行运算功能能让传统数据库编程人员无需太高的函数式编程模式门槛就可以让他们能快速熟悉并掌握,实现数据库程序的并行运算。

FunDA的总体开发方式是:先实现功能要求,然后再进行代码重新组织、优化、开源、维护。功能开发过程框架如下:

一、数据行操作:读取数据后进行数据格式转换,结果为强类型数据行(Strong Typed DataRow),即带字段名称的数据行。数据行基础操作代表对后台数据库的更新,包括:append、update、delete。用数据行的状态来代表对后台数据库的具体操作。数据行状态变化属于不可变模式操作(immutable operations)。

二、数据流动管理:moveNext,载入下一数据行直到完成所有数据源读取、moveLast,强行终止数据读取。

三、运算管理:运算可以分成两大类:一是数据源产生loadData,包括从后台数据库读取或者直接产生形成数据源头。二是按每条数据行要求进行状态处理函数的运算run(func)或者并行运算runPar(func)。产生数据源同样可以实现并行运算,比如通过构建一个多任务计算对象后进行运算。模拟了个应用场景可能是如下这样的:

buildPar(loadData(age.between(0,10))  //构建并行运算对象
  .with(loadData(age.between(11,20)) 
  .with(loadData(age.between(21,50))
  .runPar                             //开始并行读取,产生数据源
  .runPar(updateRow)                  //对源头产生的数据行进行并行处理

数据流动管理和运算管理功能可以通过某种流库(stream library)如scalar-streams-fs2、aka-stream等提供的现有运算功能实现。

大体的开发计划可以分成下面几个阶段:

一、scalaz-streams-fs2+slick:先直接绑定slick作为FRM部分与后台数据库发生关系、fs2作为在内存中数据流和运算管理工具来实现FunDA的功能组成部分

二、scalaz-streams-fs2+freemonad-FRM-DSL:用freemonad模拟一套数据库数据操作DSL(domain-specific-language)。通过freemonad的多种功能实现模式(separation of concern)来实现FunDA数据库具体操作与各种FRM、ORM的松散耦合(loose coupling),最终能同时支持slick、doobie直至jdbc等数据库操作api。

三、freemonad stream+FRM DSL:用freemonad来抽象FunDA全部操作,全面实现与下层软件工具库的松散耦合,同时提供scalaz-streams-fs2、akka-stream、slick、doobie、jdbc这些工具库的功能实现。创建相关DSL形成一套完整的泛型api。

四、把FunDA推上开源平台GitHub

好了,思路整理完毕后下面应该是一系列编程过程的描述了。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏星流全栈

Phoenix Framework — 新一代的实时 Web 框架

1805
来自专栏苦逼的码农

为什么寄存器比内存快?

计算机的存储层次(memory hierarchy)之中,寄存器(register)最快,内存其次,最慢的是硬盘。

612
来自专栏最高权限比特流

漫谈计算机组成原理(二)系统总线

从引言中,我们基本上能够了解到总线在计算机系统中的作用。但是上面的说法只是一个概论,我们需要给出更加详细的总线的作用:总线是计算机中各个部件的信息传输线。在计算...

1633
来自专栏blackheart的专栏

[解读REST] 5.Web的需求 & 推导REST

衔接上文[解读REST] 4.基于网络应用的架构风格,上文总结了一些适用于基于网络应用的架构风格,以及其评估结果。在前文的基础上,本文介绍一下Web架构的需求,...

17910
来自专栏我思故我在

ABP框架 - N层架构

3758
来自专栏PHP实战技术

3-5年的PHPer常见的面试题

看到有很多,的总结一下,比较适合有一定经验的PHPer 平时喜欢哪些php书籍及博客?CSDN、虎嗅、猎云 js闭包是什么,原型链了不了解? for与forea...

36710
来自专栏程序你好

系统集成的演变历史

如果你仔细想想,标准和协议在任务完成后就会出现它们本来要简化的东西已经出现了一段时间了,没有两组是用同样的方法来做的。这适用于软件,移动开发如何成为标准化的最近...

1113
来自专栏JetpropelledSnake

RESTful源码学习笔记之RPC和 RESTful 什么区别

REST,即Representational State Transfer的缩写。翻译过来是表现层状态转换。 如果一个架构符合REST原则,就称它为RESTfu...

641
来自专栏王亚昌的专栏

Go语言入门之路

Go is designed from first principles to advance the practice of software enginee...

2505
来自专栏我思故我在

ABP框架 - N层架构

1063

扫码关注云+社区