为什么使用独立的分析存储
BlockDB 的在线访问围绕记录 ID、区块和时间组织,适合持续写入和读取特定对象。分析查询则经常读取大量记录中的少数字段,例如扫描一段时间的转账金额并按天汇总。 Chaintable 将这两种访问交给不同的存储路径:在线数据从 BlockDB 同步到分析存储,再由 SQL 引擎执行查询。
例如,统计每日转账量只需要时间和金额等列,无需同时读取每条记录的所有业务字段。列式存储可以减少这类扫描的数据量;具体能跳过多少文件或数据块,仍取决于查询条件、文件布局和统计信息。
在线数据如何同步
同步服务读取 BlockDB 的表结构和数据,更新对应的分析表,并在一个同步批次完成后发布新的数据版本。各类表的当前记录与历史记录分别同步:状态表的 latest 用于当前值分析,archive 用于研究历史变化,选择其中一种会改变统计含义。 不同数据组织采用不同的同步方式:- 区块事件和状态历史可以按区块范围同步。服务比较 BlockDB 的区块包摘要,找出新增或变化的范围,重新读取这些范围并替换分析表中对应的数据文件。近期区块还可以通过订阅变化触发同步。
- 普通表和状态 latest中的同一记录可能持续被覆盖,服务通过全量读取生成新一批文件,再替换对应分析表的数据。
- 时间历史需要适应历史数据的分桶和整理,服务可按配置分别处理近期与较早的数据,更新相关时间范围。
分析表快照保证什么
快照表示分析表的一份已发布数据版本。同步批次完成后,新的数据版本才对查询可见,避免查询读到一次更新中尚未完成的部分数据。 这保证的是分析表版本的完整性。一个已提交快照仍可能落后于在线表;分别同步的多张表也不因此共享同一个链上高度或同一次源端提交。涉及区块一致性的统计,应在 SQL 中限定需要的区块范围,并确保所需表都已同步覆盖该范围。 如果统计“某个历史区块时各对象的状态”,应使用历史版本,并为每个对象选择不晚于该区块的最新版本。只查询 latest 会得到同步时的当前状态,无法还原过去的状态。SQL 执行
点击 Run 后,系统按以下过程生成结果:- 检查账户的分析额度,保存本次 SQL 和参数并创建查询任务。
- 将 SQL 提交给查询引擎。引擎根据分析表元数据规划读取范围,执行筛选、关联和聚合。
- 收集返回行、列名、类型和执行统计,保存本次查询结果。
- 建立该次任务与结果文件的关联,查询任务完成后,页面即可读取保存的结果。
保存的结果
查询定义保存 SQL、参数等配置;查询结果保存某次执行得到的数据。编辑并保存 SQL 不会自动产生新的结果,必须再次点击 Run。 查询结果是从分析表计算得到的一份独立数据。结果页面的分页、排序和关键词筛选读取这次执行的结果,不会重新执行原 SQL,也不会推进源表同步。图表和看板使用查询的结果数据;源表更新后,已有结果不会自动变成新统计。 因此,判断数据是否更新,需要分别看三个环节:
例如,10:00 写入的转账在 10:02 才完成同步,10:01 执行的统计不会包含这些转账。同步完成后,这份旧结果仍保持不变;需要重新运行查询,图表才能使用包含新转账的统计结果。
编写和运行查询的方法见SQL 查询,图表与结果的使用方式见可视化和看板。