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

摘要:
我手中的小项目需要储存约十万个联系人的数据,考察了sqlite与db4o,最终决定选用db4o.我使用的是db4o7.4for.NET2.0。Tracedb4oObjectManager是官方查看db4o数据库的客户端,然而,db4o7.4这个版本对应的ObjectManager不再免费,用不了了。这样,在VS的output窗口或者控制台里会有相关的操作日志,如:[db4o7.4.60.116582008-10-1607:59:06]17563updateOrc.ContactManager.Contact,联系人管理器[db4o7.4.60.116582008-10-1607:59:06]346372newSystem.Guid,mscorlib[db4o7.4.60.116582008-10-1607:59:06]346415newOrc.ContactManager.ChannelType,联系人管理器[db4o7.4.60.116582008-10-1607:59:06]17770updateOrc.ContactManager.Contact,联系人管理器[db4o7.4.60.116582008-10-1607:59:06]346571newSystem.Guid,mscorlib2尽量少用struct,enum目前db4o处理普通struct及enum还不尽如意。");Console.ReadLine();}}程序运行结束后,数据库文件test.yap大小为2k.运行日志如下:[db4o7.4.60.116582008-10-1609:42:39]914updateDb4oTest.Contact,Db4oTest[db4o7.4.60.116582008-10-1609:42:39]914updateDb4oTest.Contact,Db4oTest[db4o7.4.60.116582008-10-1609:42:39]914updateDb4oTest.Contact,Db4oTest[db4o7.4.60.116582008-10-1609:42:39]914updateDb4oTest.Contact,Db4oTest[db4o7.4.60.116582008-10-1609:42:39]914updateDb4oTest.Contact,Db4oTest可见,每次运行ObjectContainer.Store均对c进行update。

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

#ifDEBUG
Db4objects.Db4o.Db4oFactory.Configure().MessageLevel(
3);
#endif
IObjectContainerObjectContainer
=Db4oFactory.OpenFile("test.yap");

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

[db4o7.4.60.116582008-10-1607:59:06]
17563updateOrc.ContactManager.Contact,联系人管理器
[db4o
7.4.60.116582008-10-1607:59:06]
346372newSystem.Guid,mscorlib
[db4o
7.4.60.116582008-10-1607:59:06]
346415newOrc.ContactManager.ChannelType,联系人管理器
[db4o
7.4.60.116582008-10-1607:59:06]
17770updateOrc.ContactManager.Contact,联系人管理器
[db4o
7.4.60.116582008-10-1607:59:06]
346571newSystem.Guid,mscorlib

2 尽量少用struct, enum

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

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

Code
publicclassContact
{
publicStringId{get;set;}
publicStringName{get;set;}
publicContact(Stringid,Stringname)
{
Id
=id;
Name
=name;
}
publicstaticContactRandom()
{
returnnewContact(Guid.NewGuid().ToString(),Guid.NewGuid().ToString());
}
}
publicclassProgram
{
staticvoidMain(string[]args)
{
#ifDEBUG
Db4objects.Db4o.Db4oFactory.Configure().MessageLevel(
3);
#endif
IObjectContainerObjectContainer
=Db4oFactory.OpenFile("test.yap");
Contactc
=Contact.Random();
for(inti=0;i<1000;i++)
{
c.Name
=i.ToString();
ObjectContainer.Store(c);
}
ObjectContainer.Commit();
ObjectContainer.Close();
Console.WriteLine(
"OK!");
Console.ReadLine();
}
}

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

运行日志如下:

Db4o for .NET 使用心得(1、2):Trace db4o;慎用struct第1张
[db4o
7.4.60.116582008-10-1609:42:39]
914updateDb4oTest.Contact,Db4oTest
[db4o
7.4.60.116582008-10-1609:42:39]
914updateDb4oTest.Contact,Db4oTest
[db4o
7.4.60.116582008-10-1609:42:39]
914updateDb4oTest.Contact,Db4oTest
[db4o
7.4.60.116582008-10-1609:42:39]
914updateDb4oTest.Contact,Db4oTest
[db4o
7.4.60.116582008-10-1609:42:39]
914updateDb4oTest.Contact,Db4oTest
Db4o for .NET 使用心得(1、2):Trace db4o;慎用struct第1张

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

