【Mongodb教程 第十六课 】 分享NO-SQL开发实战
时间:2022-03-14 01:14
最近研究了一下NOSQL,现整理目录如下:
一、关系数据库的瓶颈;
二、NOSQL概述;
三、NOSQL中的热门数据库MongoDB介绍及安装配置;
四、MongoDB开发模式及实战;
一、关系数据库的瓶颈
从90年代到至今,关系数据库扮演了最重要的角色,它的性能,可扩展性、稳定性、数据的备份和恢复机制等都非常好,关系数据库发展到现在已经非常成熟,它提供给使用者的是一整套体系,包括数据存储、数据备份恢复、数据加解密、应用开发驱动、图形化配置维护工具、安全策略等等。图1中展示了世界上各种数据库的使用比例,从这个图上我们明显看得出它的霸主地位。
图3:mongDB内部组成 Mongo的官方网站地址是:; 这里给大家推荐一本MongoDB入门的书籍《MongoDB权威指南》,这个有中文版本。 2、特性 面向集合存储,易存储对象类型的数据。 模式自由。 支持动态查询。 支持完全索引,包含内部对象。 支持查询。 支持复制和故障恢复。 使用高效的二进制数据存储,包括大型对象(如视频等)。 自动处理碎片,以支持云计算层次的扩展性 . 支持Python,PHP,Java,C#,Javascript等语言的驱动程序. 文件存储格式为BSON(一种JSON的扩展)。 可通过网络访问。
3、功能
面向集合的存储:适合存储对象及JSON形式的数据。 动态查询:Mongo支持丰富的查询表达式。查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。 完整的索引支持:包括文档内嵌对象及数组。Mongo的查询优化器会分析查询表达式,并生成一个高效的查询计划。 查询监视:Mongo包含一个监视工具用于分析数据库操作的性能。 复制及自动故障转移:Mongo数据库支持服务器之间的数据复制,支持主-从模式及服务器之间的相互复制。复制的主要目标是提供冗余及自动故障转移。 高效的传统存储方式:支持二进制数据及大型对象(如照片或图片) 自动分片以支持云级别的伸缩性:自动分片功能支持水平的数据库集群,可动态添加额外的机器 4、使用场景 网站数据:Mongo非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。 缓存:由于性能很高,Mongo也适合作为信息基础设施的缓存层。在系统重启之后,由Mongo搭建的持久化缓存层可以避免下层的数据源 过载。 大尺寸,低价值的数据:使用传统的关系型数据库存储一些数据时可能会比较昂贵,在此之前,很多时候程序员往往会选择传统的文件进行存储。 高伸缩性的场景:Mongo非常适合由数十或数百台服务器组成的数据库。Mongo的路线图中已经包含对MapReduce引擎的内置支持。 用于对象及JSON数据的存储:Mongo的BSON数据格式非常适合文档化格式的存储及查询。 5、安装过程第一步:下载安装包:←单击此处,如果是win系统,注意是64位还是32位版本的,请选择正确的版本。
第二步:新建目录“D:\MongoDB”,解压下载到的安装包,找到bin目录下面全部.exe文件,拷贝到刚创建的目录下。
第三步:在“D:\MongoDB”目录下新建“data”文件夹,它将会作为数据存放的根文件夹。
配置Mongo服务端:
打开CMD窗口,按照如下方式输入命令:
> d:
> cd D:\MongoDB
> mongod --dbpath D:\MongoDB\data
配置成功后会看到如下图4:
图4:启动成功界面第四步:安装为windows服务
mongod --install --serviceName MongoDB --serviceDisplayName MongoDB --logpath D:\MongoDB\log\MongoDB.log --dbpath D:\MongoDB\data --directoryperdb,执行成功之后在windows服务中可以看到名称为MongoDB的服务,开启就可以了,这样能避免exe CMD命令框的烦恼;
四、MongoDB开发模式及实战
1、开发模式
对于MongoDB的开发模式,我们可以采用类似高速服务框架HSF的模式进行架构,见图5,首先在基础构件层中我们把MongoDB的驱动封装到基类库Inspur.Finix.DAL中,
然后在领域层采用小三层架构模式调用基础构件层的数据服务,展现层在通过AJAX+JSON+Filter方式通过服务的形式调用业务层,展现层就可以很好的利用返回的JSON串实现页面的功能。
图5:开发模式
2、开发实战
C#驱动有很多种比较常用的是官方驱动和samus驱动。samus驱动除了支持一般形式的操作之外,还支持linq方式操纵数据
(1)基础构件层封装我们采用samus驱动进行封装,代码如下:
public class MongoDBAccess : IDisposable { /// <summary> /// 数据库别名 /// </summary> private string _dataBaseAlias = "Noah.MongoDB"; /// <summary> /// 集合名 /// </summary> public string _collectionName { get; set; } // 定义mongo服务 private Mongo _mongo = null; // 获取databaseName对应的数据库,不存在则自动创建 private IMongoDatabase _mongoDatabase = null; public MongoCollection<Document> MongoCollection; /// <summary> /// 构造函数 /// </summary> /// <param name="dataBaseAlias"></param> /// <param name="collectionName"></param> public MongoDBAccess(string dataBaseAlias, string collectionName) { _dataBaseAlias = dataBaseAlias; _collectionName = collectionName; init(); } /// <summary> /// 初始化 /// </summary> private void init() { DatabaseConfigManager dcm = DatabaseConfigManager.Create(); // 根据别名得到连接串 string connStr = dcm.GetPrimaryConnection(_dataBaseAlias); // 把conn进行拆分 StringTokenizer st = new StringTokenizer(connStr, ";"); string conn = st.GetValueByIndex(0); // 定义mongo服务 _mongo = new Mongo(conn); _mongo.Connect(); st = new StringTokenizer(st.GetValueByIndex(1), "="); string databaseName = st.GetValueByIndex(1); // 获取databaseName对应的数据库,不存在则自动创建 if (string.IsNullOrEmpty(databaseName) == false) _mongoDatabase = _mongo.GetDatabase(databaseName); //获取collectionName对应的集合,不存在则自动创建 MongoCollection = _mongoDatabase.GetCollection<Document>(_collectionName) as MongoCollection<Document>; } /// <summary> /// 切换到指定的数据库 /// </summary> /// <param name="dbName"></param> /// <returns></returns> public IMongoDatabase UseDb(string dbName) { if (string.IsNullOrEmpty(dbName)) throw new ArgumentNullException("dbName"); _mongoDatabase = _mongo.GetDatabase(dbName); return _mongoDatabase; } /// <summary> /// 获取当前连接的数据库 /// </summary> public IMongoDatabase CurrentDb { get { if (_mongoDatabase == null) throw new Exception("当前连接没有指定任何数据库。请在构造函数中指定数据库名或者调用UseDb()方法切换数据库。"); return _mongoDatabase; } } /// <summary> /// 获取当前连接数据库的指定集合【依据类型】 /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> public IMongoCollection<T> GetCollection<T>() where T : class { return this.CurrentDb.GetCollection<T>(); } /// <summary> /// 获取当前连接数据库的指定集合【根据指定名称】 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="name">集合名称</param> /// <returns></returns> public IMongoCollection<T> GetCollection<T>(string name) where T : class { return this.CurrentDb.GetCollection<T>(name); } /// <summary> /// 使用GridFS保存附件 /// </summary> /// <param name="byteFile"></param> /// <returns></returns> public string GridFsSave(byte[] byteFile) { string filename = Guid.NewGuid().ToString(); //这里GridFile构造函数有个重载,bucket参数就是用来替换那个创建集合名中默认的"fs"的。 GridFile gridFile = new GridFile(_mongoDatabase); using (GridFileStream gridFileStream = gridFile.Create(filename)) { gridFileStream.Write(byteFile, 0, byteFile.Length); } return filename; } /// <summary> /// 读取GridFs附件 /// </summary> /// <param name="filename"></param> /// <returns></returns> public byte[] GridFsRead(string filename) { GridFile gridFile = new GridFile(_mongoDatabase); byte[] bytes; using (GridFileStream gridFileStream = gridFile.OpenRead(filename)) { bytes = new byte[gridFileStream.Length]; gridFileStream.Read(bytes, 0, bytes.Length); } return bytes; } public void GridFsDelete(string filename) { GridFile gridFile = new GridFile(_mongoDatabase); gridFile.Delete(new Document("filename", filename)); } /// <summary> /// 资源释放 /// </summary> public void Dispose() { if (_mongo != null) { _mongo.Dispose(); _mongo = null; } } }
(2)领域层部分代码
public class KNOWLEDGE_SOCKDAL { public KNOWLEDGE_SOCKDAL() { } /// <summary> /// 保存一个对象 /// </summary> /// <param name="model"></param> public void Add(KNOWLEDGE_SOCK model) { try { using (MongoDBAccess mm = new MongoDBAccess(cConfig.Noah_MongoDB, "")) { mm.GetCollection<KNOWLEDGE_SOCK>().Insert(model); } } catch (Exception ex) { ExceptionManager.Handle(ex); } } /// <summary> /// 保存附件 /// </summary> /// <param name="file"></param> /// <returns></returns> public string SaveAttach(byte[] file) { string fileName = string.Empty; try { using (MongoDBAccess mm = new MongoDBAccess(cConfig.Noah_MongoDB, "")) { fileName = mm.GridFsSave(file); } } catch (Exception ex) { ExceptionManager.Handle(ex); } return fileName; } /// <summary> /// 读取附件 /// </summary> /// <param name="fileName"></param> /// <returns></returns> public byte[] ReadAttach(string fileName) { try { using (MongoDBAccess mm = new MongoDBAccess(cConfig.Noah_MongoDB, "")) { mm.GetCollection<KNOWLEDGE_SOCK>(); return mm.GridFsRead(fileName); } } catch (Exception ex) { ExceptionManager.Handle(ex); } return null; } /// <summary> /// 删除附件 /// </summary> /// <param name="fileName"></param> public void DeleteAttach(string fileName) { try { using (MongoDBAccess mm = new MongoDBAccess(cConfig.Noah_MongoDB, "")) { mm.GetCollection<KNOWLEDGE_SOCK>(); mm.GridFsDelete(fileName); } } catch (Exception ex) { ExceptionManager.Handle(ex); } } /// <summary> /// 更新 /// </summary> /// <param name="model"></param> public void Update(KNOWLEDGE_SOCK model) { try { using (MongoDBAccess mm = new MongoDBAccess(cConfig.Noah_MongoDB, "")) { var query = new Document("Know_Code", model.Know_Code); mm.GetCollection<KNOWLEDGE_SOCK>().Update(model, query); } } catch (Exception ex) { ExceptionManager.Handle(ex); } } /// <summary> /// 删除 /// </summary> /// <param name="id"></param> public void Delete(string id) { try { using (MongoDBAccess mm = new MongoDBAccess(cConfig.Noah_MongoDB, "")) { var query = new Document("Know_Code", id); mm.GetCollection<KNOWLEDGE_SOCK>().Remove(query); } } catch (Exception ex) { ExceptionManager.Handle(ex); } } /// <summary> /// 查询特定一条 /// </summary> /// <param name="id"></param> /// <returns></returns> public KNOWLEDGE_SOCK FindOne(string id) { KNOWLEDGE_SOCK catalog = new KNOWLEDGE_SOCK(); try { using (MongoDBAccess mm = new MongoDBAccess(cConfig.Noah_MongoDB, "")) { var query = new Document("Know_Code", id); catalog = mm.GetCollection<KNOWLEDGE_SOCK>().FindOne(query); } } catch (Exception ex) { ExceptionManager.Handle(ex); } return catalog; } /// <summary> /// 根据条件查询 /// </summary> /// <param name="js"></param> /// <returns></returns> public List<KNOWLEDGE_SOCK> Find(string js) { List<KNOWLEDGE_SOCK> catalogs = new List<KNOWLEDGE_SOCK>(); try { using (MongoDBAccess mm = new MongoDBAccess(cConfig.Noah_MongoDB, "")) { string jsStr = @" function(){ return " + js + ";}"; catalogs = mm.GetCollection<KNOWLEDGE_SOCK>().Find(Op.Where(jsStr)).Documents.ToList(); } } catch (Exception ex) { ExceptionManager.Handle(ex); } return catalogs; } /// <summary> /// 查询全部 /// </summary> /// <returns></returns> public List<KNOWLEDGE_SOCK> FindAll() { List<KNOWLEDGE_SOCK> catalogs = new List<KNOWLEDGE_SOCK>(); try { using (MongoDBAccess mm = new MongoDBAccess(cConfig.Noah_MongoDB, "")) { catalogs = mm.GetCollection<KNOWLEDGE_SOCK>().FindAll().Documents.ToList(); } } catch (Exception ex) { ExceptionManager.Handle(ex); } return catalogs; } /// <summary> /// 返回数量 /// </summary> /// <param name="js"></param> /// <returns></returns> public int GetCount(string js) { int count = 0; try { using (MongoDBAccess mm = new MongoDBAccess(cConfig.Noah_MongoDB, "")) { string jsStr = @" function(){ return " + js + ";}"; count = mm.GetCollection<KNOWLEDGE_SOCK>().Find(Op.Where(jsStr)).Documents.Count(); } } catch (Exception ex) { ExceptionManager.Handle(ex); } return count; } public List<KNOWLEDGE_SOCK> Find(string js, int pageSize, int pageIndex) { List<KNOWLEDGE_SOCK> list = new List<KNOWLEDGE_SOCK>(); try { using (MongoDBAccess mm = new MongoDBAccess(cConfig.Noah_MongoDB, "")) { string jsStr = @" function(){ return " + js + ";}"; list = mm.GetCollection<KNOWLEDGE_SOCK>().Find(Op.Where(jsStr)).Documents.OrderBy(x=>x.Know_CreateTime).Skip(pageSize * (pageIndex-1)).Take(pageSize).ToList(); } } catch (Exception ex) { ExceptionManager.Handle(ex); } return list; } }