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

# 写入与事件订阅

> 了解 BlockDB 的实时写、大批量写、区块订阅事件与订阅闭环。

# 写入与事件订阅

BlockDB 把写入分为**实时写**与**大批量写**两类，并在此基础上提供区块事件的订阅能力。

## 实时写

实时写面向常规规模的在线写入，提供近实时的低延迟写入。SDK 提供以下接口：

| SDK 接口 | 说明 |
| - | - |
| `table.upsert_rows(rows)` | 普通表写入 |
| `block_table.write_block(block, rows)` | Block State / Block Event 表按区块写入 |
| `time_table.upsert_time_rows(rows, time_at)` | Time 表按时间桶写入 |

适合持续流入的在线数据写入场景。

## 大批量写

当需要写入海量数据（例如历史回填）时，使用大批量写。它的特点是：

* **一次性提交百万行级别的数据异步写入任务**。
* **提交吞吐无上限**：数据先通过**对象存储中转**，不占用实时的网络与内存通路，因此你可以连续、高吞吐地提交任务。
* **实际落库速度快**：大规模批量写入的底层速度可达**数十万行/秒，甚至百万行/秒**，具体取决于表类型与底层数据库规模。

批量写统一走 `BatchWriteService` gRPC 服务。在 `InitWriteJob` 请求中，通过 `strategy` 字段指定目标表类型：

| Strategy | 表类型 | 说明 |
| - | - | - |
| `normal_upsert` | 普通表 | 普通表大批量写入 |
| `block_overwrite` | Block 表 | Block 表按区块/高度区间批量写入 |
| `time_upsert` | Time 表 | Time 表批量写入（回填） |

```protobuf theme={null}
message InitWriteJobRequest {
  string table_id = 1;
  oneof strategy {
    BlockTableOverwriteStrategy block_overwrite = 2;
    NormalTableUpsertStrategy   normal_upsert   = 3;
    TimeTableUpsertStrategy     time_upsert     = 4;
  }
}
```

### 实时写 vs 大批量写

| 维度 | 实时写 | 大批量写 |
| - | - | - |
| 适用场景 | 常规、在线、近实时写入 | 海量、历史回填 |
| 数据规模 | 单批较小 | 百万行级别 |
| 提交方式 | 直接提交 | 对象存储中转 + 异步任务 |
| 吞吐能力 | 近实时低延迟 | 提交吞吐无上限，落库数十万 \~ 百万行/s |

所有写接口返回统一的 `WriteResult`（`affectedRows` 受影响行数 + `jobID` 任务 ID）。

## 区块订阅事件（BlockSubscribeEvent）

每次 BlockDB 写入 Block 表成功，会自动发布一个**区块订阅事件**（`BlockSubscribeEvent`）。根据 `subscribe` 的协议定义，事件字段为：

| 字段 | 说明 |
| - | - |
| `table_id` | 哪个 Block 表更新了 |
| `block` | 关联的区块元信息（`id` / `height` / `timestamp`） |
| `created_at` | 事件产生的时间戳 |

事件通过 Kafka 事件源分发，订阅方通过 `Subscribe` 服务以流式方式接收。

## 事件订阅闭环

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

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

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

这个闭环让业务代码像"虚拟智能合约"一样运行在数据库的变更流上。

### 从表到表的 ETL 流水线

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

## 多表对齐订阅

当业务逻辑强依赖多张并行计算的上游表时，需要保证各表在目标高度均已写入完毕才能安全消费。BlockDB 内置 `Aligned` 状态机自动处理跨表乱序事件流，参见[多表区块高度对齐订阅](/zh/guides/multi-table-alignment)。

## BlockDB 模式优势

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


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.