MongoDB是一个NoSQL(Not only SQL)数据库,使用C++语言编写,当前最新版本为3.0(beta)。
安装
在MongoDB官网上有各个OS的安装指导,但在docker横行的时代,使用docker来安装无疑是最方便的,这里是MongoDB的docker镜像地址,使用非常简单,执行以下命令,docker就会自动下载镜像并启动MongoDB容器了。
1
| docker run --name somename -d -p 27017:27017 mongo:tag
|
客户端
对比了几个MongoDB的GUI客户端,发现一个比较好用的客户端Robomongo,而且是跨平台的,安装完成后点击添加连接,输入ip和端口号就可以连接到你的MongoDB服务器了。
PS:因为我是OS系统,用boot2docker来启动docker的,所以我的ip不是localhost
,而是192.168.59.103
。
sql查询
MongoDB是用表达式语言进行数据库操作的,这里有一篇blog介绍了MongoDB的一些简单操作,并有SQL语句与之对应,下面简单介绍几个命令。
关系型数据库 vs NoSQL
在介绍命令之前,需要先理解与关系型数据库两者概念上的区别。
- 表:table vs collection
- 行:view/row(s) vs json document
- 索引:index vs index
简单命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| db.createCollection(“collName”, {size: 20, capped: 5, max: 100});
db.userInfo.find(); 相当于: select * from userInfo;
db.userInfo.find({"age": 22}); 相当于: select * from userInfo where age = 22;
db.userInfo.find({name: /mongo/}); 相当于: select * from userInfo where name like ‘%mongo%’;
db.userInfo.find({name: 'zhangsan', age: 22}); 相当于: select * from userInfo where name = ‘zhangsan’ and age = ‘22’;
db.users.update({age: 25}, {$set: {name: 'changeName'}}, false, true); 相当于: update users set name = ‘changeName’ where age = 25;
db.users.remove({age: 132}); 相当于: delete from users where age = 132;
|
Java示例
使用Java来操作MongoDB也比较简单,首先要下载Java驱动,在Maven库上可以查询到,下面是驱动的Gradle定义。
1
| org.mongodb:mongo-java-driver:3.0.0-beta2
|
驱动最新的版本是3.0,语法上跟2.x有一些差别,具体示例可以参考MongoDB官网的Java示例。
简单示例
MyMongoDB.java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| import com.mongodb.BasicDBObject; import com.mongodb.MongoClient; import com.mongodb.client.FindIterable; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import org.bson.Document;
public class MyMongoDb {
public static void main(String[] args) { MongoClient mongo = new MongoClient("192.168.59.103", 27017);
MongoDatabase mydb = mongo.getDatabase("mydb"); MongoCollection<Document> collection = mydb.getCollection("collectName");
FindIterable<Document> documents = collection.find(); for (Document document : documents) { System.out.println(document.toString()); }
Document t = new Document("name", "time") .append("age", 100) .append("sex", true) .append("address", new BasicDBObject("name", "china").append("province", "Sichuan")); collection.insertOne(t);
collection.updateOne(new Document("name", "time"), new Document("$set", new Document("age", 101))); }
|
数据库设计原则
MongoDB的数据模式有2种结构:引用(References)和内嵌(Embedded)。
- 引用和关系型数据库的表设计比较像,不同的对象放在不同的集合(表)中。
- 内嵌比较特殊,是把对象的关联对象放到一个集合(表)中,这个恰恰是关系系数据库做不到的。
那问题来了,什么时候使用引用,什么时候使用内嵌呢?下面是官方给的一些建议,总结如下:
- 顶级对象,一般使用独立的collection,区别于内嵌
- 线性明细对象如订单里的订单项,一般使用内嵌
- 包含关系的对象通常使用内嵌
- 多对多的关系通常采用引用,dbref
- 只有少量数据的可以单独作为一个collection,这样可以快速缓存到应用服务器内存
- 内嵌对象比顶级对象难引用,至少现在还不能对它使用dbref
- 内嵌对象的获取有时候会比较难,例如各科分数内嵌到学生对象,从所有学生中获取前100个高分,不内嵌会更简单
- 如果内嵌对象数量很多,可以限制其大小
- 性能存在问题(应是查询的性能),使用内嵌
总而言之,数据库的设计需要考虑需求的使用场景,能一次查询到结果的尽量不要分多次进行查询,更多内容可以参考MongoDB官网Data Modeling的章节。