将Contact的代码改为:

Code
publicenumContactType
{
Type1,
Type2
}
publicclassContact
{
publicStringId{get;set;}
publicStringName{get;set;}
publicGuidGuid{get;set;}
publicInt32Code{get;set;}
publicContactTypeType{get;set;}
publicContact(Stringid,Stringname)
{
Id
=id;
Name
=name;
Guid
=Guid.NewGuid();
Code
=Guid.GetHashCode();
Type
=ContactType.Type1;
}
publicstaticContactRandom()
{
returnnewContact(Guid.NewGuid().ToString(),Guid.NewGuid().ToString());
}
}

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


2352updateDb4oTest.Contact,Db4oTest
[db4o
7.4.60.116582008-10-1609:48:56]
99639newSystem.Guid,mscorlib
[db4o
7.4.60.116582008-10-1609:48:56]
99682newDb4oTest.ContactType,Db4oTest
[db4o
7.4.60.116582008-10-1609:48:56]
2352updateDb4oTest.Contact,Db4oTest
[db4o
7.4.60.116582008-10-1609:48:56]
99716newSystem.Guid,mscorlib
[db4o
7.4.60.116582008-10-1609:48:56]
99759newDb4oTest.ContactType,Db4oTest

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

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

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

免责声明:文章转载自《Db4o for .NET 使用心得(1、2):Trace db4o;慎用struct》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇机器学习策略(二)---误差分析、训练集与开发测试集不相配怎么办、迁移学习/多任务学习、端到端深度学习Devexpress GridView 数据格式化显示下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

mongodb分片认证

启动configsvr 1. 确保mongdb的configsvr是采用service模式启动的,即从/etc/init.d下的脚本启动的,其用户是mongod。 2. 确保mongod的配置文件完全相同。 3. 确保整个集群的所有keyFile文件内容相同。 启动mongos 1. 使用以下命令启动,以确保用户切换为mongod: runuser -s...

PostgreSQL操作-psql基本命令

一、命令说明psql是PostgreSQL的交互终端,等同于Oracle中的sqlplus。执行该命令连接数据库时, 默认的用户和数据库是postgres二、命令参数-c 命令 :指定psql执行一条SQL命令(用双引号括起),执行后退出。-d 数据库名 :待连接的数据库名称。-f 文件名 :使用文件中的数据作为命令的输入源,在处理完文件后,psql结束并...

如何彻底删除DB2中的Database以及DB2文件配置

如何彻底删除DB2中的Database以及DB2文件配置 Posted by MIB Admin on 二 - 26 - 2008 暂无评论 615 views 首先我不是专门做DB2的,只是工作中遇到了一些问题并且X文个DB2根本无法跟它沟通,所以对删除DB这个新手问题做一些个人解释。 背景操作(类似) 1、在“配置助手”中选择数据库A点击右键,...

(转)SQL SERVER 日志已满的处理方法

本文转载自:http://www.cnblogs.com/eycbest/archive/2012/01/04/2311567.html 事务日志文件Transaction Log File是用来记录数据库更新情况的文件,扩展名为ldf。在 SQL Server 7.0 和 SQL Server 2000 中,如果设置了自动增长功能,事务日志文件将会自动扩...

Oracle客户端连接数据库配置

配置文件和路径 配置文件:tnsnames.ora 默认路径:%ORACLE_HOME% etworkadmin nsnames.ora,%ORACLE_HOME%通常在环境变量中使用。 我的路径为:C:Program Files (x86)OracleInstant Client etworkadmin nsnames.or 配置文件如下: # t...

微服务架构 SpringBoot(二)

第二天内容:想来想去玩个ssm小demo吧1.创建表 2..引入相关mybatis 数据库jar: <!--mybatis --> <dependency>   <groupId>org.mybatis.spring.boot</groupId>   <artifactId>mybatis-s...