ElectricSQL 中的 Shapes 同步机制详解

ElectricSQL 中的 Shapes 同步机制详解

electric electric-sql/electric: 这是一个用于查询数据库的JavaScript库,支持多种数据库。适合用于需要使用JavaScript查询数据库的场景。特点:易于使用,支持多种数据库,具有灵活的查询构建和结果处理功能。 electric 项目地址: https://gitcode.com/gh_mirrors/el/electric

什么是 Shapes

在 ElectricSQL 系统中,Shapes 是控制数据同步的核心概念。它允许开发者定义需要从云端 Postgres 数据库同步到本地应用的数据子集。

数据子集同步的必要性

想象一下,云端 Postgres 数据库中存储了大量数据,但通常我们并不需要将所有数据都同步到本地设备上。这既可能因为网络带宽限制,也可能出于数据隐私考虑,或者仅仅是本地设备存储空间有限。Shapes 提供了一种精确控制数据同步范围的方式。

Shapes 的组成要素

一个 Shape 由以下三个关键部分组成:

  1. 表定义:指定要同步的基础表
  2. Where 条件(可选):过滤需要同步的行
  3. 列选择(可选):指定需要同步的列

表定义详解

表定义是 Shape 的必选部分,它必须对应 Postgres 数据库中的一个实际表。表名可以简单如 projects,也可以包含模式前缀如 foo.projects。如果省略模式前缀,则默认使用 public 模式。

分区表支持

ElectricSQL 支持声明式分区表,既可以订阅整个分区表,也可以订阅特定分区。例如:

CREATE TABLE measurement (
    city_id int not null,
    logdate date not null,
    peaktemp int,
    unitsales int
) PARTITION BY RANGE (logdate);

订阅根表 measurement 会同步所有分区的数据,而订阅特定分区如 measurement_y2025m03 则只同步该分区范围内的数据。

Where 条件详解

Where 条件用于过滤表中需要同步的行,它必须是一个有效的 PostgreSQL 查询表达式。支持的特性包括:

  • 数值类型、布尔值、UUID、文本等字段的比较
  • 算术运算、比较运算、逻辑运算符等
  • 位置参数占位符(如 $1)防止 SQL 注入

但需要注意以下限制:

  1. 只能引用目标行的列
  2. 不能执行表连接或引用其他表
  3. 不能使用非确定性函数如 count()now()

列选择详解

列选择允许开发者精确控制需要同步的列。如果指定,则只同步列出的列;如果省略,则同步所有列。必须始终包含主键列,列名必须与数据库模式中完全一致,必要时使用引号。

Shapes 订阅机制

本地客户端通过订阅 Shapes 来同步数据,通常使用客户端库实现。同步服务维护这些订阅,并将新数据和数据变更流式传输到本地客户端。

HTTP API 方式

开发者可以直接使用 HTTP API 手动同步 Shapes:

# 初始同步请求
curl -i 'http://localhost:3000/v1/shape?table=foo&offset=-1'

# 实时更新请求
curl -i 'http://localhost:3000/v1/shape?table=foo&live=true&offset=...&handle=...'

TypeScript 客户端方式

更高级的方式是使用 TypeScript 客户端:

import { ShapeStream, Shape } from '@electric-sql/client'

const stream = new ShapeStream({
  url: `http://localhost:3000/v1/shape`,
  params: {
    table: `foo`
  }
})
const shape = new Shape(stream)

// 等待数据加载完成
await shape.rows

// 订阅数据变更
shape.subscribe(({ rows }) => {
  // 处理变更数据
})

性能考量

Where 条件的评估对数据吞吐量有重要影响。ElectricSQL 将 Where 条件分为两类:

  1. 优化条件:特定形式的条件(如 field = constant)可以高效评估
  2. 非优化条件:其他形式的条件

使用优化条件时,ElectricSQL 可以维持约 5,000 行变更/秒的吞吐量,不受 Shape 数量影响。而非优化条件下,吞吐量与 Shape 数量成反比。

优化条件类型

目前优化的条件包括:

  • field = constant:对常量值的等值检查
  • field = constant AND another_condition:组合条件中的优化部分
  • a_non_optimized_condition AND field = constant:顺序无关的组合条件

当前限制

  1. 单表限制:目前 Shapes 仅支持单表,不支持旧版本中的包含树(include trees)功能
  2. 不可变性:Shape 定义一旦创建就无法修改,需要创建新订阅来改变同步数据
  3. 表删除处理:删除表时需要手动删除相关的 Shapes

实际应用建议

对于需要同步关联数据的场景,可以采用以下变通方案:

  1. 对于一级关联(如项目及其问题),可以订阅两个 Shapes:projects where="id=..."issues where="project_id=..."
  2. 对于多级关联(如项目、问题和评论),可以反规范化设计,在底层表中添加项目 ID 字段

这些方案虽然增加了设计复杂度,但在当前版本下提供了可行的解决方案。

electric electric-sql/electric: 这是一个用于查询数据库的JavaScript库,支持多种数据库。适合用于需要使用JavaScript查询数据库的场景。特点:易于使用,支持多种数据库,具有灵活的查询构建和结果处理功能。 electric 项目地址: https://gitcode.com/gh_mirrors/el/electric

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

资源下载链接为: https://pan.quark.cn/s/3d8e22c21839 随着 Web UI 框架(如 EasyUI、JqueryUI、Ext、DWZ 等)的不断发展与成熟,系统界面的统一化设计逐渐成为可能,同时代码生成器也能够生成符合统一规范的界面。在这种背景下,“代码生成 + 手工合并”的半智能开发模式正逐渐成为新的开发趋势。通过代码生成器,单表数据模型以及一对多数据模型的增删改查功能可以被直接生成并投入使用,这能够有效节省大约 80% 的开发工作量,从而显著提升开发效率。 JEECG(J2EE Code Generation)是一款基于代码生成器的智能开发平台。它引领了一种全新的开发模式,即从在线编码(Online Coding)到代码生成器生成代码,再到手工合并(Merge)的智能开发流程。该平台能够帮助开发者解决 Java 项目中大约 90% 的重复性工作,让开发者可以将更多的精力集中在业务逻辑的实现上。它不仅能够快速提高开发效率,帮助公司节省大量的人力成本,同时也保持了开发的灵活性。 JEECG 的核心宗旨是:对于简单的功能,可以通过在线编码配置来实现;对于复杂的功能,则利用代码生成器生成代码后,再进行手工合并;对于复杂的流程业务,采用表单自定义的方式进行处理,而业务流程则通过工作流来实现,并且可以扩展出任务接口,供开发者编写具体的业务逻辑。通过这种方式,JEECG 实现了流程任务节点和任务接口的灵活配置,既保证了开发的高效性,又兼顾了项目的灵活性和可扩展性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

井唯喜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值