一个简单的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中
  1. package webspider.berkeleydb;
  2.  
  3. import java.io.Serializable;
  4.  
  5. /**
  6. * 定义一个序列化的java类,放到Berkeley DB中
  7. *
  8. * @author typ
  9. *
  10. */
  11. public class Bean implements Serializable {
  12. private static final long serialVersionUID = -6865837107626208563L;
  13.  
  14. private Integer id;
  15. private String name;
  16.  
  17. public Integer getId() {
  18. return id;
  19. }
  20.  
  21. public void setId(Integer id) {
  22. this.id = id;
  23. }
  24.  
  25. public String getName() {
  26. return name;
  27. }
  28.  
  29. public void setName(String name) {
  30. this.name = name;
  31. }
  32.  
  33. }
2、定义Frontier接口类,定义存储和获取键值对(key/value)时候需要实现的功能接口
  1. package webspider.berkeleydb;
  2.  
  3. /**
  4. * 定义需要实现的功能接口
  5. *
  6. * @author typ
  7. *
  8. */
  9. public interface Frontier {
  10. /**
  11. * 获得下一条记录
  12. *
  13. * @return
  14. * @throws Exception
  15. */
  16. public Bean getNext() throws Exception;
  17.  
  18. /**
  19. * 添加一条记录
  20. *
  21. * @param bean
  22. * @return
  23. * @throws Exception
  24. */
  25. public boolean putNext(Bean bean) throws Exception;
  26.  
  27. }
3、定义AbstractFrontier类,来封装Berkeley DB中的操作
  1. package webspider.berkeleydb;
  2.  
  3. import java.io.File;
  4. import com.sleepycat.bind.serial.StoredClassCatalog;
  5. import com.sleepycat.je.Database;
  6. import com.sleepycat.je.DatabaseConfig;
  7. import com.sleepycat.je.Environment;
  8. import com.sleepycat.je.EnvironmentConfig;
  9.  
  10. /**
  11. * 封装Berkeley DB的操作
  12. *
  13. * @author typ
  14. *
  15. */
  16. public abstract class AbstractFrontier {
  17.  
  18. private Environment env;
  19. private static final String CLASS_CATALOG = "java_class_catalog";
  20. protected StoredClassCatalog javaCatalog;
  21. protected Database catalogDatabase;
  22. protected Database database;
  23.  
  24. /**
  25. * 初始化数据库需要的各种变量
  26. *
  27. * @param homeDirectory
  28. * @throws Exception
  29. */
  30. public AbstractFrontier(String homeDirectory) throws Exception {
  31. EnvironmentConfig envConfig = new EnvironmentConfig();
  32. // 设置事务处理开启,
  33. envConfig.setTransactional(true);
  34. // AllowCreate属性表示没有数据库的前提下,可以自动创建数据库
  35. envConfig.setAllowCreate(true);
  36. // 定义Environment变量,homeDirectory指的是数据库存放路径
  37. env = new Environment(new File(homeDirectory), envConfig);
  38. // 设置数据库的属性
  39. DatabaseConfig dbConfig = new DatabaseConfig();
  40. dbConfig.setTransactional(true);
  41. dbConfig.setAllowCreate(true);
  42. // 通常java对象和java对象之间的映射关系要分开存放,放置到不同的数据库中
  43. // 存放java对象的数据库
  44. catalogDatabase = env.openDatabase(null, CLASS_CATALOG, dbConfig);
  45. javaCatalog = new StoredClassCatalog(catalogDatabase);
  46. // 存放key/value映射的数据库<String,JavaBean>
  47. database = env.openDatabase(null, "String_JavaBean", dbConfig);
  48. }
  49.  
  50. /**
  51. * 关闭数据库时候,关闭各种链接
  52. *
  53. * @throws Exception
  54. */
  55. public void close() throws Exception {
  56. database.close();
  57. javaCatalog.close();
  58. env.close();
  59. }
  60.  
  61. /**
  62. * Berkeley DB的存储键值对操作
  63. *
  64. * @param key
  65. * @param value
  66. */
  67. protected abstract void put(Object key, Object value);
  68.  
  69. /**
  70. * Berkeley DB的得到键值对操作
  71. *
  72. * @param key
  73. * @return
  74. */
  75. protected abstract Object get(Object key);
  76.  
  77. /**
  78. * Berkeley DB的删除键值对操作
  79. *
  80. * @param key
  81. * @return
  82. */
  83. protected abstract Object delete(Object key);
  84. }
