使用不可变 SQL 数据库 XTDB 进行时间旅行
Clojure 概览
什么是 Clojure?
Clojure 是一种运行在 Java 虚拟机 (JVM) 上的动态、通用编程语言。它是 Lisp 的一种方言,强调函数式编程、不可变性和面向数据的设计。它以简洁、强大以及有效处理并发的能力而闻名。
Clojure 有什么用?
- 数据处理:Clojure 对不可变性和数据结构的关注使其非常适合数据操作和转换。它常用于 ETL(提取、转换、加载)管道和数据分析。
- Web 开发:Clojure 拥有多个强大的 Web 框架(例如 Ring、Compojure、Pedestal)和库,使其适合构建 Web 应用程序。其函数式特性可以带来更易于维护的代码。
- 并发:Clojure 的不可变性使得处理并发操作变得容易得多。它提供了用于管理状态和并行性的强大工具。
- 分布式系统:Clojure 在 JVM 上运行的能力及其对数据的关注,使其非常适合构建分布式系统。
- 云计算:Clojure 在云环境中运行良好,并经常与云平台结合使用。
- 特定领域:金融、电子商务和其他数据密集型领域通常能从 Clojure 的优势中受益。
如何入门
- 安装 Leiningen (Lein):Leiningen 是 Clojure 的标准构建工具。它简化了项目管理、依赖管理和 REPL 的使用。请按照 Leiningen 网站上针对您操作系统的说明进行操作。
- 创建项目:使用 Lein 创建一个新的 Clojure 项目:`lein new my-clojure-project`
- 启动 REPL:导航到您的项目目录并启动 REPL:`lein repl`
- 学习基础知识:熟悉 Clojure 的核心数据结构(列表、向量、映射)、函数和语法。Clojure.org 和《Clojure for the Brave and True》等在线资源是极好的起点。
Clojure 基础语法
- 列表:`(1 2 3)`(用于函数调用、代码表示)
- 向量:`[1 2 3]`(用于有序数据)
- 映射:`{ :a 1 :b 2 }`(键值对)
- 函数:`(defn my-function [x y] (+ x y))`
- 关键字:`:my-keyword`(用作映射中的键,代表其自身)
使用场景
- XTDB:Clojure 常与 XTDB 一起使用,这是一种强调时间和历史的图数据库。Clojure 的面向数据的方法与 XTDB 的设计非常契合。
- 数据分析:Neanderthal 和 Incanter 等 Clojure 库使其适用于数值和统计计算。
- Web 应用程序:构建 Web 服务和 API。
- 微服务:创建小型、独立的各种服务。
示例(REPL 交互)
lein repl ; 启动 REPL
; 定义一个函数
(defn greet [name]
(str "Hello, " name "!"))
; 调用函数
(greet "World") ; => "Hello, World!"
; 操作向量
(def numbers [1 2 3 4 5])
(first numbers) ; => 1
; 操作映射
(def person {:name "Alice" :age 30})
(:name person) ; => "Alice"XTDB
什么是 XTDB?
XTDB 是一种双时态数据库,结合了传统 SQL 数据库、文档存储和图数据库的最佳特性。它专为需要时间数据管理和复杂查询能力的现代应用程序而设计。
主要特性
双时态 (Bitemporality)
记录 /有效时间/(事实在现实中成立的时间)和 /事务时间/(事实被记录的时间) 支持时间旅行查询和审计追踪 非常适合合规性、历史分析和数据溯源
无模式文档 (Schemaless Documents)
无需预定义模式即可存储数据 类似于 MongoDB 的灵活文档模型 读取时模式 (Schema-on-read) 方法 支持嵌套数据结构
图查询 (Graph Queries)
无需特殊建模即可将数据作为图进行查询 关系的自然表示 强大的遍历能力 兼容文档和图范式
SQL 支持
熟悉的 SQL 查询语法 将 SQL 与文档和图功能相结合 SQL 开发人员可轻松过渡 支持 JDBC 驱动
不可变数据模型 (Immutable Data Model)
所有更改均为添加,从不修改 完整的审计历史 数据完整性保证 非常适合合规性要求
使用场景
金融服务
- 交易历史
- 审计追踪
- 合规性
- 历史报告
医疗保健
- 患者随时间变化的记录
- 治疗历史
- 合规性
- 数据溯源
供应链
- 产品追踪
- 库存历史
- 关系管理
- 时间线分析
技术优势
简单的架构
- 单一事实来源
- 无需单独的事件日志
- 易于理解
- 简化部署
ACID 事务
- 强一致性保证
- 多文档事务
- 可靠的数据操作
- 安全的并发访问
出色的性能
- 高效索引
- 快速时间查询
- 良好的读写平衡
- 可扩展设计
代码示例:基本操作
;; 启动节点
(def xtdb-node
(xt/start-node {:xtdb/tx-log {:kv-store {:xtdb/module 'xtdb.rocksdb/->kv-store}}
:xtdb/document-store {:kv-store {:xtdb/module 'xtdb.rocksdb/->kv-store}}}))
;; 放入文档
(xt/submit-tx xtdb-node
[[::xt/put
{:xt/id :person/joe
:name "Joe"
:role "Developer"}]])
;; 查询数据
(xt/q (xt/db xtdb-node)
'{:find [name role]
:where [[e :name name]
[e :role role]]})
;; 时间旅行查询(截至特定时间点)
(xt/q (xt/db xtdb-node #inst "2023-01-01")
'{:find [name role]
:where [[e :name name]
[e :role role]]})入门
安装
;; 添加到 deps.edn
{:deps {com.xtdb/xtdb-core {:mvn/version "LATEST"}}}基本设置步骤
- 添加 XTDB 依赖
- 配置存储后端
- 启动 XTDB 节点
- 开始编写查询
VS Code 与 Calva
- VS Code
- calva
开发工作流
从简单的查询开始 使用 REPL 驱动开发 测试时间场景 记录您的数据模型
XTDB 文档:https://docs.xtdb.com Clojure API 参考 教程与指南
结论
XTDB 提供: 强大的时间处理能力 灵活的数据建模 强一致性保证 现代开发体验 活跃的社区

