1、NoSql的概念
NoSQL(NoSQL = Not Only SQL ),意即“不仅仅是SQL”,互联网的早期我们的数据大多以关系型数据库来存储的。其特点是规范的数据结构(预定义模式)、强一至性、表与表之间通过外键进行关联,这些特征使我们对数据的管理更加清晰和严谨,但随着互联网的发展数据成爆炸式的增长我们对数据库需要更好的灵活性和更快的速度。这就是NoSql可以做到的。它不需要预先定义模式,没有主外键关联、支持分片、支持复本。
2.NoSql的分类:
键值(Key-Value)存储数据库
这一类数据库主要会使用到一个哈希表,这个表中有一个特定的键和一个指针指向特定的数据。Key/value模型对于IT系统来说的优势在于简单、易部署。但是如果DBA只对部分值进行查询或更新的时候,Key/value就显得效率低下了。举例如:Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB.
列存储数据库。
这部分数据库通常是用来应对分布式存储的海量数据。键仍然存在,但是它们的特点是指向了多个列。这些列是由列家族来安排的。如:Cassandra, HBase, Riak.
文档型数据库
文档型数据库的灵感是来自于Lotus Notes办公软件的,而且它同第一种键值存储相类似。该类型的数据模型是版本化的文档,半结构化的文档以特定的格式存储,比如JSON。文档型数据库可 以看作是键值数据库的升级版,允许之间嵌套键值。而且文档型数据库比键值数据库的查询效率更高。如:CouchDB, MongoDb. 国内也有文档型数据库SequoiaDB,已经开源。
图形(Graph)数据库
图形结构的数据库同其他行列以及刚性结构的SQL数据库不同,它是使用灵活的图形模型,并且能够扩展到多个服务器上。NoSQL数据库没有标准的查询语言(SQL),因此进行数据库查询需要制定数据模型。许多NoSQL数据库都有REST式的数据接口或者查询API。如:Neo4J, InfoGrid, Infinite Graph.
3、MongoDb的逻辑组成
逻辑结构与关系数据库的对比:
关系型数据库 | MongoDb |
database(数据库) | database(数据库) |
table (表) | collection( 集合) |
row( 行) | document( BSON 文档) |
column (列) | field (字段) |
index(唯一索引、主键索引) | index (全文索引) |
join (主外键关联) | embedded Document (嵌套文档) |
primary key(指定1至N个列做主键) | primary key (指定_id field做为主键) |
aggreation(group) | aggreation (pipeline mapReduce) |
4.mongodb 的安装与基础配置 https://www.mongodb.com/download-center/community
1.wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.5.tgz
2.tar -zxvf mongodb-linux-x86_64-4.0.5.tgz
3. mv mongodb-linux-x86_64-4.0.5.tgz /usr/local/app/
4.mv mongodb-linux-x86_64-4.0.5 mongodb-4.0.5
5.cd /usr/local/app/mongodb-4.0.5
6.创建数据库文件目录,日志目录,配置目录 mkdir data log config
7.创建配置文件 vim conf/mondb.conf
dbpath=/usr/local/app/mongodb-4.0.5/data
port=27017
bind_ip=0.0.0.0
fork=true
logpath = /usr/local/app/mongodb-4.0.5/log/mongodb.log
logappend = true
auth=false
参数配置说明
参数 | 说明 |
dbpath | 数据库目录,默认/data/db |
bind_ip | 监听IP地址,默认全部可以访问 |
port | 监听的端口,默认27017 |
logpath | 日志路径 |
logappend | 是否追加日志 |
auth | 是开启用户密码登陆 |
fork | 是否已后台启动的方式登陆 |
8.启动mongdb ./bin/mongod -f mongo.conf
9.tail -f log/mongdb.log ,出现如下显示证明启动成功
5.客户端shell使用及参数说明
#启动客户端 连接 本机的地的默认端口 ./bin/mongo
# 指定IP和端口 ./bin/mongo --host=127.0.0.1 --port=27017
mongo shell 是一个js 控台,可以进行相应的运算
6.数据库与集合的基础操作
1.查看数据库 show dbs
2.切换数据库 use lq 如果数据库不存在那么自动创建
3.#创建数据库与集合,在插入数据时会自动 创建数据库与集和
db.test.insertOne({name:"zhangsan",sex:"man"});
4.查看集合 show tables; show collections;
5.删除集合 db.test.drop()
6. #删除数据库 db.dropDatabase(); 删除当前所在的库
7.数据的查询
- $and、$or、$in、$gt、$gte、$lt、$lte 运算符
- 基于 sort skip limit 方法实现排序与分页
#基于ID查找 db.emp.find({_id:1101})
// 职工信息
db.emp.insert(
[
{_id:1101,name:'鲁班' ,job:'讲师' ,dep:'讲师部',salary:10000},
{_id:1102,name:'悟空' ,job:'讲师' ,dep:'讲师部',salary:10000},
{_id:1103,name:'诸葛' ,job:'讲师' ,dep:'讲师部',salary:10000},
{_id:1105,name:'赵云' ,job:'讲师' ,dep:'讲师部',salary:8000},
{_id:1106,name:'韩信',job:'校长' ,dep:'校办',salary:20000},
{_id:1107,name:'貂蝉' ,job:'班主任' ,dep:'客服部',salary:8000},
{_id:1108,name:'安其' ,job:'班主任' ,dep:'客服部',salary:8000},
{_id:1109,name:'李白' ,job:'教务' ,dep:'教务处',salary:8000},
{_id:1110,name:'默子' ,job:'教务',dep:'教务处',salary:8000},
{_id:1111,name:'大乔',job:'助教' ,dep:'客服部',salary:5000},
{_id:1112,name:'小乔' ,job:'助教' ,dep:'客服部',salary:3000},
]
);
#基于属性查找
大于运算 db.emp.find({job:"讲师",salary:{$gt:8000}})
in 运算 db.emp.find({"job":{$in:["教务","助教"]}})
or 运算 db.emp.find({$or:[{job:"讲师"},{job:"教务"}]})
排序与分页:db.emp.find().sort({dep:-1,salary:1}).skip(2).limit(6)
嵌套查询
# 错误示例:无结果 db.student.find({grade:{redis:87,dubbo:90 });
# 基于复合属性查找 时必须包含其所有的值 并且顺序一至
db.student.find({grade:{redis:87,zookeper:85,dubbo:90} })
#基于复合属性当中的指定值 查找。注:名称必须用双引号
db.student.find({"grade.redis":{$gt:81}});
数组查询
db.subject.insertMany([
{_id:"001",name:"陈霸天",subjects:["redis","zookeper","dubbo"]},
{_id:"002",name:"张明明",subjects:["redis","Java","mySql"]},
{_id:"003",name:"肖炎炎",subjects:["mySql","zookeper","bootstrap"]},
{_id:"004",name:"李鬼才",subjects:["Java","dubbo","Java"]},
])
#无结果 db.subject.find({subjects:["redis","zookeper"]})
# 与嵌套查询一样,必须是所有的值 并且顺序一至 db.subject.find({subjects:["redis","zookeper","dubbo"]})
# $all 匹配数组中包含该两项的值 db.subject.find({subjects:{$all:["redis","dubbo"]}})
# 简化数组查询 db.subject.find({subjects:"redis"})
# 简化数组查询 ,匹配数组中存在任意一值。与$all相对应 db.subject.find({subjects:{$in:["redis","mySql"]}})
#数组嵌套查询
db.subject2.insertMany([
{_id:"001",name:"陈霸天",subjects:[ {name:"redis",hour:12},{name:"dubbo",hour:120}, {name:"zookeper",hour:56}] },
{_id:"002",name:"张明明",subjects:[{name:"java",hour:120},{name:"mysql",hour:10},{name:"oracle",hour:30}]},
{_id:"003",name:"肖炎炎",subjects:[{name:"mysql",hour:12},{name:"html5",hour:120},{name:"netty",hour:56}]},
{_id:"004",name:"李鬼才",subjects:[{name:"redis",hour:12},{name:"dubbo",hour:120},{name:"netty",hour:56}]}
])
基础查询 ,必须查询全部,且顺序一至 db.subject2.find({subjects:{name:"redis",hour:12}})
嵌套数据查询 必须用引号引起来
$elemMatch 元素匹配,指定属性满足,且不要求顺序一至
db.subject2.find({subjects:{$elemMatch:{name:"dubbo",hour:{$gt:12}}}})
修改
db.emp.update({_id:1101} ,{ $set:{salary:10300} })
#自增
db.emp.update({_id:1101} ,{ $inc:{salary:200}})
# 更新所有 匹配的条件
db.emp.updateMany({"dep":"客服部"},{$inc:{salary:100}})
删除:
// 基于查找删除
db.emp.deleteOne({_id:1101})
// 删除整个集合
db.project.drop()
// 删除库
db.dropDatabase()
mongodb 聚合操作
1.pipeline 聚合
pipeline相关运算符:
- $match :匹配过滤聚合的数据
- $project:返回需要聚合的字段
- $group:统计聚合数据
$match 使用
db.emp.aggregate({$match:{dep:{$eq:"讲师部"}}})
$match 与 $project
db.emp.aggregate({$match:{job:"讲师"}},{$project:{name:1,dep:1,salary:1}})
$group 与 $sum 使用
db.emp.aggregate({$project:{dep:1,job:1,salary:1}},{$group:{_id:"$dep",total:{$sum:"$salary"}}})
薪水大于8000
# 基于多个字段 进行组合group 部门+职位进行统计
db.project.aggregate({$match:{$text:{$search:"apache"}}},{$project:{"name":1,"price":1}},{$group:{_id:"$name",price:{$sum:"$price"}}})
db.emp.aggregate({$project:{dep:1,job:1,salary:1}},{$group:{_id:{"dep":"$dep",job:"$job"},total:{$sum:"$salary"}}})
在聚合中使用索引
除了全文索引之外,还有单键索引。即整个字段的值作为索引。单键索引用值
创建单值索引
db.emp.createIndex({"dep":1})
查看基于索引的执行计划
db.emp.find({"dep":"客服部"}).explain()
可以创建联合索引如下:
db.emp.createIndex({"dep":1,"job":-1})
到此mongodb基本操作已经完成,下一篇讲主从复制