在 QCon New York 2013 上, Rich Hickey 做了一次话题为函数式数据库的演讲。Hickey 因创造了 Clojure 编程语言而蜚声业内,目前他正在开发函数式数据库 Datomic 。在他的演讲中,Hickey 表示函数式语言中的两个非常有用的属性:数据即值(data as values)和纯函数(译者注:Pure Functions ,不会产生副作用的函数,副作用指的是函数会改变外界环境的某些属性,或者返回值依赖于外部环境的某个属性),同样也有适用于数据库这一环境。他认为,这与对象关联的编程有很大不同。对象包含了数据和逻辑,就像是一台机器:它顺序地进行处理并不断改变自己的状态。每次调用对象上的方法都有可能返回不同的结果。这种状态可能会以某种不可预知的方式进行改变。例如,由于另一个线程同样也引用了该对象并修改了它。这让与对象关联的程序很难进行对结果的推断。而我们今天所使用的数据库与对象非常相似:一个数据库服务器就是一个不断改变状态,并且具有查询逻辑和变化部分的单独实体(有可能存在多份复制),可以采用事务的概念来弥补对数据库不可变(immutable)值的缺失。
Hickey 以反问的口吻向观众说道:“如果将所有这些函数式的属性应用到数据库上岂不是很好?”在这样的一个世界里,整个数据库将可以代表一个(不变)值,而查询就好比是以一个或多个数据库作为参数的函数。这样一来,数据库便可以在多个线程间被安全的传递,而在相同数据库值上进行的相同查询将会产生相同的结果。自然地,由于一个不可变的数据库对大家来说并不是很有用处,所以我们将会使用事务处理器(transactor)来产生变更,更准确地说是:基于先前的数据库值产生新的数据库值。给定事务处理器一个数据库值和变化的数量,它将会返回一个新的数据库值。程序可以在任何时间向数据库索取它的当前值。 Datomic 就是一个拥有这些属性的数据库。
这种针对数据库的函数式方式应用了函数式编程的核心思想,即严格地将数据库的数据和逻辑进行区分。数据被持久化在默默无闻的数据存储上,甚至可以存储在像 Amazon 的 DynamoDB 这样的简单键值存储上。事务处理器进程将会对事务进行协调,并且在出现多个“节点(peer)”(Datomic 对客户端的叫法) 于同一时间执行事务时起到主要的作用。通常节点会以 Java 库的形式集成到应用当中。一个节点会与事务处理器建立起一个连接来执行事务性的变化。查询会由节点本身来执行,并根据实际的需要来进行延迟(lazily)数据加载。为了使查询更加简单,Datomic 支持以 Datalog 作为查询语言,该语言是 Prolog 的一个子集,非常适合以声明式的方式进行数据库查询。
关于 Datomic 的更多信息可以访问它的官方网站。InfoQ 曾经发表过 Datomic 的架构与数据模型的文章,并且同样发表了上文所提到的关于 Datomic 的演讲视频。
查看英文原文: The Database as a Value
评论