尽管不同的键值数据库采用了不同的实现细节,有些甚至采用了分布式架构,或者具有多机备份能力,但是这些键值数据库对用户而言提供的都是相似的数据接口,包括Put、Del、Get和Range(部分键值数据库支持)等。简单来说,Put、Del、Get和Range操作分别对应插入/修改一个键值对、删除一个键所对应的键值对、查询一个键所对应的键值对,以及按照键的字典序查询数据库中从某个键开始的若干个键值对。采用哈希索引结构的键值数据库,例如Redis、Memcached和FASTER等放弃了对范围查询操作的支持,但是换来了更好的性能和更高的分区扩展性;而RocksDB、LevelDB和BerkelyDB这些采用有序存储结构或者范围索引的数据库则提供了对范围查询的支持,以满足部分用户的范围查询需求。
下面来详细定义一下这4种基本的数据操作。
1)Put(k,v):如果键k在数据库中存在,将键k所对应的值修改为v;否则,将(k,v)插入到数据库中。
2)Del(k):如果键k在数据库中存在,将键k所对应的键值对从数据库中删除;否则不做任何操作。
3)Get(k):如果键k在数据库中存在,返回键k所对应的值;否则,返回null。
4)Range(k,len):假定数据库中的键值按照键的字典序升序排列,Range操作首先定位到第一个大于或等于k的键,并从这个键开始返回len个键值对。
大部分键值存储引擎只提供了上面3~4种基本数据操作,并且提供了多个操作的并行支持,例如FASTER、RocksDB、LevelDB等,这些数据操作足以向多个并发用户提供对数据库的读/写操作,并且保证较高的读写吞吐。对于现如今的新媒体时代的应用,例如短视频应用、云音乐应用等在线媒体服务器,其后端均采用了类似上述4种基本数据操作的键值数据库。
尽管一个支持多线程的键值存储引擎能够满足绝大部分的键值存取需求,但是为了实现更高层的业务逻辑,保证敏感性业务的可靠性和一致性,部分键值数据库也提供了类似关系数据库的事务操作,例如Redis、Riak、CosmosDB等。考察一个由基本操作构成的序列,键值数据库的事务操作类似关系数据库的事务,提供了对事务内部基本操作序列的ACID性质保证。举例来说,对于一个基本操作序列T:
键值数据库的事务操作能够保证T的操作是原子执行的,这意味着,T的整个执行序列要么完全执行,要么都不执行,不会出现部分执行的状态。并且事务T的执行不会与基本操作序列发生冲突,以对执行事务T的上层应用提供一种在单独访问数据库的抽象。