1. 引言

一次偶然的机会接触到了iBoxDB这样一个小型的嵌入式对象数据库。感觉非常惊讶有这样轻巧的数据库。iBoxDB 本身是一个NOSQL 同时也有关系数据库的特点。

说说iBoxDB的优点:

1)无需安装,不像其他数据库比如MongoDB, MySQL 需要安装。iBOXDB只需要某个目录存放最终的数据即可。完全就像操作本地文件一  样,应该说比本地文件更方便。

2) 支持多种设备,只需要添加.Net 或者 Java的驱动程序,就可以在多种设备上使用iBoxD,比如Android, Linux,Windows Phone, PC程序等。

3)提供数据库事务支持,可以使用类SQL语法存取对象数据。

4)提供索引,主键以及主从和多主的数据库热同步。

4) 性能优越,这里展示下iBoxDB官方网站提供的和MongoDB性能测试对比结果

在32位机子下的测试结果,代码见Github

这里可以看到iBoxDB有三种运行模式:File 、 MemoryMappedFile、 InMemory。熟悉操作系统的同学对这三个概念肯定不会陌生。它的性能一个比一个高。

2. iBoxDB 的 CRUD 操作

任何DB的肯定包含CRUD的操作,这里给出一个简单的C#实现。

        public class Account
{
public string Name { get; set; }
public int Age { get; set; }
public string Email { get; set; }
public string Desc { get; set; } } public static DB.AutoBox InitAndCreateAutoBox()
{
var dbPath = Path.Combine(Directory.GetCurrentDirectory(), "ibox");
if (!Directory.Exists(dbPath))
{
Directory.CreateDirectory(dbPath);
} var server = new DB(dbPath);
var config = server.GetConfig(); config.EnsureTable<Account>("AccountTable", "Name"); return server.Open();
}

函数 InitAndCreateAutoBox 初始化iBoxDB的环境,创建需要表以及指定主键,保存最终数据的目录。

从DB.Open()方法可获得一个AutoBox对象,这个对象是操作CRUD的。它不需要管理,也不需要释放。

比如:

        static void Main(string[] args)
{
//初始化DB
var box = InitAndCreateAutoBox(); //插入数据
box.Insert("AccountTable",
new Account() {Name = "001", Age = 14, Desc = "this is test", Email = "fake@qq.com"});
box.Insert("AccountTable",
new Account() {Name = "002", Age = 88, Desc = "this is test 33", Email = "fake2@qq.com"});
box.Insert("AccountTable",
new Account() { Name = "003", Age = 88, Desc = "this is test 88", Email = "fake3@qq.com" }); //更新特定数据
var account = box.SelectKey<Account>("AccountTable", "001");
account.Age = 15;
account.Desc = "fake";
account.Email = "email";
box.Update("AccountTable", account); //删除特定数据
box.Delete("AccountTable", "002"); var age15Account = box.Select<Account>("from AccountTable where Age==?", 88);
}

另外一种方式就是利用AutoBox.Cube()获得一个Box对象,这个对象是用于控制事务的。此对象一定要释放,典型的就是利用using语句。

        static void Main(string[] args)
{
//初始化DB
var box = InitAndCreateAutoBox(); using (var cube = box.Cube())
{
cube.Bind("AccountTable")
.Insert(new Account() {Name = "001", Age = 14, Desc = "this is test", Email = "fake@qq.com"});
                cube.Bind("AccountTable")
                    .Insert(new Account() {Name = "002", Age = 15, Desc = "this is test", Email = "fake@qq.com"});
                var result = cube.Commit();
}
}

如果是一次性批量处理数据,最好是在一个事务中进行,建议使用Cube,这样效率可以达到最好。

3. iBoxDB下数据库同步

可以看到iBoxDB对于CRUD的便利,利用iBoxDB我们可以快速的搭建一个数据存储的原型并且Demo。但是如何才能将iBoxDB运用到实际的生产环境肯定还有很多工作需要完成。

如果数据量达到某种程度。对于Website而言数据库服务器很有可能成为网站的性能瓶颈。配置数据库的master slave 实现读写分离已经是老生常谈的问题。

不像MongoDB, 直接可以通过配置实现数据同步,iBoxDB 需要代码来实现同步,它提供两种形式:

不管哪种形式都,iBoxDB都用IBoxRecycler 实现数据同步。

这里自定义一个简单的接口实现,主要就是提取出master中数据存放到内存。

    public class Package
{
public Socket Socket;
public byte[] OutBox;
}
    public class InMemoryBoxRecycler : IBoxRecycler
{
List<Package> qBuffer;
public InMemoryBoxRecycler(long name, DatabaseConfig config)
{
qBuffer = new List<Package>();
} public void OnReceived(Socket socket, BoxData outBox, bool normal)
{
if (socket.DestAddress == long.MaxValue)
{
return;
}
lock (qBuffer)
{
qBuffer.Add(new Package { Socket = socket, OutBox = outBox.ToBytes() });
}
}
public List<Package> GetPackage()
{
return qBuffer;
}
        public void Dispose()
{
qBuffer = null;
}
}

自定义Server来管理所有的master 和 slave 节点

    public class MsaterSlaveReplicableServer : LocalDatabaseServer
{
public const int MasterAddress = 10;
public const int SlaveAddress = 11; protected override DatabaseConfig BuildDatabaseConfig(long name)
{
if (name == MasterAddress || name == SlaveAddress)
{
var config = new DBPlatform.Config();
config.EnsureTable<Account>("Account", "Name");
} throw new NotImplementedException(name);
} protected override IBoxRecycler BuildBoxRecycler(long name, DatabaseConfig config)
{
if (name == MasterAddress || name == SlaveAddress)
{
return new InMemoryBoxRecycler(name, config);
} return base.BuildBoxRecycler(name, config);
}
}

