基于Mongodb进行分布式数据存储

简介

MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB是一个高性能,开源,无模式的文档型数据库,是当前NoSql数据库中比较热门的一种。
MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bjson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
传统的关系数据库一般由数据库(database)、表(table)、记录(record)三个层次概念组成,MongoDB是由数据库(database)、集合(collection)、文档对象(document)三个层次组成。MongoDB对于关系型数据库里的表,但是集合中没有列、行和关系概念,这体现了模式自由的特点。

特点

它的特点是高性能、易部署、易使用,存储数据非常方便。主要功能特性有:

  1. 面向集合存储,易存储对象类型的数据。
  2. 模式自由。
  3. 支持动态查询。
  4. 支持完全索引,包含内部对象。
  5. 支持查询。
  6. 支持复制和故障恢复。
  7. 使用高效的二进制数据存储,包括大型对象(如视频等)。
  8. 自动处理碎片,以支持云计算层次的扩展性。
  9. 支持RUBY,PYTHON,JAVA,C++,PHP,C#等多种语言。
  10. 文件存储格式为BSON(一种JSON的扩展)
  11. 可通过网络访问。

在C#中使用官方驱动操作MongoDB

先用官方提供的CSharpDriver-1.7.0.4714.zip
MongoDB.Driver.dll:顾名思义,驱动程序
MongoDB.Bson.dll:序列化、Json相关
然后在我们的程序中引用这两个dll。

下载安装和开启服务器

下载地址:http://www.mongodb.org/downloads。提供了各种平台的版本。我这里选择的是Windows平台下的。
新建目录E:\ mongodb , 将下载的压缩包解压到此目录。bin文件夹下有一堆.exe 文件

其中有两个最重要的文件:Mongod.exe和Mongo.exe 。
Mongod.exe 是用来连接到mongo数据库服务器的,即服务器端。
**Mongo.exe **是用来启动MongoDB shell的,即客户端。

其他文件:
mongodump 逻辑备份工具。
mongorestore 逻辑恢复工具。
mongoexport 数据导出工具。
mongoimport 数据导入工具。

开启服务器
第一步:新建一个目录用来存放MongoDB的数据库文件,即dbpath。随便建在那都可以,我这里建在 E:\MongoDBFiles。 这是为了下一步使用的。
第二步:打开CMD窗口,键入如下命令

e:
cd E:\mongodb\mongodb-win32-x86_64-3.0.6\bin
mongod.exe -dbpath "E:\mongodbfiles"

最后一行命令中的-dbpath 参数值就是我们第一步新建的文件夹。这个文件夹一定要在开启服务之前事先建立好,否则会报错,mongodb不会自己创建。
如果操作成功会出现如下界面:


该界面该我们展示了一些信息:如进程ID是7620,端口号是27017。
打开浏览器输入:http://127.0.0.1:27017/
我们看到了这样的提示:
“You are trying to access MongoDB on the native driver port. For http diagnostic access, add 1000 to the port number”
到此,MongoDB数据库服务已经成功启动了。

使用mongo.exe 执行数据库增删改查操作

mongodb 为我们提供的客户端管理工具是mongo.exe

  • 创建数据库
    双击打开mongo.exe 出现如下界面:

    该界面的意思是,当前连接的数据库是test,这是系统默认将要创建的。为什么说是“将要创建的”呢?因为此时并不存在此数据库,或者说它现在还只在内存中,并没有创建在物理磁盘上。不信,你看MongoDBFiles文件夹下面除了mongod.lock外,什么都没有。只有当你执行了插入数据的命令后,该数据库才会真正的创建。
    好了,我们暂时不管这个test了。现在我们来创建一个叫RdfDb的数据库。
    在shell 命令窗口键入如下命令:
use RdfDb // use 命令用来切换当前数据库,如果该数据库不存在,则会先新建一个。
  • 创建collection并插入数据
    在传统关系型数据库中,创建完了库后接下来会创建表,但是在mongoDB中没有“表”的概念,与其对应的一个概念是集合,即collection。
    在shell 命令窗口键入如下命令:
> db.users.insert({'name':'Bobby','sex':'man'})
// 这条命令是向users 集合中插入一条数据。
如果集合users不存在,则会先新建一个,然后再插入数据,参数以JSON格式传入。

因为我们后面要测试删除数据,所以我们再插入一条数据:

> db.users.insert({'name':'Samba','sex':'man'})

在上面我们创建了数据库,创建了集合,还插入了两条数据,那么这些操作有没有执行成功呢?我们来查询一下:
在shell 命令窗口键入如下命令:

> show dbs // 显示所有数据库
> show collections // 显示当前数据库下的所有集合
> db.users.find() // 显示users集合下的所有数据文档

shell 界面如下:



看我用红色标记的部分。这说明我们之前的操作是成功的。我们还看到系统**给每条记录分配了一个惟一主键 _id **。

  • 更新数据
    现在我们要把第二条数据的sex改成女即“women”
    在shell 命令窗口键入如下命令:
> db.users.update({'name':'Samba'},{'$set':{'sex':'women'}},upsert=true,multi=false)

