1为什么使用NOSQL
关系型数据库难以克服的问题
- High performance(高并发读写)
- Huge Storage(海量数据的高效率存储与访问)
- High Scalability &&High Availability(高扩展性和高可用性)
关系型数据库的拘束
- 数据库事务一致性需求
- 数据的写实时性和读实时性需求
- 对复杂的SQL查询,特别是多表关联查询的需求
简介:
MongoDB是一个介于关系库和非关系数据库之间的产品,是非关系数据库中功能最丰富,最像关系数据库的,他支持的数据结构非常松散,是类似JSON和BSON格式,因此可以存储比较复杂的数据类型,MongoDB最大的特点是支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引,他是一个面向集合的,模式自由的文档型数据库,
面向集合文档的存储
- 模式自由
- 强大的查询能力,支持索引与查询计划
- 支持自动复制和自动故障转移
- 支持二进制数据集大型对象(文件)的高效存储
2.MongoDB基本概念
关系型sql概念 | MongoDB概念 |
Database(数据库) | DB(库) |
Table(表) | Collection(集合) |
Row(行) | Document(文档) |
Column(列) | Field(字段) |
index(索引) | Index(索引) |
Join(关联) | |
Primarykey(主键) | Primarykey(主键) |
3.MongoDB下载安装教程
1、下载安装包
2、解压
tar -zxvf mongodb-linux.tgz
3、移动文件
mv mongodb-linux/ /usr/local/mongodb
4、在/usr/local/mongodb下创建文件
mkdir -p data/db
mkdir logs
5、在/usr/local/mongodb/bin下新建配置文件mongodb.conf
vi mongodb.conf
#配置文件内容
dbpath = /usr/local/mongodb/data/db
logpath = /usr/local/mongodb/logs/mongodb.log
port = 27017
fork = true
nohttpinterface = true
6、环境变量配置
vi /etc/profile
export MONGODB_HOME=/usr/local/mongodb
export PATH=$PATH:$MONGODB_HOME/bin
#保存后,重启系统配置
source /etc/profile
7、在/usr/local/mongodb/bin下 启动MongoDB
mongod -f mongodb.conf 或 ./mongod -f mongodb.conf
8、连接MongoDB
./mongo
9、初始化创建用户
db.createUser({user:'username',pwd:'password',roles[{role:'dbOwner',db:'dbname'}]})
MongoDB 创建数据库
如果数据库不存在,则创建数据库,否则切换到指定数据库。
use DATABASE_NAME
查看所有数据库,可以使用 show dbs 命令:
show dbs
直接使用这个命令(show dbs)刚创建的数据库 ,并不在数据库的列表中, 要显示它,我们需要向 ,数据库插入一些数据。
db.test.insert({"name":"test"})
4. mongoDB查询
数据类型
数据类型 | 示例 | 说明 |
NULL | {"key":"null"} | null表示空值或者不存在该字段 |
布尔 | {"key":true,"key":false} | 布尔类型表示真或加 |
32位整数 | {"key":123} | 存储32位整数,但在shell界面显示会被自动转成64位浮点数 |
64位整数 | {"key":{"floatApprox":"8"}} | 存储64位整数,flaotApprox意思是使用64位浮点数近似表示一个64位整数 |
字符串 | {“key”:value},{"key":"123"} | utf-8格式 |
对象ID | {"key":ObjectId} | 12字节的唯一ID |
日期 | {"key":new Date()} | |
代码 | {"key":fucntion(){}} | |
二进制数据 | 主要存储文件 | |
未定义 | {"key":undefined} | 值没有定义,null和undefined是不同的 |
数组 | {"key":[1,2,3]} | 集合或者列表 |
内嵌文档 | {"user":{"name":"xiaoming"}} | 子对象 |
Decimal128 | {"price":NumberDecimal("1.0.1")} | 3.4版本新增的数据类型,无精度问题 |
1:准备测试数据(使用一个测试库)
db.users.drop();
var user1 = {
"username" : "用户1",
"address" : {
"aCode" : "411000",
"add" : "长沙"
},
"favorites" : {
"movies" : ["战狼","战狼2","阿凡达"],
"cites" : ["长沙","杭州","上海"]
},
"age" : 18,
"salary":NumberDecimal("108.09"),
"length" :1.79,
"comments" :[
{
"movies" : "战狼",
"content" : "评论1",
"commentTime" : ISODate("2017-02-06T04:26:18.354Z")
},
{
"movies" : "战狼",
"content" : "评论2",
"commentTime" : ISODate("2017-04-06T04:26:18.354Z")
},
{
"movies" : "倩女幽魂",
"content" : "评论3",
"commentTime" : ISODate("2017-02-06T04:26:18.354Z")
},
{
"movies" : "战狼2",
"content" : "评论4",
"commentTime" : ISODate("2017-04-06T04:26:18.354Z")
},
{
"movies" : "阿凡达",
"content" : "评论5",
"commentTime" : ISODate("2017-08-06T04:26:18.354Z")
},
{
"movies" : "肉蒲团",
"content" : "评论6",
"commentTime" : ISODate("2017-07-06T04:26:18.354Z")
},
{
"movies" : "西红柿首富",
"content" : "评论7",
"commentTime" : ISODate("2017-09-06T04:26:18.354Z")
},
{
"movies" : "万万没想到",
"content" : "评论8",
"commentTime" : ISODate("2017-04-06T04:26:18.354Z")
},
{
"movies" : "大黄蜂",
"content" : "评论9",
"commentTime" : ISODate("2017-07-06T04:26:18.354Z")
}
]
};
var user2 = {
"username" : "用户2",
"address" : {
"aCode" : "311000",
"add" : "东京"
},
"favorites" : {
"movies" : ["万万没想到","战狼","大黄蜂"],
"cites" : ["南京","东京","上海"]
},
"age" : 24,
"salary":NumberDecimal("7889.09"),
"length" :1.35,
"comments" :[
{
"movies" : "倩女幽魂",
"content" : "评论2",
"commentTime" : ISODate("2017-08-06T04:26:18.354Z")
},
{
"movies" : "大白鲨",
"content" : "评论6",
"commentTime" : ISODate("2017-01-06T04:26:18.354Z")
}
]
};
var user3 ={
"username" : "用户3",
"address" : {
"aCode" : "411000",
"add" : "长沙"
},
"favorites" : {
"movies" : ["西红柿首富","肉蒲团","倩女幽魂"],
"cites" : ["东莞","深圳","东京"]
},
"age" : 22,
"salary":NumberDecimal("6666.66"),
"length" :1.85
};
var user4 = {
"username" : "用户4",
"country" : "USA",
"address" : {
"aCode" : "411000",
"add" : "长沙"
},
"favorites" : {
"movies" : ["西红柿首富","功夫瑜伽","蝙蝠侠"],
"cites" : ["青岛","东莞","上海"]
},
"age" : 20,
"salary":NumberDecimal("6398.22"),
"length" :1.77
};
var user5 = {
"username" : "用户5",
"country" : "UK",
"address" : {
"aCode" : "411000",
"add" : "东京"
},
"favorites" : {
"movies" : ["蜘蛛侠","无双","蝙蝠侠"],
"cites" : ["青岛","东莞","上海"]
},
"salary":NumberDecimal("1969.88")
};
var user6 = {
"username" : "用户6",
"country" : "UK",
"address" : {
"aCode" : "411000",
"add" : "东京"
},
"favorites" : {
"movies" : ["无双","钢铁侠","蝙蝠侠"],
"cites" : ["青岛","东莞","上海"]
},
"salary":NumberDecimal("1969.88")
};
db.users.insert(user1);
db.users.insert(user2);
db.users.insert(user3);
db.users.insert(user4);
db.users.insert(user5);
db.users.insert(user6);
db.product.drop();
var product1 = {
"name" : "算法导论",
"price" : 128.00,
"category" : "book",
"tags" : [
"Algorithms",
"Introduction"
]
};
var product2 = {
"name" : "空气净化器",
"price" : 899.00,
"category" : "furniture",
"tags" : [
"MI"
]
};
var product3 = {
"name" : "Java编程思想",
"price" : 108.00,
"category" : "book",
"tags" : [
"Java",
"Introduction"
],
"author" : {
"name" : "Bruce Eckel",
"from" : "MindView"
}
};
db.product.insert(product1);
db.product.insert(product2);
db.product.insert(product3);
4.1增删改查curd
增
查
mongoDB查询语法:db.COllECTION.find(query,projection)
query:可选,使用查询操作符指定查询条件
projection:可选,使用投影操作符指定返回键,查询时返回文档中所有键值,只需要省略该参数即可(默认省略)
如果需要以易读的方式读取数据,可以使用pretty()方法,db.product.find().pretty()
运算符类型 | 运算符 | 示例 | 描述 |
范围 | $eq | db.product.find({name:{$eq:"java编程思想"}}).pretty(); | 等于 |
$lt | db.product.find({price:{$lt:50}}).pretty(); | 小于 | |
$gt | db.product.find({price:{$gt:50}}).pretty(); | 大于 | |
$lte | db.product.find({price:{$lte:50}}).pretty(); | 小于等于 | |
$gte | db.product.find({price:{$gte:50}}).pretty(); | 大于等于 | |
$in | db.product.find({price:{$in:[10,100]}}).pretty(); | 判断元素是否在指定的集合范围(判断值是否等于集合中的值) | |
$all | db.product.find({tags:{$all:["Introduction","java"]}}).pretty(); | 判断数组中是否包含几个元素 | |
$nin | db.product.find({tags:{$ini:["Introduction","java"]}}).pretty(); | 判断元素是否不在指定的集合范围 | |
布尔运算 | $ne | db.product.find({price:{$ne:50}}).pretty(); | 不等于 |
$not | db.product.find({name:{$not:"java编程思想"}}).pretty(); | 不匹配结构 | |
$or | db.product.find({$or:[{price:128},{category:"book"}]}).pretty(); | 有一个条件成立则匹配 | |
$nor | db.product.find({$nor:[{price:128},{category:"book"}]}).pretty(); | 所有条件都不匹配 | |
$and | db.product.find({$and:[{price:128},{category:"book"}]}).pretty(); | 所有条件都必须匹配 | |
$exists | db.product.find({author:{$exists:ture}}).pretty(); | 判断元素是否存在 | |
其他 | $regex | db.product.find({name:{$regex:/java/}}).pretty(); | 正则表达式匹配 |
. | 子文档匹配 |
查询选择
字段选择:db.product.find({},{'tags':1}) #展示tags字段,除ObjectId字段外其他也不展示
字段排除:db.product.find({},{'tags':0}) #不展示tags字段,展示其他字段
排序
sort() : db.product.find().sort({name:1}); 按照name字段进行排序(正序);-1为倒序
跳过和限制
skip(n):跳过n条数据
limit(n) :限制n条数据
查询唯一值:
distinct():查询指定字段的唯一值,db.product.distinct('name');
4.2mongoDB实现关联查询
4.2.1聚合
4.2.2管道
4.2.3更新
5. mongoDB高级
引擎
B+tree节点需要冗余,但是B-tree在节点需要存储数据,所以节点数量也多,二者数高应该差不多,
B+tree检索时必须检索到叶子节点,B-tree不需要所以平均检索时B-tree的少