第二节 为什么用MongoDB及.NET开发入门

标签: mongodb net 开发 | 发表时间:2011-06-12 15:17 | 作者:小城岁月 Pei
出处:http://www.cnblogs.com/

本节问题:

  • 为什么要用MongoDB
  • MongoDB for .net驱动选择
  • MongoDB for VS插件介绍
  • Demo介绍   

 一、为什么要用MongoDB

  为什么要用MongoDB取代传统关系型数据库?其实不是取代,只是对传统数据库的文档型补充。不是所有的数据都需要二维关系及多表对应的存储和查询,比如:文件的海量存储,只需Key与Value形式的存储及查询,同时这种方式的存储及查询都是高效的,可查看GirdFS,GirdFS是MongoDB的大文件存储系统,比如图片、音频、视频;数据如果不需要实时分析统计(包含读写比高的),也可以使用KV形式存储及查询。MongoDB介于缓存与数据库之间,存取速度逊于缓存但远远高于传统数据库。数据库存储以键值形式,你可能会认为对数据关系的处理及分析挖掘不及传统数据库,理论上是如此,但是MongoDB加入了对LINQ的支持,相信可以弥补其不足之处。做项目要求稳,对于MongoDB的使用我们只是对传统数据库的一个类似二级缓存的补充,cache缓存及Memcached做为一级缓存,MongoDB做为二级缓存对海量大数据的一个缓冲查询,最终才是数据库及物理文件的存储。如果你对数据的分析挖掘统计不是实时的,也可以尝试使用MongoDB直接存取数据,数据后期处理工作可通过MongoDB同步到传统数据库。(以上纯属个人理解)

      用MongoDB做海量存储,又出现另一个问题读写频率与扩展?MongoDB可以根据应用程序的需要以两种模式来运行。第一种是“单主”(single master)模式,只有一台主服务器来处理所有的写操作。读操作能从中分离出去,通过任意数量的从服务器来进行读操作,这有利于提高读的可扩展性(使用场景:Sourceforge)。对于那些写数据量很大或写频率过高,单台主服务器无法处理的应用程序,可以使用MongoDB的自动分片模式。该模式下写操作会自动分配到任意数量的“片”中(一般是一台或一组MongoDB服务器),它们负责这部分数据集的写和读。无论使用哪种模式,MongoDB都会采取“强一致性”方法(你可以把MongoDB看成CAP理论中的C-P系统)。高可用性是通过将数据复制到多个MongoDB节点来实现的,每个节点都能及时成为一个分片的主服务器——MongoDB会自动处理故障转移。这能让你在维持相当高的写可用性的同时,拥有强一致性特性,这对一些用例来说非常重要。而MongoDB的分片支持复制和故障切换:Mongo数据库支持服务器之间的数据复制,支持主-从模式及服务器之间的相互复制。MongoDB的自动分片模块 ("mongos"). 自动分片可以用于构建一个大规模的可扩展的数据库集群,这个集群可以并入动态增加的机器。(说细可参照此官方文档

二、MongoDB for .net驱动选择

驱动源码地址:https://github.com/mongodb/mongo-csharp-driver/downloads(第一章提到的)

项目应用:

第一款:mongodb-csharp 项目地址:http://github.com/samus/mongodb-csharp  应用很广泛,更新速度也比较快,也加入了对LINQ的支持 

第二款:simple-mongodb 项目地址:http://code.google.com/p/simple-mongodb   以JSON为核心

第三款:NoRM 项目地址:http://github.com/atheken/NoRM  加入了对强类型的支持,是对一的补充

其它的也有,就不介绍了,经过综合比较选择了方案一,也就是第一章介绍的。方案一应该广泛用于项目了,并且保持较快的更新速度,同时也加了LINQ的支持,对于项目求稳的朋友是最好的选择,所以我也选择了方案一samus驱动,下载的是(samus-mongodb-csharp-0.90.0.1.zip)下载选Tar.Zip包含源码。另外一个包只有DLL。后面的文章中将一直使用samus开发包。

三、MongoDB for VS插件介绍

插件下载地址:http://www.cnblogs.com/ILoveSilence/archive/2010/08/10/mongowidget_1.html (园子里人做的)

插件和VS的数据源功能类似,想使用的就去看这篇博文吧。

四、Demo介绍

下载samus开发包后,你会发现里面已经有了samples了,那就开始我们的入门之路了

这Demo都不写了,直接拿来分析了

留意的朋友会发现,MongoDB的连接字符串是IP+端口,与传统的数据库引擎不同,包括数据的CURD操作都是键值方式,是不是有点像Memcached。

View Code
using System;
using System.Configuration;
using System.Linq;
using MongoDB;
using MongoDB.Configuration;
using MongoDB.Linq;

namespace Simple
{
/// <summary>
/// Illustrates some simple operations on the database.
/// Creating a database connection.
/// Remove some documents.
/// Insert some documents
/// Find one document
/// Find several documents and iterate through them.
/// </summary>
internal class MainClass
{
private IMongoCollection<Document> categories;
private Mongo mongo;
private IMongoDatabase simple;

private class MyClass
{
public string Name { get; set; }
public int Corners { get; set; }
}

private class SubClass : MyClass
{
public double Ratio { get; set; }
}

public static void Main(string[] args)
{
#region 以下为被屏蔽源码部分,我们先从SetUp方法开始
//var config = new MongoConfigurationBuilder();
//// COMMENT OUT FROM HERE
//config.Mapping(mapping =>
//{
// mapping.DefaultProfile(profile =>
// {
// profile.SubClassesAre(t => t.IsSubclassOf(typeof(MyClass)));
// });
// mapping.Map<MyClass>();
// mapping.Map<SubClass>();
//});
//// TO HERE

//config.ConnectionString("Server=127.0.0.1");

//using (Mongo mongo = new Mongo(config.BuildConfiguration()))
//{
// mongo.Connect();
// try
// {
// var db = mongo.GetDatabase("TestDb");
// var collection = db.GetCollection<MyClass>();

// MyClass square = new MyClass()
// {
// Corners = 4,
// Name = "Square"
// };

// MyClass circle = new MyClass()
// {
// Corners = 0,
// Name = "Circle"
// };

// SubClass sub = new SubClass()
// {
// Name = "SubClass",
// Corners = 6,
// Ratio = 3.43
// };

// collection.Save(square);
// collection.Save(circle);
// collection.Save(sub);

// var superclass = (from item in db.GetCollection<MyClass>("MyClass").Linq()
// where item.Corners > 1
// select item.Corners).ToList();

// var subclass = (from item in db.GetCollection<SubClass>("MyClass").Linq()
// where item.Ratio > 1
// select item.Corners).ToList();

// Console.WriteLine("Count by LINQ on typed collection: {0}", collection.Linq().Count(x => x.Corners > 1));
// Console.WriteLine("Count by LINQ on typed collection2: {0}", db.GetCollection<SubClass>().Linq().Count(x => x.Corners > 1));
// //Console.WriteLine("Count by LINQ on typed collection3: {0}", db.GetCollection<SubClass>().Count(new { Corners = Op.GreaterThan(1) }));
// Console.WriteLine("Count on typed collection: {0}", collection.Count(new { Corners = Op.GreaterThan(1) }));

// var coll = db.GetCollection("MyClass");
// var count = coll.Count(new Document("Corners", Op.GreaterThan(1)));
// Console.WriteLine("Count: {0}", count);
// Console.ReadKey();
// }
// finally
// {
// mongo.Disconnect();
// }
//}
#endregion

var main
= new MainClass();
main.Setup();
main.Run();

Console.ReadLine();
}

/// <summary>
/// Setup the collection and insert some data into it.
/// </summary>
public void Setup()
{
//从配置文件读取连接字符串 IP+端口
var connstr = ConfigurationManager.AppSettings["simple"];
if(String.IsNullOrEmpty(connstr))
throw new ArgumentNullException("Connection string not found.");
//创建Mongo数据服务及连接
mongo = new Mongo(connstr);
mongo.Connect();

//获取数据库实例(如果该实例不存,就会自动创建simple实例)
simple = mongo["simple"];
//获取表名(如果该表名不存在,就会自动创建categories表名)
categories = simple.GetCollection<Document>("categories");
//添加记录前清除所有记录
Clean();

var names
= new[] {"Bluez", "Jazz", "Classical", "Rock", "Oldies", "Heavy Metal"};
//循环插入记录 doucment会自动生成键值_id,id的编码体现了数据的插入顺序
foreach(var name in names)
categories.Insert(
new Document {{"name", name}});
}

public void Clean()
{
//删除document name 为Jazz的记录
categories.Remove(new Document {{"name", "Jazz"}}); //remove documents with the name Jazz.
//删除所有记录集
categories.Remove(new Document()); //remove everything from the categories collection.
}

public void Run()
{
//查找单条记录 参数类型为Document
var category = categories.FindOne(new Document {{"name", "Bluez"}});
Console.WriteLine(
"The id findOne" + category["_id"]);

//更新1 用键值ID读取对象,并更新字段值,保存
var selector = new Document {{"_id", category["_id"]}};
category[
"name"] = "Bluess";
//The following will do the same thing.
categories.Save(category);
Console.WriteLine(
"Category after one update " + categories.FindOne(selector));
//更新2 Update参数1去更新参数2并保存
category["name"] = "Blues";
categories.Update(category, selector);
Console.WriteLine(
"Category after two updates " + categories.FindOne(selector));

//Find it by _id that has been converted to a string now.
var id = (category["_id"]).ToString();
//注意: 这里id.ToString()与id.ToOid() (为什么类扩展这个方法,我也没明白,是不是id!=24 位会出现转义字符要替换掉)
Console.WriteLine(string.Format("Found by string id[{0}] converted back to Oid[{1}]",id.ToString(),id.ToOid()));
Console.WriteLine(categories.FindOne(
new Document {{"_id", id.ToOid()}}));

//Find(new Document()) is equivalent to FindAll();
//Specifying the cursor in a using block will close it on the server if we decide not
//to iterate through the whole thing.
Console.WriteLine("输出所有对象.........");
using(var all = categories.Find(new Document()))
{
foreach(var doc in all.Documents)
Console.WriteLine(doc.ToString());
}

mongo.Disconnect();
}
}
}

//类扩展ToOid方法到string中
public static class OidExtensions
{
public static Oid ToOid(this string str)
{
if(str.Length == 24)
return new Oid(str);

return new Oid(str.Replace("\"", ""));
}
}

以上为MongoDB的数据库连接及CRUD操作(Document方式),我们来测试一下,数据库实例,表,记录是否创建成功了呢?

打开上一章提到的Bin文件夹下的Mongo.exe程序 按图示输入命令查看

入门Demo就演示到这里了,有点简单,我也在是一边学习一边分享。Demo就不提供下载了,都在samus里面,只是我这边加了注释。

作者: 小城岁月 发表于 2011-06-12 15:17 原文链接

评论: 0 查看评论 发表评论


最新新闻:
· Google Earth里植入更多的3D树木(2011-06-12 21:45)
· IBM开源Java语言变种NetRexx(2011-06-12 21:42)
· Richard MacManus:20年后,网站将不复存在?(2011-06-12 21:40)
· 亚马逊拒绝缴纳营业税 再次中断在美两州业务(2011-06-12 21:38)
· 网上叫卖“差评”供买家发泄不满(2011-06-12 20:57)

编辑推荐:自己动手开发编译器(四)利用DFA转换表建立扫描器

网站导航:博客园首页  我的园子  新闻  闪存  小组  博问  知识库

相关 [mongodb net 开发] 推荐:

第二节 为什么用MongoDB及.NET开发入门

- Pei - 博客园-首页原创精华区
MongoDB for .net驱动选择. MongoDB for VS插件介绍.  一、为什么要用MongoDB.   为什么要用MongoDB取代传统关系型数据库. 其实不是取代,只是对传统数据库的文档型补充. 不是所有的数据都需要二维关系及多表对应的存储和查询,比如:文件的海量存储,只需Key与Value形式的存储及查询,同时这种方式的存储及查询都是高效的,可查看GirdFS,GirdFS是MongoDB的大文件存储系统,比如图片、音频、视频;数据如果不需要实时分析统计(包含读写比高的),也可以使用KV形式存储及查询.

分清“语言/规范”以及“平台/实现”,以及跨平台.NET开发

- 王雪松 - 博客园-老赵点滴 - 追求编程之美
在许多年前,“语言”就等同于“平台”,例如C,C++以及最早的Ruby和Python等等. 但是随着技术发展,出现了一些通用的平台,例如.NET和Java,逐渐这些平台上的语言也越来越多. 再后来,某些语言在不同平台上的实现也越来越多,事情也变得有些复杂. 技术在发展,但是从目前社区的讨论中,我发现许多朋友的观念还没有跟上.

开发高性能的MongoDB应用—浅谈MongoDB性能优化 - 吴纹羽

- - 博客园_首页
大数据时代的数据存储,非关系型数据库MongoDB(一).   “如何能让软件拥有更高的性能. ”,我想这是一个大部分开发者都思考过的问题. 性能往往决定了一个软件的质量,如果你开发的是一个互联网产品,那么你的产品性能将更加受到考验,因为你面对的是广大的 互联网用户,他们可不是那么有耐心的. 严重点说,页面的加载速度每增加一秒也许都会使你失去一部分用户,也就是说, 加载速度和用户量是成反比的.

[mongodb] java操作mongodb

- - 数据库 - ITeye博客
           //实例化Mongo对象,连接27017端口.                               //连接名为yourdb的数据库,假如数据库不存在的话,mongodb会自动建立. //从Mongodb中获得名为yourColleection的数据集合,如果该数据集合不存在,Mongodb会为其新建立.

超越MongoDB, PostgreSQL引领开发新未来

- - 博客 - 伯乐在线
最新一轮的针对PostgreSQL和MongoDB的性能比较的多次几近重复的结果证明了PostgreSQL的性能已经超越了MongoDB.  Postgres在JSON和JSONB方面取得的进展使得Postgres可以支持文档型数据库. 能在一个关系型数据库中创建文档型数据库的能力是一项令人印象深刻的成就,尤其是它比当今主流的NOSQL解决方案还要好用.

【MongoDB】MongoDB之优化器Profiler

- - CSDN博客数据库推荐文章
在mysql数据库中,慢查询日志经常作为优化数据库的依据, mongodb中依然有类似的功能. Mongodb自带的profiler,可以方便地记录所有耗时的操作,以便于调优;. 一、开始profiler功能. 开启profier功能有两种:. 第一种就是直接在启动参数里面进行设置,就在茄冬mongodb时候添加-profile=级别.

工作多年的.NET程序员,是否建立了自己的开发知识库?分享制作电子书的经验

- L - 博客园-首页原创精华区
经过多年的编程经验的积累,工作中肯定会遇到很多问题,也都通过各种办法解决了. 无论是上网搜索,或是向同事寻求帮忙,在遇到问题时,都会把这个系列的问题的网页都保存起来,以便以后查找起来方便. 这样,随着时间的积累,知识库的内容会越来越多,如何整理这些文件,方便查找,一直是工作之外努力的方向. 曾经用EverNote建立各种知识库,如下图所示,定期抽出时间,在网上搜索,看到好的文章,都剪贴下来.

夜说mongodb

- Lianhui Wang - NoSQLFan
前两天本站刚刚分享了wordnik使用MongoDB经验的文章:《Wordnik 的 MongoDB 使用经历》,今天又看到一位朋友对这方面做的总结,分享在这里,供大家参考. 赋闲以后很长没有更新博客了,说忙完全是借口,多半因为没有兴致所致. 今天凌晨比赛多多,趁着比赛的前奏和间隙,遂浏览些技术文章.

MongoDB与内存

- 高春辉 - 火丁笔记
但凡初次接触MongoDB的人,无不惊讶于它对内存的贪得无厌,至于个中缘由,我先讲讲Linux是如何管理内存的,再说说MongoDB是如何使用内存的,答案自然就清楚了. 据说带着问题学习更有效,那就先看一个MongoDB服务器的top命令结果:. 这台MongoDB服务器有没有性能问题. 先讲讲Linux是如何管理内存的.