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

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介:

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

 

这样,在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

 

程序运行结束后,数据库文件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

 

编译程序,删除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。

本文转自xiaotie博客园博客,原文链接http://www.cnblogs.com/xiaotie/archive/2008/10/16/1312397.html如需转载请自行联系原作者


xiaotie 集异璧实验室(GEBLAB)

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
4月前
|
存储 C#
揭秘C#.Net编程秘宝:结构体类型Struct,让你的数据结构秒变高效战斗机,编程界的新星就是你!
【8月更文挑战第4天】在C#编程中,结构体(`struct`)是一种整合多种数据类型的复合数据类型。与类不同,结构体是值类型,意味着数据被直接复制而非引用。这使其适合表示小型、固定的数据结构如点坐标。结构体默认私有成员且不可变,除非明确指定。通过`struct`关键字定义,可以包含字段、构造函数及方法。例如,定义一个表示二维点的结构体,并实现计算距离原点的方法。使用时如同普通类型,可通过实例化并调用其成员。设计时推荐保持结构体不可变以避免副作用,并注意装箱拆箱可能导致的性能影响。掌握结构体有助于构建高效的应用程序。
121 7
|
4月前
|
开发框架 监控 .NET
【Azure 应用程序见解】在Docker中运行的ASP.NET Core应用如何开启Application Insights的Profiler Trace呢?
【Azure 应用程序见解】在Docker中运行的ASP.NET Core应用如何开启Application Insights的Profiler Trace呢?
|
7月前
|
存储 C#
C#.Net筑基-类型系统②常见类型--结构体类型Struct
本文介绍了C#中的结构体(struct)是一种用户自定义的值类型,适用于定义简单数据结构。结构体可以有构造函数,能定义字段、属性和方法,但不能有终结器或继承其他类。它们在栈上分配,参数传递为值传递,但在类成员或包含引用类型字段时例外。文章还提到了`readonly struct`和`ref struct`,前者要求所有字段为只读,后者强制结构体存储在栈上,适用于高性能场景,如Span和ReadOnlySpan。
.NET6新东西--struct优化
.NET6新东西--struct优化
185 0
|
监控 程序员
一起谈.NET技术,System.Diagnostics命名空间里的Debug类和Trace类的用途【转】
  在 .NET 类库中有一个 System.Diagnostics命名空间,该命名空间提供了一些与系统进程、事件日志、和性能计数器进行交互的类库。当中包括了两个对开发人员而言十分有用的类Debug类和Trace类。
972 0
|
监控 程序员
System.Diagnostics命名空间里的“.NET研究”Debug类和Trace类的用途【转】
  在 .NET 类库中有一个 System.Diagnostics命名空间,该命名空间提供了一些与系统进程、事件日志、和性能计数器进行交互的类库。当中包括了两个对开发人员而言十分有用的类Debug类和Trace类。
1162 0