zoukankan      html  css  js  c++  java
  • Db4o for .NET 使用心得(1、2):Trace db4o;慎用struct

    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。

    版权所有,欢迎转载
  • 相关阅读:
    luogu P1955 [NOI2015]程序自动分析
    luogu P5514 [MtOI2019]永夜的报应
    bzoj1816[Cqoi2010]扑克牌
    bzoj1040[ZJOI2008]骑士
    bzoj4582[Usaco2016 Open]Diamond Collector
    bzoj1029[JSOI2007]建筑抢修
    bzoj1079[SCOI2008]着色方案
    bzoj1051[HAOI2006]受欢迎的牛
    bzoj4525[Usaco2016 Jan]Angry Cows
    bzoj4512[Usaco2016 Jan] Build Gates
  • 原文地址:https://www.cnblogs.com/xiaotie/p/1312397.html
Copyright © 2011-2022 走看看