Db4o(http://www.db4o.com/)是著名的开源对象数据库,使用它能够将持续层代码量降低到忽略不计的程度。如果数据量不大,用它能够将开发速度提高一个层次。
我手中的小项目需要储存约十万个联系人的数据,考察了sqlite与db4o,最终决定选用db4o. 我使用的是db4o 7.4 for .NET 2.0。关于db4o网上有很多文档,然而有一些问题,在网上不容易找到解决办法,总结一下,写在下面。

(1) Trace db4o

ObjectManager是官方查看db4o数据库的客户端,然而,db4o7.4这个版本对应的ObjectManager不再免费,用不了了。要弄清楚在程序中db4o数据库到底做了哪些事情,除了ObjectManager外,还可以打开db4o 的日志,进行跟踪。

在打开数据库之前,进行Trace操作的代码如下:

Code

#if DEBUG
   Db4objects.Db4o.Db4oFactory.Configure().MessageLevel(3);
#endif
   IObjectContainer ObjectContainer = Db4oFactory.OpenFile("test.yap");

这样,在VS的output窗口或者控制台里会有相关的操作日志,如:

[db4o 7.4.60.11658   2008-10-16 07:59:06] 
 17563 update Orc.ContactManager.Contact, 联系人管理器
[db4o 7.4.60.11658   2008-10-16 07:59:06] 
 346372 new System.Guid, mscorlib
[db4o 7.4.60.11658   2008-10-16 07:59:06] 
 346415 new Orc.ContactManager.ChannelType, 联系人管理器
[db4o 7.4.60.11658   2008-10-16 07:59:06] 
 17770 update Orc.ContactManager.Contact, 联系人管理器
[db4o 7.4.60.11658   2008-10-16 07:59:06] 
 346571 new System.Guid, mscorlib

2 尽量少用struct, enum

目前db4o处理普通struct及enum还不尽如意。
对于普通的struct及enum,db4o不能辨别待储存/更新的实例与数据库中原有实例是否同一实例,因此当update时,即使值没有变动,db4o也会将它new一个出来,储存入数据库。如果仅仅只是这样,不过浪费了一些无谓的IO操作,更大的问题是它储存进去一个新值,却不删除原有的值,导致数据库文件中存在大量的垃圾数据。

通过下面小程序就可以验证这一缺陷:

Code
 public class Contact
 {
  public String Id { get; set; }
  public String Name { get; set; }
  public Contact(String id, String name)
  {
   Id = id;
   Name = name;
  }

public static Contact Random()
  {
   return new Contact(Guid.NewGuid().ToString(), Guid.NewGuid().ToString());
  }
 }

public class Program
 {
  static void Main(string[] args)
  {
#if DEBUG
   Db4objects.Db4o.Db4oFactory.Configure().MessageLevel(3);
#endif
   IObjectContainer ObjectContainer = Db4oFactory.OpenFile("test.yap");
   Contact c = Contact.Random();
   for (int i = 0; i < 1000; i++)
   {
    c.Name = i.ToString();
    ObjectContainer.Store(c);
   }
   ObjectContainer.Commit();
   ObjectContainer.Close();
   Console.WriteLine("OK!");
   Console.ReadLine();
  }
 }

程序运行结束后,数据库文件test.yap 大小为2k.

运行日志如下:


[db4o 7.4.60.11658   2008-10-16 09:42:39]
 914 update Db4oTest.Contact, Db4oTest
[db4o 7.4.60.11658   2008-10-16 09:42:39]
 914 update Db4oTest.Contact, Db4oTest
[db4o 7.4.60.11658   2008-10-16 09:42:39]
 914 update Db4oTest.Contact, Db4oTest
[db4o 7.4.60.11658   2008-10-16 09:42:39]
 914 update Db4oTest.Contact, Db4oTest
[db4o 7.4.60.11658   2008-10-16 09:42:39]
 914 update Db4oTest.Contact, Db4oTest

可见,每次运行ObjectContainer.Store(c)均对c进行update。

将Contact的代码改为:

Code
 public enum ContactType
 {
  Type1,
  Type2
 }

public class Contact
 {
  public String Id { get; set; }
  public String Name { get; set; }
  public Guid Guid { get; set; }
  public Int32 Code { get; set; }
  public ContactType Type { get; set; }
  public Contact(String id, String name)
  {
   Id = id;
   Name = name;
   Guid = Guid.NewGuid();
   Code = Guid.GetHashCode();
   Type = ContactType.Type1;
  }

public static Contact Random()
  {
   return new Contact(Guid.NewGuid().ToString(), Guid.NewGuid().ToString());
  }
 }

编译程序,删除test.yap文件,重新运行程序,得到新的test.yap文件大小为144k,可见其中存在大量的垃圾数据。查看日志信息可以发现问题所在:


2352 update Db4oTest.Contact, Db4oTest
[db4o 7.4.60.11658   2008-10-16 09:48:56]
 99639 new System.Guid, mscorlib
[db4o 7.4.60.11658   2008-10-16 09:48:56]
 99682 new Db4oTest.ContactType, Db4oTest
[db4o 7.4.60.11658   2008-10-16 09:48:56]
 2352 update Db4oTest.Contact, Db4oTest
[db4o 7.4.60.11658   2008-10-16 09:48:56]
 99716 new System.Guid, mscorlib
[db4o 7.4.60.11658   2008-10-16 09:48:56]
 99759 new Db4oTest.ContactType, Db4oTest

可见每update一次Contact c,db4o都要new一个Guid,new 一个ContactType,存入数据库,原有的Guid/ContactType,则变成垃圾,依旧呆在数据库中,导致数据库文件急剧增长。

.net下,Int32也是一种struct,然而,从上例日志中却未发现新建Int32 Code,我猜测是db4o对Int32这些常用struct进行了特殊处理。

为了避免垃圾数据,使用db4o时最好慎用struct。

转载于:https://www.cnblogs.com/xiaotie/archive/2008/10/16/1312397.html

Db4o for .NET 使用心得(1、2):Trace db4o;慎用struct相关推荐

  1. 多样化实现Windows Phone 7本地数据访问3——DB4O

    终于把这篇文章发出来了. 对于Windows Phone 7 Visit Local DataBase新采用DB4O和SiaqoDB方式来验证 本地数据访问. 其实这篇已经在上周 完成一个大概草稿. ...

  2. Android 对象型数据库 db4o

    你有木有烦恼过数据库的crud,有木有对sql很烦躁,Android虽然有封装好的ContentProvider,但是操作还是有点复杂了.不是很喜欢. 这两天花时间整了下DB4O,确实很不错,不用建表 ...

  3. Common Trace Format

    2019独角兽企业重金招聘Python工程师标准>>> Common Trace Format (CTF) Specification (v1.8.1)Mathieu Desnoye ...

  4. [转载]面向 Java 开发人员的 db4o 指南: 超越简单对象

    面向 Java 开发人员的 db4o 指南: 超越简单对象 2007 年 7 月 09 日 到目前为止,我们在 db4o 中创建并操作对象看起来都比较简单 -- 事实上,甚至有点太简单了.本文中,热心 ...

  5. 开源面向对象数据库 db4o 之旅: 初识 db4o“db4o 之旅(一)”

    前言 业界对持久存储领域的追求从未停止过,为了更方便.更容易地用对象表达我们的思维,开源领域和商业领域都涌现了许多新技术, ORM 的出现恰恰说明了这点.最近一年,业界也在反思,到底 ORM 给我们带 ...

  6. 开源面向对象数据库 db4o 之旅: db4o 查询方式“db4o 之旅(二)”

    前言 在 开源面向对象数据库 db4o 之旅 系列文章的第一部分:初识 db4o 中,作者介绍了 db4o 的历史和现状,应用领域,以及和 ORM 等的比较.在这篇文章中,作者将会介绍 db4o 的安 ...

  7. Linux内核的namespace机制分析

    1.  Linux内核namespace机制 Linux Namespaces机制提供一种资源隔离方案.PID,IPC,Network等系统资源不再是全局性的,而是属于某个特定的Namespace.每 ...

  8. linux tracepoint例子,tracepoint介绍

    内核中的每个tracepoint提供一个钩子来调用probe函数.一个tracepoint可以打开或关闭.打开时,probe函数关联到tracepoint:关闭时,probe函数不关联到tracepo ...

  9. DL之RNN:人工智能为你写代码——基于TF利用RNN算法实现生成编程语言代码(C++语言)、训练测试过程全记录

    DL之RNN:基于TF利用RNN算法实现生成编程语言代码(C语言).训练&测试过程全记录 目录 输出结果 监控模型 训练&测试过程全记录 训练的数据集展示 输出结果 1.test01 ...

  10. 35个非主流开源数据库

    几乎每个Web开发人员都有自己喜欢的数据库,或自己最熟悉的数据库,但最常见的无外乎以下几种: MySQL PostgreSQL MSSQL SQLite MS Access 或是更简单的XML,文本文 ...

最新文章

  1. 如何有效的使用C#读取文件
  2. 第四天学习Java的笔记(方法入门,编译器优化)
  3. C语言矩阵N*N旋转的算法(附完整源码)
  4. 集合已修改,可能无法执行枚举操作
  5. c#后台alert出来变乱码问题解决
  6. base64链接转为地址php,php将图片链接转换为base64编码文件流
  7. 【Java】如何理解Java中的双列集合Map?
  8. 用计算机程序求n,计算机编程 算法 求n!.doc
  9. 用python爬取微信公众号文章
  10. mysql查询同时选修了两门_查找同时选修了C01及C02两门课程的学生姓名及学号
  11. 清明上河图对计算机技术的启发,风俗画的定义与《清明上河图》的启示
  12. 终于找到一个功能全面的番茄钟时间管理工具:myPomodoro for Mac
  13. tensorflow实战之手写体识别
  14. redis命令之string类型mset命令用法详情
  15. 十进制 二进制 十六进制 八进制
  16. c语言中get的作用,c语言中get的用法
  17. 个人电子邮箱格式大全,邮箱的正确格式是什么?
  18. 吊打何同学?B站UP主24小时肝出AirDesk平替,成本6000!
  19. 全向轮三轮小车的搭建(一)
  20. 【云原生之K8s】 Pod基础概念

热门文章

  1. 很简单的源码剖析-SpringBoot内嵌Tomcat原理
  2. 数据结构课设——航空航天订票系统
  3. 地理加权回归简易总结
  4. Xmind思维导图教程
  5. Docker使用阿里云镜像加速
  6. vue 导出excel表格-乱码问题
  7. “野火FreeRTOS教程”第7章补充知识点-异常流程
  8. 基于python的数字印刷体识别_利用卷积神经网络识别印刷体中文
  9. Unity 脚本生成瓦片地图TileMap
  10. 用Excel和Python编程完成线性规划问题的求解