> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chaintable.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 工作原理

> 理解在线表如何同步到分析存储，以及 SQL 执行、结果保存和数据更新之间的关系。

数据分析面向跨记录的筛选、关联和聚合。在线表的数据先同步到分析存储，SQL 再读取分析表并生成一份保存的结果，供页面、图表和看板使用。这几个步骤独立发生，因此“在线表有新数据”和“图表已经更新”之间存在多个环节。

## 为什么使用独立的分析存储

BlockDB 的在线访问围绕记录 ID、区块和时间组织，适合持续写入和读取特定对象。分析查询则经常读取大量记录中的少数字段，例如扫描一段时间的转账金额并按天汇总。

Chaintable 将这两种访问交给不同的存储路径：在线数据从 BlockDB 同步到分析存储，再由 SQL 引擎执行查询。

| 组成部分    | 保存或处理什么        | 在分析过程中的作用                     |
| ------- | -------------- | ----------------------------- |
| 分析存储    | 分析表数据及其元数据     | 持久保存供 SQL 查询的数据               |
| 列式数据文件  | 按列组织的记录        | 使查询可以只读取需要的列，并利用统计信息跳过不相关的数据块 |
| 表元数据与快照 | 表结构及各版本包含的数据范围 | 将数据组织成可更新、可一致读取的分析表           |
| SQL 引擎  | 查询计划与执行        | 读取分析表，完成筛选、关联和聚合              |

例如，统计每日转账量只需要时间和金额等列，无需同时读取每条记录的所有业务字段。列式存储可以减少这类扫描的数据量；具体能跳过多少文件或数据块，仍取决于查询条件、文件布局和统计信息。

## 在线数据如何同步

同步服务读取 BlockDB 的表结构和数据，更新对应的分析表，并在一个同步批次完成后发布新的数据版本。各类表的当前记录与历史记录分别同步：状态表的 latest 用于当前值分析，archive 用于研究历史变化，选择其中一种会改变统计含义。

不同数据组织采用不同的同步方式：

* **区块事件和状态历史**可以按区块范围同步。服务比较 BlockDB 的区块包摘要，找出新增或变化的范围，重新读取这些范围并替换分析表中对应的数据文件。近期区块还可以通过订阅变化触发同步。
* **普通表和状态 latest**中的同一记录可能持续被覆盖，服务通过全量读取生成新一批文件，再替换对应分析表的数据。
* **时间历史**需要适应历史数据的分桶和整理，服务可按配置分别处理近期与较早的数据，更新相关时间范围。

区块包摘要让服务能够按范围核对数据，而不必每次重新扫描整张事件表；重新核对也能补偿遗漏的变化通知。近期区块同步和完整区块包核对各有用途，不需要将所有新数据都等到一个完整区块包形成后才处理。

同步是异步过程。数据量、任务排队、批次提交和失败重试都会影响延迟；在线 SDK 已经读到的新值，SQL 仍可能暂时读不到。不同表也可能推进到不同位置，关联多张表时需要留意各自的数据覆盖。

## 分析表快照保证什么

快照表示分析表的一份已发布数据版本。同步批次完成后，新的数据版本才对查询可见，避免查询读到一次更新中尚未完成的部分数据。

这保证的是分析表版本的完整性。一个已提交快照仍可能落后于在线表；分别同步的多张表也不因此共享同一个链上高度或同一次源端提交。涉及区块一致性的统计，应在 SQL 中限定需要的区块范围，并确保所需表都已同步覆盖该范围。

如果统计“某个历史区块时各对象的状态”，应使用历史版本，并为每个对象选择不晚于该区块的最新版本。只查询 latest 会得到同步时的当前状态，无法还原过去的状态。

## SQL 执行

点击 **Run** 后，系统按以下过程生成结果：

1. 检查账户的分析额度，保存本次 SQL 和参数并创建查询任务。
2. 将 SQL 提交给查询引擎。引擎根据分析表元数据规划读取范围，执行筛选、关联和聚合。
3. 收集返回行、列名、类型和执行统计，保存本次查询结果。
4. 建立该次任务与结果文件的关联，查询任务完成后，页面即可读取保存的结果。

任务可能经历等待、执行、成功或失败，受执行期限、查询资源和结果大小限制。需要统计的数据应尽量在 SQL 内完成筛选和聚合，再返回适合查看的结果，避免把大量明细全部取回后仅靠页面过滤。

## 保存的结果

查询定义保存 SQL、参数等配置；查询结果保存某次执行得到的数据。编辑并保存 SQL 不会自动产生新的结果，必须再次点击 **Run**。

查询结果是从分析表计算得到的一份独立数据。结果页面的分页、排序和关键词筛选读取这次执行的结果，不会重新执行原 SQL，也不会推进源表同步。图表和看板使用查询的结果数据；源表更新后，已有结果不会自动变成新统计。

因此，判断数据是否更新，需要分别看三个环节：

| 环节    | 回答的问题              | 如何得到新数据      |
| ----- | ------------------ | ------------ |
| 在线表   | 数据是否已经写入 BlockDB？  | 数据构建任务完成写入   |
| 分析表快照 | 新数据是否已经同步供 SQL 读取？ | 等待相应同步批次完成提交 |
| 查询结果  | 本次统计使用了哪次执行的数据？    | 在同步完成后重新运行查询 |

例如，10:00 写入的转账在 10:02 才完成同步，10:01 执行的统计不会包含这些转账。同步完成后，这份旧结果仍保持不变；需要重新运行查询，图表才能使用包含新转账的统计结果。

编写和运行查询的方法见[SQL 查询](/zh/guides/analytics/sql-queries)，图表与结果的使用方式见[可视化和看板](/zh/guides/analytics/visualizations-and-dashboards)。
