Db4o for .NET 使用心得(1、2):Trace db4o;慎用struct
Db4o(http://www.db4o.com/)是著名的開源對象數(shù)據(jù)庫,使用它能夠?qū)⒊掷m(xù)層代碼量降低到忽略不計的程度。如果數(shù)據(jù)量不大,用它能夠?qū)㈤_發(fā)速度提高一個層次。
我手中的小項目需要儲存約十萬個聯(lián)系人的數(shù)據(jù),考察了sqlite與db4o,最終決定選用db4o. 我使用的是db4o 7.4 for .NET 2.0。關(guān)于db4o網(wǎng)上有很多文檔,然而有一些問題,在網(wǎng)上不容易找到解決辦法,總結(jié)一下,寫在下面。
(1) Trace db4o
ObjectManager是官方查看db4o數(shù)據(jù)庫的客戶端,然而,db4o7.4這個版本對應的ObjectManager不再免費,用不了了。要弄清楚在程序中db4o數(shù)據(jù)庫到底做了哪些事情,除了ObjectManager外,還可以打開db4o 的日志,進行跟蹤。
在打開數(shù)據(jù)庫之前,進行Trace操作的代碼如下:
Code…
#if?DEBUG
???Db4objects.Db4o.Db4oFactory.Configure().MessageLevel(3);
#endif
???IObjectContainer?ObjectContainer?=?Db4oFactory.OpenFile("test.yap");
…
?
這樣,在VS的output窗口或者控制臺里會有相關(guān)的操作日志,如:
[db4o?7.4.60.11658???2008-10-16?07:59:06]??17563?update?Orc.ContactManager.Contact,?聯(lián)系人管理器
[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,?聯(lián)系人管理器
[db4o?7.4.60.11658???2008-10-16?07:59:06]?
?17770?update?Orc.ContactManager.Contact,?聯(lián)系人管理器
[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不能辨別待儲存/更新的實例與數(shù)據(jù)庫中原有實例是否同一實例,因此當update時,即使值沒有變動,db4o也會將它new一個出來,儲存入數(shù)據(jù)庫。如果僅僅只是這樣,不過浪費了一些無謂的IO操作,更大的問題是它儲存進去一個新值,卻不刪除原有的值,導致數(shù)據(jù)庫文件中存在大量的垃圾數(shù)據(jù)。
通過下面小程序就可以驗證這一缺陷:
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();
??}
?}
?
程序運行結(jié)束后,數(shù)據(jù)庫文件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,可見其中存在大量的垃圾數(shù)據(jù)。查看日志信息可以發(fā)現(xiàn)問題所在:
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,存入數(shù)據(jù)庫,原有的Guid/ContactType,則變成垃圾,依舊呆在數(shù)據(jù)庫中,導致數(shù)據(jù)庫文件急劇增長。
.net下,Int32也是一種struct,然而,從上例日志中卻未發(fā)現(xiàn)新建Int32 Code,我猜測是db4o對Int32這些常用struct進行了特殊處理。
為了避免垃圾數(shù)據(jù),使用db4o時最好慎用struct。
轉(zhuǎn)載于:https://www.cnblogs.com/xiaotie/archive/2008/10/16/1312397.html
總結(jié)
以上是生活随笔為你收集整理的Db4o for .NET 使用心得(1、2):Trace db4o;慎用struct的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 品优购电商系统开发
- 下一篇: oracle查看日期是第几周,oracl