构建 Web3 原生数据仓库的挑战之一是所需的极端数字规模和精度——我们已经看到 Gas 费、Gas 限制、代币奖励等要求数字规模和精度达到 72 位或更高。Oracle 或 Snowflake 等传统数据仓库的 Decimal 数据类型最高可达 37 位,利用 Float 数据类型来处理更大的数字。Float 数据类型面临的挑战是缺乏精度,这在 Web3 中意味着在聚合各方之间的价值转移时缺乏保真度。或者,一些 Web3 数据提供程序将这些非常大的数字存储在 VarChar 等字符字段中,但会牺牲基本数学函数的性能。用户可以在全精度数字之间进行选择,并能够执行基本计算。
为了实现高保真 Web3 用例,Space and Time 构建了 Big Decimal 数据类型来支持 Web3 极端大小和精度,同时仍然保留数学功能。
Space and Time从多个端点接收区块链数据,然后将其发送到Kafka主题,数据仓库从中实时消费数据并将其写入表中。另外,我们建立了一个 ETL 流程,用于将历史区块链数据批量加载到数据仓库中。这允许用户访问区块 1 中的所有数据,还可以访问实时添加到链中的数据。我们努力使区块链事件与空间和时间中反映的数据之间的延迟尽可能低。
我们不是使用类似 JSON 的模式存储区块链数据,而是将区块链表提取到特定的结构化模式中,使开发人员更容易使用数据。对于开发人员来说,在关系模式之上编写应用程序和查询要容易得多,而不是简单的 JSON 块。
由于 Space and Time 是一个 HTAP 数据仓库,因此它由两种不同的查询引擎组成:OLTP(事务性、基于行)引擎和 OLAP(分析、基于列)引擎。从用户的角度来看,没有分叉——您只需运行查询并获取结果即可。Space and Time 处理到验证器层中适当引擎的路由。当用户运行事务查询时,它是从具有极端延迟的行格式数据库提供服务的。如果查询路由器确定用户运行了分析查询,则由 OLAP 引擎提供服务,该引擎作用于列式存储格式,以实现更快的查询响应时间并减少存储和查询引擎之间的数据传输。
当我们构建区块链索引服务时,我们意识到区块链数据(特别是财务数据,如钱包余额)的精度可以高达 78 位。虽然我们的 OLTP 引擎本身支持这种精度级别,但 OLAP 引擎不支持超过 38 的精度和超过 18 的标度。尽管数据以字符串格式存储,但仍然无法进行计算(即使对此类数据进行基本的数学运算(如加法和减法),而不会损失精度。因此,我们创建了 Big Decimal 数据类型,它支持无限精度,允许用户以有意义的方式处理区块链数据,而不会损失精度。
Create table ETH.FUNGIBLETOKEN_WALLET(key integer, balance decimal(78, 10))
上面的余额字段可以包含精度(总位数)为 78 的小数值。小数位数为 10,即小数点后的位数可以为 10。
Create table ETH.FUNGIBLETOKEN_WALLET(key integer, balance decimal(78, 0))
请注意上面的刻度为 0。这将使我们能够在字段中存储整数。您可以尽可能任意地定义比例和精度。
二进制算术: [+、-、*、/、%]
比较运算符: [>、<、<=、>=、<=>]
分组运算符: [Avg、Min、Max、Count、Sum]
空检查
注意:对于二元运算,如果前导操作数的数据类型不是 Big Decimal,查询引擎将尝试对 Big Decimal 进行截断和四舍五入,从而导致精度损失。
例如,以下表达式将导致精度损失,因为 1 是前导操作数并且不是大十进制:
1 - 3000000089999919191919190000000000000000.2000000
为了避免失去精度,请使用强制转换:
cast(1, decimal(48,7) - 3000000089999919191919190000000000000000.2000000)
Web3 原生数据类型可实现高保真 Web3 分析用例,否则无法实现真正的精度:
Gas 优化是大多数智能合约作者主要关心的问题,但开发人员如何知道什么是“好”?当自费用户开始寻找替代方案时,断点在哪里?能够进行精确的数据仓库/大数据分析意味着能够轻松了解 Gas 消耗的生态系统如何随时间变化,并帮助开发人员将其 Gas 使用情况置于更广泛的行业背景中,无论是 DeFi、DEX 还是游戏。\
同样,使用机器学习模型来预测未来的 Gas 费用可以让开发人员和用户了解各种价格点的未来可能性。这为用户提供了大量使用的计划,以做出最有效的选择,也为寻求提供更低成本替代方案的开发人员提供了帮助。
