一文详解区块链的存储体系
从数据库的角度看待区块链的存储机制会简单直观很多。在一个标准的关系型数据库中,存储一般分为日志存储、用户数据存储、以及索引存储三大类(有些数据库可能还包含大对象存储等)。而区块链项目中基本所有的“账本”存储其本质就是交易日志存储。用户数据存储则根据项目不同而有选择性地采用。譬如说对于UTXO结构的区块链项目来说,其每个账号对应的余额直接保存在内存哈希表中(或类似LevelDB等嵌入式KV数据库中),因此不需要一个独立的外接用户数据存储模块。而类似Hyperledger等通用区块链框架则一般包含类似State Store等存储最终结果数据的模块。索引存储则在当前大部分区块链项目中均不存在。 1.账本格式 区块链的链式结构笔者在这里不再赘述,其每个块包含上一个块的哈希值,而内容则使用默克尔树进行校验以实现快速验证,每条记录则使用数字签名的方式保证其一定来自拥有私钥的用户。 (图1:区块链数据结构) 对比传统数据库的日志结构,区块链结构并不复杂。一般来说,所有传统数据库日志结构都比较相似,每个日志文件包含日志头与多个日志数据页,其中日志头代表其起始交易号(Oracle中叫做SCN,DB2中叫做LSN),也就是该日志文件中第一条日志记录在整个日志空间中的起始字节数,以及日志文件大小,日志页大小等元数据信息。紧接着真实的日志记录则以二进制码流的方式依次存放在文件中,每一条日志记录头包含该条记录的交易号、事务号、同一事务中上一条记录的交易号(反向指针),以及变更前与变更后的数据(满足回滚要求)。 因此,从结构上来看,区块链账本与数据库日志本质上没有任何区别,仅仅在数据结构上为了满足一些特定要求做了部分优化。 2. 存储内容 通用型数据库与当前大部分区块链账本项目(例如比特币、以太坊等,而Hyperledger这类区块链平台则不包含在内)从日志的角度看,最大的区别在于区块链账本项目对于日志格式进行了高度定制化与业务绑定。 一般来说,传统的数据库日志包含的是数据页的变更信息,我们叫做“写前镜像”和“写后镜像”,代表新的数据写入前这条记录长什么样子,同时新数据写入后这个记录长什么样子。通过这种方式,可以很轻易地在磁盘中的某个数据页的指定偏移上进行数据前滚与回滚操作。 譬如说一条数据库日志并不会记录一个INSERT操作的具体命令,而是以“X数据页的第Y个槽位,其所对应的偏移地址数据由ABC变化为DEF,总长度Z”的方式体现出来。因此,数据库的日志几乎可以记录任何信息,这也是为什么通用数据库可以被用来实现任何业务逻辑的原因。 而大部分的账本项目则高度定制化其日志结构,例如以太坊的每一条交易信息都会包含输入金额、输出金额、燃料等信息,然后每一个节点在进行验证时必须判断其符合某种规则,否则不予通过。这种机制可以看做是一个完全高度定制化的数据库业务,每一条日志记录不仅仅记录数据内容的变更,而是与业务逻辑紧密耦合,记录每个账户的余额变化。 因此,从可扩展性来看,尽管以太坊等项目支持“智能合约”,但是其核心本质还是一个高度定制化的账本系统,其业务逻辑与交易结算进行了非常紧密的绑定。 3. 设计思路 从设计哲学上看,当前的区块链与数据库在对通用业务的支持上采用了两种不同的策略。对于传统数据库来说,其秉承的设计理念是“业务与数据分离”的思路,也就是说数据库仅负责数据的存放,通过提供一种灵活的查询语言能够让应用程序直接访问数据库进行增删改查,但是基本所有的业务逻辑由应用程序自行定义。 但是,对于区块链来说则是存储与业务逻辑紧耦合的思路。在区块链,尤其是公链的设计哲学中,因为每个存储节点和应用都是不可信的,因此大部分业务逻辑需要在协议层进行高度定制。一个区块链节点即需要对协议层进行解析和封装,同时也需要负责对数据本地化落盘和存储。 因而,尽管站在高层面可以将区块链看做是多活数据库,但是如果从具体实现层面来看,每个区块链节点又不能简单地看做是一个传统数据库的多活替代品,而是一套包含协议解析封装和一部分业务逻辑的应用软件。 4. 用户数据存储 如果未来区块链的目标是作为通用平台,用以存储多种类型的数据,则其日志格式与存储必须回归数据库的通用性本源。当前的账本模式可以作为该体系中的一个特别模块存在用以进行账户间结算,但是无法将其扩展为通用业务平台。 既然要成为通用数据存储平台,那么UTXO模型存在一定局限性。在一个典型的银行业务中,零售业务可能会包含千万甚至亿级别的账户,不同账户可能使用不同的利息计算规则,也可能存在冻结等特殊状态。而交易流水信息每天可能达到千万笔,如果将其业务扩展到非金融行业,流水信息每天几亿也是可能的。因此,从一个通用账户+流水的业务模型中,一般企业会建立一个账户表与一个流水表,以不同的策略进行管理。 账户表俗称余额类数据,在典型的数据治理体系中需要做到定期快照备份(例如月初数和月末数);而流水表则成为流水类数据,一般来说以原始交易格式直接存储和备份。通过对余额类数据快照备份的恢复,对指定账号重做某个时间范围内的全部交易流水,可以得到该账号任意时间点的余额信息。 而UTXO的本质在于日志存放的信息不是记录的最终结果,而是变化行为。在传统数据库中,每条事务记录的是数据的写前与写后内容。例如将一条记录从5更改为8,其数据库日志记录原始数据为5且新数据为8,而不是记录“+3”的操作。但是UTXO记录的是变更信息,其主要的目的是解决双花问题(例如对于一个有100块钱的账号,一个人在中国转走10块钱,另一个人在美国同时转走10块钱,如果记录的是最终结果,那么中国的服务器会认为这个人有90块,美国的服务器在没有全局锁的情况下也会认为这个人有90块,最终写到区块中就变成90块余额,而非80)。 (编辑:应用网_阳江站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |