一个简单的NoSQL内存数据库—Berkeley DB基本操作的例子

最近,由于云计算的发展,数据库技术也从结构式数据库发展到NoSQL数据库,存储模式从结构化的关系存储到现在如火如荼的key/value存储。其中Berkeley

DB就是上述过程中的一个比较有代表性的内存数据库产品,数据库的操作是通过程序来实现的,而不是SQL语句。特别是当今数据不断动态增加的过程中,试图
通过数据切割来达到扩充的思路已经行不通了,因为事先不知道客户数据格式,因此服务提供商不可能进行数据切割。而无模式的key/value存储就可以解
决这种扩充带来的可扩展性问题,因为key/value的存储模式正好可以使得扩充能够自动完成,不需要事先知道任何的数据格式问题。因此,目前NoSQL数据库基本都基于key/value的存储模式,如amazon的simpleDB,google的BigTable等。本文就详细描述key/value模式的一个比较有代表性的内存数据库Berkeley
DB,来介绍如何使用它来操作键值对数据。

Berkeley DB是一个开源的内存数据库,它提供的是一系列直接访问数据库的函数,而不是像关系数据库那样需要网络通讯、SQL解析等步骤。Berkeley
DB是一个高性能的,嵌入数据库编程库,“嵌
入”是指它内嵌在程序中,而不是说他只应用在嵌入式系统上。它适合于管理海量的,简单的数据。例如,Google用Berkeley
DB HA (High Availability) 来管理他们的帐户信息,Motorola在他的无线产品中用Berkeley
DB跟踪移动单元。HP,Microsoft,Sun
Microsystems等也都是它的大客户。它不能完全取代关系数据库,但在某些方面,它却有他们望尘莫及的高效性。

       关键字/数据(key/value)是Berkeley DB用来进行数据库管理的基础。前几年,key/value 这个词还是和 hash 表联系在一起的。而现在,程序员看见 key/value这个词时,马上联想到的就是 BigTable、SimpleDB 和云计算。当下,key/value 存储(或者叫
key/value Database、云存储等)是个非常时髦的词汇,越来越多的开发人员(特别是互联网企业)开始关注和尝试 key/value 的存储形式。
       每个
key/value对构成一条记录(数据表中的一行)。而整个数据库实际上就是由许多这样的结构单元所构成的。通过使用这种方式,开发人员在使用
Berkeley DB提供的API来访问数据库时,只需提供关键字就能够访问到相应的数据。当然也可以也可以提供 key
和部分value来查询符合条件的相近数据。
       Berkeley DB底层实现机制采用B树,可以看成能够存储大量数据的HashMap。Berkeley DB通过环境对象EnvironmentConfig来对数据库进行管理的,每个EnvironmentConfig对象可以管理多个数据库
        下面来介绍Berkeley DB是如何存入key/value键值对数据的。
1、定义一个序列化的java类,后面将把String和该类的映射<String,java类>存放到Berkeley DB中
package webspider.berkeleydb;

import java.io.Serializable;

/**
* 定义一个序列化的java类,放到Berkeley DB中
*
* @author typ
*
*/
public class Bean implements Serializable {
private static final long serialVersionUID = -6865837107626208563L; private Integer id;
private String name; public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} }
2、定义Frontier接口类,定义存储和获取键值对(key/value)时候需要实现的功能接口
package webspider.berkeleydb;

/**
* 定义需要实现的功能接口
*
* @author typ
*
*/
public interface Frontier {
/**
* 获得下一条记录
*
* @return
* @throws Exception
*/
public Bean getNext() throws Exception; /**
* 添加一条记录
*
* @param bean
* @return
* @throws Exception
*/
public boolean putNext(Bean bean) throws Exception; }
3、定义AbstractFrontier类,来封装Berkeley DB中的操作
package webspider.berkeleydb;

import java.io.File;
import com.sleepycat.bind.serial.StoredClassCatalog;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseConfig;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig; /**
* 封装Berkeley DB的操作
*
* @author typ
*
*/
public abstract class AbstractFrontier { private Environment env;
private static final String CLASS_CATALOG = "java_class_catalog";
protected StoredClassCatalog javaCatalog;
protected Database catalogDatabase;
protected Database database; /**
* 初始化数据库需要的各种变量
*
* @param homeDirectory
* @throws Exception
*/
public AbstractFrontier(String homeDirectory) throws Exception {
EnvironmentConfig envConfig = new EnvironmentConfig();
// 设置事务处理开启,
envConfig.setTransactional(true);
// AllowCreate属性表示没有数据库的前提下,可以自动创建数据库
envConfig.setAllowCreate(true);
// 定义Environment变量,homeDirectory指的是数据库存放路径
env = new Environment(new File(homeDirectory), envConfig);
// 设置数据库的属性
DatabaseConfig dbConfig = new DatabaseConfig();
dbConfig.setTransactional(true);
dbConfig.setAllowCreate(true);
// 通常java对象和java对象之间的映射关系要分开存放,放置到不同的数据库中
// 存放java对象的数据库
catalogDatabase = env.openDatabase(null, CLASS_CATALOG, dbConfig);
javaCatalog = new StoredClassCatalog(catalogDatabase);
// 存放key/value映射的数据库<String,JavaBean>
database = env.openDatabase(null, "String_JavaBean", dbConfig);
} /**
* 关闭数据库时候,关闭各种链接
*
* @throws Exception
*/
public void close() throws Exception {
database.close();
javaCatalog.close();
env.close();
} /**
* Berkeley DB的存储键值对操作
*
* @param key
* @param value
*/
protected abstract void put(Object key, Object value); /**
* Berkeley DB的得到键值对操作
*
* @param key
* @return
*/
protected abstract Object get(Object key); /**
* Berkeley DB的删除键值对操作
*
* @param key
* @return
*/
protected abstract Object delete(Object key);
}
4、设计实现类,实现数据库的插入,查找和删除功能(其实数据库的功能就是直接可以用java程序来实现的,这是Berkeley DB优点的地方,可以直接向操作普通java hash程序一样,操作数据库)
package webspider.berkeleydb;

import java.util.Map.Entry;
import java.util.Set;
import com.sleepycat.bind.EntryBinding;
import com.sleepycat.bind.serial.SerialBinding;
import com.sleepycat.collections.StoredMap; /**
* 具体实现类
*
* @author typ
*
*/
public class BDBFrontier extends AbstractFrontier implements Frontier {
// 建立map,存储key/value键值对
private StoredMap pendingUrisDBMap; /**
* 初始化java对象数据库和对象映射数据库
*
* @param homeDirectory
* @throws Exception
*/
public BDBFrontier(String homeDirectory) throws Exception {
super(homeDirectory);
// 定义key和value的Entry
EntryBinding keyBinding = new SerialBinding(javaCatalog, String.class);
EntryBinding valueBinding = new SerialBinding(javaCatalog, Bean.class);
// map存放在database中,database存放key/value映射
pendingUrisDBMap = new StoredMap(database, keyBinding, valueBinding,
true);
} /*
* (non-Javadoc)
*
* @see webspider.berkeleydb.Frontier#getNext()
*/
public Bean getNext() throws Exception {
Bean bean = null;
if (!pendingUrisDBMap.isEmpty()) {
Set<Entry<String, Bean>> entrys = pendingUrisDBMap.entrySet();
Entry<String, Bean> entry = (Entry<String, Bean>) pendingUrisDBMap
.entrySet().iterator().next();
bean = entry.getValue();
delete(entry.getKey());
}
return bean;
} /* (non-Javadoc)
* @see webspider.berkeleydb.Frontier#putNext(webspider.berkeleydb.Bean)
*/
public boolean putNext(Bean bean) throws Exception {
put(bean.getName(), bean);
return true;
} /*
* (non-Javadoc)
*
* @see webspider.berkeleydb.AbstractFrontier#put(java.lang.Object,
* java.lang.Object)
*/
protected void put(Object key, Object value) {
pendingUrisDBMap.put(key, value);
} /*
* (non-Javadoc)
*
* @see webspider.berkeleydb.AbstractFrontier#get(java.lang.Object)
*/
protected Object get(Object key) {
return pendingUrisDBMap.get(key);
} /*
* (non-Javadoc)
*
* @see webspider.berkeleydb.AbstractFrontier#delete(java.lang.Object)
*/
protected Object delete(Object key) {
return pendingUrisDBMap.remove(key);
} /**
* 测试效果,可以看到在f:\bdb文件夹下面生成了.jdb和.lck等Berkeley DB相关文件,数据存储在.jdb中
* 控制台输出刚刚插入的数据bean的Name值LiMing
*/
public static void main(String[] args) {
try {
BDBFrontier frontier = new BDBFrontier("f:\\bdb");
Bean bean = new Bean();
bean.setName("LiMing");
frontier.putNext(bean);
System.out.println(frontier.getNext().getName());
frontier.close();
} catch (Exception e) {
e.printStackTrace();
}
} }

从上述过程看来,Berkeley DB可以很好的实现key/value这种存储方式,而且完全是通过一系列直接访问数据库的函数,而不是像关系数据库那样需要数据库连接、SQL解析等步骤。完全跟java程序中操作HashMap没有太大的区别,比较容易上手。

一个简单的NoSQL内存数据库—Berkeley DB基本操作的例子的更多相关文章

  1. 一个简单的C#+arcgis的非数据库版例子

    1.首先新建一个winform的项目. 2.确保C#工具箱包含ESRI的相关控件,如果没有就需要安装SDK. 如果VS中依旧不存在esri控件解决方案如下,以VS2013为例: (1)打开注册表,定位 ...

  2. 一个简单的div弹出层的小例子

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...

  3. 一个简单的使用mock技术进行测试的例子

    Account: public class Account { private String acountId; private long balance; public Account(String ...

  4. The Architecture of Open Source Applications: Berkeley DB

    最近研究内存关系数据库的设计与实现,下面一篇为berkeley db原始两位作为的Berkeley DB设计回忆录: Conway's Law states that a design reflect ...

  5. 一个简单的 MVVM 实现

    简介 一个简单的带有双向绑定的 MVVM 实现. 例子 使用 新建一个 ViewModel 对象, 参数分别为 DOM 元素以及绑定的数据即可. 指令 本 MVVM 的指令使用 data 数据, 即 ...

  6. socket编程——一个简单的例子

    从一个简单的使用TCP例子开始socket编程,其基本步骤如下: server                                                  client ++++ ...

  7. 一个简单的基于 DirectShow 的播放器 1(封装类)

    DirectShow最主要的功能就是播放视频,在这里介绍一个简单的基于DirectShow的播放器的例子,是用MFC做的,今后有机会可以基于该播放器开发更复杂的播放器软件. 注:该例子取自于<D ...

  8. 了解 Oracle Berkeley DB 可以为您的应用程序带来 NoSQL 优势的原因及方式。

    将 Oracle Berkeley DB 用作 NoSQL 数据存储 作者:Shashank Tiwari 2011 年 2 月发布 “NoSQL”是在开发人员.架构师甚至技术经理中新流行的一个词汇. ...

  9. BDB (Berkeley DB)数据库简单介绍(转载)

    近期要使用DBD,于是搜了下相关的资料,先贴个科普性的吧: 转自http://www.javaeye.com/topic/202990 DB综述DB最初开发的目的是以新的HASH訪问算法来取代旧的hs ...

随机推荐

  1. 用jq给img添加error事件

    <img src="xxxx.jpg" alt="" /> <script> $(document).ready(function(){ ...

  2. Android四大基本组件介绍及生命周期

    Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器. 一.了解四大基本组件 Activity ...

  3. The Tower of Babylon UVA - 437 DAG上的动态规划

    题目:题目链接 思路:每个方块可以用任意多次,但因为底面限制,每个方块每个放置方式选一个就够了,以x y为底 z 为高,以x z为底 y 为高,以y z为底 x为高,因为数据量很小,完全可以把每一种当 ...

  4. V4L2学习(五)VIVI虚拟摄像头驱动

    概述 前面简单分析了内核中虚拟摄像头驱动 vivi 的框架与实现,本文参考 vivi 来写一个虚拟摄像头驱动,查询.设置视频格式相对简单,难点在于 vb2_buf 的处理过程. 数据采集流程分析 在我 ...

  5. 给B公司的一些建议(又一篇烂尾的文章)

    感慨:太多太多的悲伤故事,发生在自己身上,发生在自己的身边.因此,为了避免总是走"弯路",走"错误"的道路,最近一直在完善自己的理论模型. 烂尾说明:本文是一篇 ...

  6. 怕忘记-windows 2003服务器安装Node.js NPM

    现在高版本的Nodejs安装已经自带了NPM模块,本次我需要安装的是:supervisor 执行命令: npm install -g supervisor 等待安装完成. 查看版本可以cmd里面运行: ...

  7. Composer 下载安装类库

    安装 Composer 你需要先下载 composer.phar 可执行文件. curl -sS https://getcomposer.org/installer | php composer.js ...

  8. live 555 freebsd 或centos 7.4 实现代理视频直播服务

    live 555   freebsd 或centos 7.4 实现代理视频直播服务 the live555 media server    在线直播服务器 关于此服务器 此服务是一个无安全的rtsp服 ...

  9. 12 JVM 垃圾回收(下)

    Java 虚拟机的堆划分 Java 虚拟机将堆划分为新生代和老年代.其中新生代又被划分为 Eden 区,以及两个大小相同的 Survivor 区. 默认情况下,Java 虚拟机采取一种动态分配的策略, ...

  10. 精通CSS高级Web标准解决方案(3-1 背景图像与图像替换)

    3.1背景图像基础 3.2图像替换 使用文本的图像并保留文本的方法.