最后启动Server:

              using (var server = new MsaterSlaveReplicableServer())
{
var master = server.GetInstance(MsaterSlaveReplicableServer.MasterAddress);
var slave = server.GetInstance(MsaterSlaveReplicableServer.SlaveAddress); //在master 节点中插入数据
using (var box = master.Cube())
{
for (var i = 0; i < 10; i++)
{
box.Bind("Account").Insert(
new Account()
{
Name = "account" + i,
Age = i,
Desc = "fake",
Email = "email" + i
});
}
box.Commit();
} //将master数据复制到slave
var recycler = (InMemoryBoxRecycler)master.GetBoxRecycler();
lock (recycler.GetPackage())
{
foreach (var p in recycler.GetPackage())
{
if (p.Socket.SourceAddress == MsaterSlaveReplicableServer.MasterAddress)
{
(new BoxData(p.OutBox)).SlaveReplicate(slave).Assert();
}
}
recycler.GetPackage().Clear();
} //检查slave 中的数据
using (var box = slave.Cube())
{
foreach (var item in box.Select<Account>("from Account", null))
{
Console.WriteLine(item);
}
}
}

4. 总结

iBoxDB 这样轻巧的数据库非常适合做项目Demo,但是在实际的Production环境中还是介意大家用MongoDB 等数据库。

欢迎访问我的个人网站 51zhang.net 网站还在不断开发中…

iBoxDB的学习与使用的更多相关文章

  1. 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代

    2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...

  2. Angular2学习笔记(1)

    Angular2学习笔记(1) 1. 写在前面 之前基于Electron写过一个Markdown编辑器.就其功能而言,主要功能已经实现,一些小的不影响使用的功能由于时间关系还没有完成:但就代码而言,之 ...

  3. ABP入门系列(1)——学习Abp框架之实操演练

    作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...

  4. 消息队列——RabbitMQ学习笔记

    消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...

  5. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  6. Unity3d学习 制作地形

    这周学习了如何在unity中制作地形,就是在一个Terrain的对象上盖几座小山,在山底种几棵树,那就讲一下如何完成上述内容. 1.在新键得项目的游戏的Hierarchy目录中新键一个Terrain对 ...

  7. 《Django By Example》第四章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:祝大家新年快乐,这次带来<D ...

  8. 菜鸟Python学习笔记第一天:关于一些函数库的使用

    2017年1月3日 星期二 大一学习一门新的计算机语言真的很难,有时候连函数拼写出错查错都能查半天,没办法,谁让我英语太渣. 关于计算机语言的学习我想还是从C语言学习开始为好,Python有很多语言的 ...

  9. 多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)

    前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...

随机推荐

  1. Ubuntu 下配置Ganglia监控

    Ganglia是比较知名的开源监控系统, 运维上需要关注的一些通用的状态都有所涉及.其组成主要是gmond(监控程序),gmetad(信息收集程序),web(监控数据展现app).ubuntu的apt ...

  2. 知方可补不足~SQL2005使用ROW_NUMBER() OVER()进行数据分页

    回到目录 数据分页是这个经常说的东西,无论在WEBForm还是WinForm中它都会被单独拿出来,或者是公用组件,或者是公用类库,反正对于数据分页这个东西,总是我们关注的一个话题,但事实上,数据分页归 ...

  3. position格式布局

    布局大体分为: 位置--position 绝对坐标 absolute 绝对定位的元素 不受其他位置影响 可通过z-index进行层次分级 body来定位自己 相对坐标 设置  top和left之后 r ...

  4. Atitit vod ver 12 new feature v12 pb2 影吧 视频 电影 点播 播放系统v12新特性

    Atitit vod ver 12 new feature v12 pb2 影吧 视频 电影 点播 播放系统v12新特性 项目分离从独立的se ver Run mode from brow ex to ...

  5. fir.im weekly - 「 持续集成 」实践教程合集

    我们常看到许多团队和开发者分享他们的持续集成实践经验,本期 fir.im Weekly 收集了 iOS,Android,PHP ,NodeJS 等项目搭建持续集成的实践,以及一些国内外公司的内部持续集 ...

  6. asp.net 文件 操作方法

    /// <summary> /// 移动文件 /// </summary> /// <param name="oldPath">源文件路径< ...

  7. unity生成WP工程后ExtendedSplashImage显示不正确的问题

    这个bug我已经彻底无语了,居然这么久都没有fix. 解决方法如下: <SwapChainPanel x:Name="DXSwapChainPanel"> <Gr ...

  8. mysql命令详解

    mysqld.exe 和 mysql.exe 有什么区别? mysqld.exe 是MySQL后台程序(即MySQL服务器).要想使用客户端程序,该程序必须运行,因为客户端通过连接服务器来访问数据库. ...

  9. Testing - 测试基础 - 用例

    测试用例 是指对一项特定的软件产品进行测试任务的描述,体现测试方案.方法.技术和策略. 内容包括测试目标.测试环境.输入数据.测试步骤.预期结果.测试脚本等,并形成文档. 每个具体测试用例都将包括下列 ...

  10. Hadoop阅读笔记(七)——代理模式

    关于Hadoop已经小记了六篇,<Hadoop实战>也已经翻完7章.仔细想想,这么好的一个框架,不能只是流于应用层面,跑跑数据排序.单表链接等,想得其精髓,还需深入内部. 按照<Ha ...