> ## 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.

# BlockDB 介绍

> 了解 Chaintable 中 BlockDB 的核心能力、架构模型和链上语义表。

***

用户数据全部存储在chaintable的BlockDB数据库中，所有用户表的创建和管理，都是由BlockDB这个组件完成的。

## 什么是BlockDB

**BlockDB解决的核心痛点：** 区块链数据获取面临三个难题：**状态难追溯**（不知道过去某个时刻的余额）、**事件难同步**（链上操作零散，对不同区块事件处理的先后顺序有要求）、**链路太长**（需要搭建复杂的 ETL 队列）。

**BlockDB 的定义：** BlockDB 是专为区块链设计的“逻辑多模型数据库”。它在底层（在线表）提供标准在线数据库的存储能力，在逻辑层提供开箱即用的“链上语义表”（Block表）。

BlockDB对用户提供的核心能力：

* \*\*链上数据特化：\*\*用户可以通过Block表直接查询任意时刻的链上状态，或者订阅任何合约的实时变动，无需理解底层复杂的区块回滚（Reorg）和数据管理逻辑。

* **在线数据库，** 传统的 ETL 需要先离线计算再导出到在线库。在 ChainTable，**BlockDB 即在线库**。

* **事件订阅能力**：BlockDB的通过提供表的事件订阅能力，使用户可以自由处理任何上游表的实时数据，让业务代码像“虚拟智能合约”一样运行在数据库的变更流上。

## 架构模型--BlockDB的“两层楼”

BlockDB在架构上分为两层的表模型：

* 存储层---普通在线表

  * 提供实时读取，高吞吐写入基础能力

* 业务抽象层---区块链场景的特化逻辑表

  * 提供链上数据存取场景的定制化能力，业务抽象层是BlockDB的核心功能

### Level 1：存储层

存储层负责创建和维护在线数据库表，可以称为普通表。

对用户而言，用户创建普通表，用于存储：

1. 非链上的业务数据，辅助数据处理。

2. 链上数据处理后的高价值数据，支持在线应用搭建。

存储层，除了直接为用户提供表功能，也为上层业务表的提供物理存储能力：

* 用户创建level 2的区块链逻辑表时，level 1层实际会为逻辑表创建1个或者多个普通表

与传统的 SQL 数据库不同，为了保证在大规模链上数据高频写入时的稳定性，在线表摒弃了复杂的 SQL 语法，直接提供**语义化 API**：

* **核心操作**：

  * `GetRow` / `FilterRows`：快速精准地获取特定行或按条件筛选。

  * `UpsertRows`：高并发、异步地批量插入或更新数据。

  * `DeleteRows`：批量清理过期或无效数据。

> todo，存储层也支持事件订阅，但是非核心feature，先不表。Scan也没提

### Level 2：业务抽象层

这是专门为“链上数据”定制的逻辑模型。目前有Block State表，Block Event表两个逻辑模型。

当你在 Level 2 创建一个 Block 表时，BlockDB 并没有在存储引擎上创建一个表，而是**自动在 Level 1 创建了多个互相协作的普通表**。

* **“影子表”机制**：

  * 不同逻辑模型，会映射成多个普通表，具体映射关系：

    * L2` onchain_state` → L1 `onchain_state`（查最新值）、`onchain_state.archive`（查任意历史值）、`onchain_state.height`（查处理高度情况）

    * L2` onchain_event` → L1 `onchain_event`（查任意事件）、`onchain_event.height`（查处理高度情况）

* **双重操作能力**：

  * **高级模式 (Level 2 API)**：用户使用“链上语义”操作（例如：按区块粒度原子性写入数据，按区块时刻读取state记录），简单省事，系统自动拆解并操作底层的三个表。

  * **专家模式 (Level 1 API)**：用户也可以直接通过 `GetRow` 等 API 绕过 L2，直接对底层的三个 Online 表进行操作（通常是读取操作）。

* **核心操作**：

  * GetState/GetEvent：按区块时刻读取state记录，event记录。

  * GetBlockData：获取表的任意区块的全部数据。

  * BlockWrite：按区块粒度原子写入新数据。

  * SubscribeTableEvent：实时订阅表的区块处理事件。

## 深入理解Block表

### Block State表：单行状态模型

**定义：** 用于存储链上实体的最新状态以及所有历史高度状态。每当有新高度的数据进入，blockDB保存历史高度数据并且异步自动处理最新状态表的更新。

#### \*\*Schema \*\*

用户只需定义最核心的业务列，BlockDB 会自动补全运维列：

* **ID (主键)**：必须名为 `id`，类型为 `String`。

* **业务属性列**：用户可以添加多列，任意逻辑类型皆可。