4、设计实现类,实现数据库的插入,查找和删除功能(其实数据库的功能就是直接可以用java程序来实现的,这是Berkeley DB优点的地方,可以直接向操作普通java hash程序一样,操作数据库)
  1. package webspider.berkeleydb;
  2.  
  3. import java.util.Map.Entry;
  4. import java.util.Set;
  5. import com.sleepycat.bind.EntryBinding;
  6. import com.sleepycat.bind.serial.SerialBinding;
  7. import com.sleepycat.collections.StoredMap;
  8.  
  9. /**
  10. * 具体实现类
  11. *
  12. * @author typ
  13. *
  14. */
  15. public class BDBFrontier extends AbstractFrontier implements Frontier {
  16. // 建立map,存储key/value键值对
  17. private StoredMap pendingUrisDBMap;
  18.  
  19. /**
  20. * 初始化java对象数据库和对象映射数据库
  21. *
  22. * @param homeDirectory
  23. * @throws Exception
  24. */
  25. public BDBFrontier(String homeDirectory) throws Exception {
  26. super(homeDirectory);
  27. // 定义key和value的Entry
  28. EntryBinding keyBinding = new SerialBinding(javaCatalog, String.class);
  29. EntryBinding valueBinding = new SerialBinding(javaCatalog, Bean.class);
  30. // map存放在database中,database存放key/value映射
  31. pendingUrisDBMap = new StoredMap(database, keyBinding, valueBinding,
  32. true);
  33. }
  34.  
  35. /*
  36. * (non-Javadoc)
  37. *
  38. * @see webspider.berkeleydb.Frontier#getNext()
  39. */
  40. public Bean getNext() throws Exception {
  41. Bean bean = null;
  42. if (!pendingUrisDBMap.isEmpty()) {
  43. Set<Entry<String, Bean>> entrys = pendingUrisDBMap.entrySet();
  44. Entry<String, Bean> entry = (Entry<String, Bean>) pendingUrisDBMap
  45. .entrySet().iterator().next();
  46. bean = entry.getValue();
  47. delete(entry.getKey());
  48. }
  49. return bean;
  50. }
  51.  
  52. /* (non-Javadoc)
  53. * @see webspider.berkeleydb.Frontier#putNext(webspider.berkeleydb.Bean)
  54. */
  55. public boolean putNext(Bean bean) throws Exception {
  56. put(bean.getName(), bean);
  57. return true;
  58. }
  59.  
  60. /*
  61. * (non-Javadoc)
  62. *
  63. * @see webspider.berkeleydb.AbstractFrontier#put(java.lang.Object,
  64. * java.lang.Object)
  65. */
  66. protected void put(Object key, Object value) {
  67. pendingUrisDBMap.put(key, value);
  68. }
  69.  
  70. /*
  71. * (non-Javadoc)
  72. *
  73. * @see webspider.berkeleydb.AbstractFrontier#get(java.lang.Object)
  74. */
  75. protected Object get(Object key) {
  76. return pendingUrisDBMap.get(key);
  77. }
  78.  
  79. /*
  80. * (non-Javadoc)
  81. *
  82. * @see webspider.berkeleydb.AbstractFrontier#delete(java.lang.Object)
  83. */
  84. protected Object delete(Object key) {
  85. return pendingUrisDBMap.remove(key);
  86. }
  87.  
  88. /**
  89. * 测试效果,可以看到在f:\bdb文件夹下面生成了.jdb和.lck等Berkeley DB相关文件,数据存储在.jdb中
  90. * 控制台输出刚刚插入的数据bean的Name值LiMing
  91. */
  92. public static void main(String[] args) {
  93. try {
  94. BDBFrontier frontier = new BDBFrontier("f:\\bdb");
  95. Bean bean = new Bean();
  96. bean.setName("LiMing");
  97. frontier.putNext(bean);
  98. System.out.println(frontier.getNext().getName());
  99. frontier.close();
  100. } catch (Exception e) {
  101. e.printStackTrace();
  102. }
  103. }
  104.  
  105. }

从上述过程看来,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. hive的常用HQL语句

    1.过滤条件 where .limit. distinct. between and . null. is not nullselect * from emp where sal > 3000; ...

  2. 关于json数据中的多反斜杆转译--StringEscapeUtils.unescapeJava(踩过的坑)

    一.需求 现有一个字符串str String str = "{\\\"name\\\":\\\"spy\\\",\\\"id\\\\&quo ...

  3. VMWare workstation Pro 14 For Linux key

    VMWare workstation Pro 14 For Linux key: (我使用的Linux 系统是 Ubuntu16.04, 64位 ) 镜像是官方网址下载的,你也可以自己去官方网址下载: ...

  4. Diycode开源项目 TopicContentActivity分析

    1.效果预览以及布局分析 1.1.实际效果预览 左侧话题列表的布局是通过TopicProvider来实现的,所以当初分析话题列表就没有看到布局. 这里的话题内容不是一个ListView,故要自己布局. ...

  5. "帮你"-用户模板和用户场景

    场景/故事/story 典型用户: 用户性质 典型用户介绍 姓名 小李 年龄 20岁 职业 学生 代表的用户在市场上的比例和重要性 代表学校内广大普通学生,因此有很大的重要性. 使用本软件的典型场景 ...

  6. 使用 Sconfig.cmd 配置服务器核心服务器

    使用 Sconfig.cmd 配置服务器核心服务器 适用对象:Windows Server 2012 R2, Windows Server 2012 在 Windows Server 2012 中,你 ...

  7. 试水新的Angular4 HTTP API

    本文来自网易云社区 作者:梁月康 原文:https://netbasal.com/a-taste-from-the-new-angular-http-client-38fcdc6b359b Angul ...

  8. OpenStack之虚机热迁移代码解析

    OpenStack之虚机热迁移代码解析 话说虚机迁移分为冷迁移以及热迁移,所谓热迁移用度娘的话说即是:热迁移(Live Migration,又叫动态迁移.实时迁移),即虚机保存/恢复(Save/Res ...

  9. Python框架之Django学习笔记(一)

    Django历史: Django 是从真实世界的应用中成长起来的,它是由 堪萨斯(Kansas)州 Lawrence 城中的一个 网络开发小组编写的. 它诞生于 2003 年秋天,那时 Lawrenc ...

  10. 【palindrome partitioning II】cpp

    题目: Given a string s, partition s such that every substring of the partition is a palindrome. Return ...