解释一下几个参数:
第一:查询的条件
第二:更新的字段
第三:如果不存在则插入
第四:是否允许修改多条记录

  • 删除记录
    我们现在要把第一条记录即'name'为'Bobby'的删除
    在shell 命令窗口键入如下命令:
> db.users.remove({'name':'Bobby'})

我们在检验一下两步有没有操作成功,在shell 命令窗口键入如下命令:

> db.users.find() 

从输出的界面我们看到现在只剩下一条'name'为'Samba'的了,并且它的'sex'为'women',这说明两步操作成功了。

  • 删除collection
> db.users.drop() //如果删除成功会返回“true”,否则返回“false”
  • 删除当前数据库
 > db.dropDatabase()

Tdf.MongoDB

https://www.nuget.org/packages/Tdf.MongoDB/
基于MongoDB官方发布的C#驱动,封装对MongoDB数据库的增删改查访问方法;

Features

The full list of extension methods in Tdf.MongoDB right now are:

将集合名称写到C#代码中作为字符串常量 CollectionNames.cs

public class CollectionNames
{
    public const string User = "User";
    public const string Role = "Role";
}

编写实体类 User.cs

public class User : EntityBase
{
    public string UserName { get; set; }
    public int Age { get; set; }
    public State State { get; set; }
}

其中,State枚举类定义如下: State.cs

public enum State
{
    /// <summary>
    /// 正常
    /// </summary>
    Normal = 1,
    /// <summary>
    /// 未使用
    /// </summary>
    Unused = 2,
}

在配置文件中编写数据库连接串和数据库名称 App.config

<appSettings>
<!--MongoDB数据库连接串-->
<add key="MongoDBConn" value="mongodb://127.0.0.1:27017"/>
<!--MongoDB数据库名称-->
<add key="MongoDBName" value="RdfDb"/>
</appSettings>

Get methods

static void QueryTest()
{
    var queryBuilder = new QueryBuilder<User>();
    var query = queryBuilder.GTE(x => x.Age, 27);
    var ltModel = MongoDbHelper.GetManyByCondition<User>(DbConfigParams.ConntionString, DbConfigParams.DbName,
        CollectionNames.User, query);
    if (ltModel != null && ltModel.Count > 0)
    {
        foreach (var item in ltModel)
        {
            Console.WriteLine("姓名:{0},年龄:{1},状态:{2}",
                item.UserName, item.Age, GetStateDesc(item.State));
        }
    }
}
/// <summary>
/// 获取状态描述
/// </summary>
/// <param name="state">状态</param>
/// <returns>状态描述</returns>
static string GetStateDesc(State state)
{
    string result = string.Empty;
    switch (state)
    {              
        case State.Normal:
            result = "正常";
            break;
        case State.Unused:
            result = "未使用";
            break;
        default:
            throw new ArgumentOutOfRangeException("state");
    }
    return result;
}

Insert methods

static void InsertTest()
{
    var random = new Random();
    for (var i = 1; i <= 10; i++)
    {
        var item = new User()
        {
            UserName = "我的名字" + i,
            Age = random.Next(25, 30),
            State = i % 2 == 0 ? State.Normal : State.Unused
        };
        MongoDbHelper.Insert(DbConfigParams.ConntionString, DbConfigParams.DbName, CollectionNames.User, item);
    }
}

Update methods

static void UpdateTest()
{
    var queryBuilder = new QueryBuilder<User>();
    var query = queryBuilder.GTE(x => x.Age, 27);
    var dictUpdate = new Dictionary<string, BsonValue>();
    dictUpdate["State"] = State.Unused;
    MongoDbHelper.Update(DbConfigParams.ConntionString, DbConfigParams.DbName, CollectionNames.User, query,
        dictUpdate);
}

Delete methods

static void DeleteTest()
{
    var queryBuilder = new QueryBuilder<User>();
    var query = queryBuilder.GTE(x => x.Age, 28);
    MongoDbHelper.DeleteByCondition(DbConfigParams.ConntionString, DbConfigParams.DbName, CollectionNames.User, query);
}

给Mongodb设置密码

mongod --dbpath 存放数据库文件夹路径
打开命令行窗口输入mongo,进入mongo环境
切换到 'admin' 数据库 use admin



给admin设置用户密码:
user: 用户名, pwd: 用户密码,roles: 用来设置用户的权限,比如读,读写 等等
db.createUser({user: 'root', pwd: '123456', roles: ['root']})
验证是否添加成功,'db.auth(用户名,用户密码)' 这里用db.auth('root', '123456') 如果返回 '1'表示验证成功, 如果是 '0' 表示验证失败...



切换到RdfLogDb数据库,use RdfLogDb
接下来为这个库添加一个用户,并且赋予权限,
db.createUser({user:'rdf',pwd:'rdfcore',roles: [{role:'readWrite',db:'RdfLogDb'}]})})

OK,一切搞定,重新开机mongodb,MongoDB默认是没有开启访问控制,我们通过--auth参数重启mongod服务。mongod --dbpath 存放数据库文件夹路径 --auth一旦开启了,用户连接mongod必须指定用户名和密码。

mongod --dbpath C:\mongodb --auth
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容