EOS 数据库结构详解
在 EOS 中,智能合约执行完毕后,所占用的内存会释放。程序中的全部变量都会丢失。若是智能合约里要持久地记录信息,好比游戏智能合约要记录每位用户游戏记录,本次合约执行完毕后数据不能丢失,就须要将数据存储到 EOS 数据库中。与数据库交互的 API 被官方称为 Persistence API,中文能够叫作持久化 API。下图说明了 EOS 智能合约在执行 Action 时,与数据库的交互过程。git
为了方便智能合约与 EOS 数据库的交互,EOS 仿造了 Boost 库中的 Multi-Index Containers
,开发了 C++ 类:eosio::multi_index(如下简称
multi_index`),中文能够叫作多索引列表类。github
multi_index
头文件地址:
https://github.com/EOSIO/eos/...数据库
在 EOS 见证人硬盘中,为每一个帐户都预留了数据库空间(大小与代币持有量有关),每一个帐户名下能够创建多个数据表。智能合约没法直接操做存储在见证人硬盘中的数据表,须要使用multi_index
做为中间工具(或者叫容器),每一个multi_index
实例都与一个特定帐户的特定数据表进行交互(取决于实例化时的参数)。EOS智能合约与EOS数据库的数据交互以下图所示。segmentfault
multi_index
是一个很是方便的数据库交互容器,能够存储任何 C++ 数据类型。每个multi_index
都至关于传统数据库的一个数据表(table),但将传统数据库的行与列的形式改成了单纯的列。也就是说multi_index
是一个线性排列的表,只有一列,每一行都只存储一个对象。可是通常来讲multi_index
存储的对象都是结构体或者类,里面含有多个成员变量,因此multi_index
存储数据的灵活性也是不亚于传统数据库的。windows
咱们使用官方的“汽车维修店”示例,咱们创建一个数据表,储存每一个汽车维修店客户的帐户名、保养时间、车辆里程。那么multi_index
数据表储存的项目中,每一个都是以下的结构体:设计模式
struct service_rec { uint64_t pkey; // 主键 account_name customer; // 车主用户名 uint32_t service_date; // 维修保养时间 uint32_t odometer; // 车辆里程 };
在传统数据库中,须要创建一个 4 列的数据表,用来储存每一个用户的这个 4 个数据,而multi_index
的每一个数据表只有一列,只存储每一个用户的 service_rec
整个结构体便可。下图为multi_index
数据结构。数据结构
首先,每一个数据表要有一组主键,主键必须是无符号 64 位整数类型(64-bit integer),这就是上面的service_rec
结构体中第一个变量为uint64_t
类型的缘由。在数据表中,全部的对象就是按照主键升序排列的,小的在前,大的在后。主键能够是有意义的,也能够是没有意义的,让系统产生一个在这个数据表中没有被使用的主键便可。为了设置主键,咱们须要在以前的service_rec
结构体添加一个叫作primary_key()
的成员函数函数的返回值为主键。dom
auto primary_key()const { return pkey; }
这样就将pkey
这个变量设置成了主键。函数
multi_index
从字面上看就是能使用多个索引的数据表。EOS 中,每一个multi_index
或者说每一个数据表均可以设置最多16个索引。索引至关于使用特定的方式给数据表中的对象从新排序。好比在咱们常用的 windows 文件管理器中,能够按照文件名排序、按照文件修改时间排序、按照文件大小排序,这就有了3个索引。EOS 数据库索引更加灵活,能够单独按照结构体中的某个变量索引,也能够将变量之间的运算结果(函数输出)进行索引。若是咱们想使用车主用户名
进行索引,须要在结构体中添加一个get_customer()
成员函数,函数的返回值为索引变量。工具
account_name get_customer()const { return customer; }
这样就将customer
这个变量设置成了数据表的一个索引,下图右侧为customer
索引。
multi_index
是如何操做数据表中的每一个对象的呢?答案是 Iterators(迭代器)。你们能够搜索 “C++ 迭代器”或者设计模式中的“迭代器模式”来了解迭代器的设计思路。在 EOS 数据库中,我更愿意将迭代器比喻为一个“电梯”,在整个数据表中上下穿梭。全部对数据的操做必须经过迭代器完成。典型的数据修改过程是这样的:首先使用迭代器的find()
方法,在特定的索引中寻找须要的数据,好比在车主用户名索引中寻找某个用户。迭代器会移动到须要的数据对象上。而后就可使用迭代器的modify()
方法修改当前迭代器对应的数据。下图为迭代器指向用户 Sue 的状况。
本篇文章介绍了 EOS 数据库的基本结构,之后的文章会详细介绍 EOS 数据库使用实战,敬请期待。
圆方圆学院聚集大批区块链名师,打造精品的区块链技术课程。 在各大平台都长期有优质免费公开课,欢迎报名收看。
公开课地址:https://ke.qq.com/course/345101