* **CHAINID**：标识该数据属于哪条链。

#### **物理存储实现 (L1 层映射)**

在底层，BlockDB 会自动驱动三张普通表来保障数据的完整性：

| 表名                     | 角色    | 核心 Schema 特件                                 | 业务场景                            |
| ---------------------- | ----- | -------------------------------------------- | ------------------------------- |
| `$table_name`          | 最新状态表 | 包含 id、业务列、Height、blockID、Blocktimestamp。     | 实际用户的索引，也是应用在最新状态表。查询此时此刻的最新余额。 |
| `$table_name.archived` | 历史快照表 | 主键为 `hash(id, height)`。包含原始 ID 和历史每一个变动点的数据。 | 追溯用户在 1 个月前链上的资产状态。             |
| `$table_name.height`   | 进度管理表 | 记录 `[start, end]` 闭区间，标注哪些高度区间已成功处理。         | 检查数据是否连续，是否有“断档”。               |

* 最终一致性，BlockDB会同步更新历史快照表和进度管理表，然后异步更新最新状态表

### Block Event表

\*\*定义：\*\*用于存储用户关心的区块链上的每一条事件。

用户只需定义最核心的业务列，BlockDB 会自动补全运维列：

* **ID (主键)**：必须名为 `id`，类型为 `String`。

* **业务属性列：用户可以添加多列，任意逻辑类型皆可。**

* **CHAINID**：标识该数据属于哪条链。

**与 State 表的区别**：Event 表**不维护 ****`.archived`**** 表**

* **逻辑背景**：因为链上事件（如一笔转账、一次授权）在特定高度发生后就是唯一的、不可变的。它没有“更新”的概念，只有“追加”。

**组成部分**：

1. **`$table_name`**：存储所有原始事件数据。

2. **`$table_name.height`**：同样维护处理进度，确保开发者知道哪些区块的事件已经被拉取。

### Block表的事件订阅能力

每次用户调用BlockWrite API写入Block表成功，BlockDB会自动产生一个**区块写入事件 (BlockWriteEvent)。**

事件包含关键信息：

* Table Name：哪个Block表更新了

* Block信息：关联的区块高度和区块哈希

* Data Hash：这一批写入行数据的整体哈希值

Block和Data Hash的业务意义：

1. Data Hash等于0值，意为订阅表当前高度没有产出数据，只表达该高度计算完成

2. 携带Data hash和Block信息调用Block表数据读取API，BlockDB会使用高速缓存，快速返回表指定区块的所有数据行

通过**事件订阅机制**(Subscribe API)，BlockDB 实现了 **“数据生产 -> 事件通知 -> 下游消费”** 的闭环，将整个业务逻辑与区块链的“心跳”（出块频率）完全同步。

这个闭环对于简化链上数据处理极为重要，它将chaintable的链上数据处理升级成了一种业务开发范式，\*\*让业务代码像“虚拟智能合约”一样运行在数据库的变更流上，\*\*同时利用高度事件的抽象让其运行得及其高效。

1. 事件驱动的处理循环：同步出块的节奏

在传统的开发模式中，你需要不断“轮询”数据库或解析器，这会导致延迟或资源浪费。

* **BlockDB 的方式**：数据库的每一次写入（BlockWriteEvent）都对应着一次区块链的真实出块。这意味着你的业务系统不再是“追赶”区块链，而是成为了区块链计算链条的一部分。**每出一个块，数据自动流向下一站。**

```Python theme={null}
from blockdb.block_table import Subscribe

sub = Subscribe(tables=["onchain_token_balance.eth"])
for table_id, block in sub.listen():
        # 业务处理逻辑...
```

2. 从表到表的“ETL 流水线”

没有chaintable时，你只能自己配置过滤区块链上的原始数据，开始一步一步开展自己的业务逻辑处理。

chaintable上，用户无需订阅最原始的trace和event区块数据表，可以从平台任意已有的特定主题的block表开始订阅加工，变成ETL的流水线，简化数据处理。

### Block表核心优势总结

| **维度**    | **传统方式处理链上数据**     | **BlockDB 模式**                                     |
| --------- | ------------------ | -------------------------------------------------- |
| **实时性**   | 手动同步，存在分钟级延迟       | **区块级同步**，毫秒级感知                                    |
| **开发难度**  | 理解区块，学习合约，从源头开始处理  | **python API 开发**，在数据库层面操作读写，可以订阅解码和建模后的数据表        |
| **链路复杂度** | 维护队列、离线脚本、中间表      | **表与表直接驱动**，天然的加工链路                                |
| **一致性**   | 自己处理多表更新，自己处理reorg | BlockDB 会**原子化**地更新block表，reorg免维护，BlockDB自动撤销数据更改 |
