NoSQL
什么是NoSQL?
NoSQL指的是非关系型数据库。是对不同于传统的关系数据库的数据管理系统的统称。
RDBMS(关系型) vs NoSQL(非关系型)
RDBMS
-
高度组织化结构化数据
-
结构化查询语言
-
数据和关系都存储在单独的表中
-
数据操纵语言
-
严格的一致性
-
基础事务
NoSQL -
代表着不仅仅是SQL
-
没有声明查询语言
-
没有预订定义的模式
-
键-值对存储,列存储,文档存储,图形数据库
-
最终一致性,而非ACID属性
-
CAP定理
-
高性能,高可用性和可伸缩性
NoSQL的优缺点
优点: -
高可扩展性;
-
分布式计算;
-
低成本;
-
架构的灵活性,半结构化数据;
-
没有复杂的关系;
缺点: -
没有标准化;
-
有限的查询功能;
-
最终一致是不直观的程序
NoSQL数据库分类
|类型|部分代表|特点|
|-|-|
|列存储|Hbase、Cassandra、Hypertable|最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,对针对某一列或者某几列的查询有非常大的IO优势|
|文档存储|MongoDB、CouchDB|文档存储一般用类似json的格式存储,存储的内容是文档性的。这样也就有机会对某些字段建立索引,实现关系型数据库的某些功能|
|key-value存储| Tokyo Cabinet / Tyrant、Berkeley DB、MemcacheDB、Redis|可以通过key快速查询到其value,不管value的储存格式|
|图存储|Neo4J、FlockDB|图形关系的最佳存储,使用传统关系数据库来解决的话,性能低下,而且设计不方便|
|对象存储|db4o、Versant|通过类似面向对象语言操作数据库,通过对象的方式存取数据|
|xml数据库|Berkeley DB、XML、BaseX|高效的存储XML数据,并支持XML的内部查询语法|
MongoDB
MongoDB是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。MongoDB旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB将数据存储为一个文档,数据结构由键值对组成。MongoDb文档类似于JSON对象。
安装MongoDB
下载MongoDB
官网链接:https://www.mongodb.com/
解压
tar -zxvf mongodb-linux-x86_64-rhel70-4.0.1.tgz
创建目录并将解压好的目录移动到创建的目录
mv mongodb-linux-x86_64-rhel70-4.0.1 /usr/local/mongodb/
添加可执行文件到PATH路径
export PATH=/usr/local/mongodb/mongodb-linux-x86_64-rhel70-4.0.1/bin:$PATH
创建数据库目录
MongoDB的数据存储在data目录下的db目录中,/data/db是默认的启动数据库路径,需要手动创建。
MongoDB概念解析
|SQL术语|MongoDB术语|描述|
|-|-|
|database|database|数据库|
|table|collection|数据表/集合|
|row|document|数据记录行/文档|
|column|field|数据字段|域|
|index|index|索引|
|table joins||表连接,MongoDB不支持|
|primary key|primary key|主键,MongoDB自动将_id设为主键|
数据库
MongoDB默认的库是db,存储在data目录中。
显示所有数据的列表
> show dbs
admin 0.000GB
cache 0.000GB
config 0.000GB
local 0.000GB
myDB 0.000GB
显示当前数据对象或集合
> db
test
指定使用哪个库
> use local
switched to db local
> db
local
数据库名
-
不能是空字符串
-
不得含有’’(空格),.,$,/,\,和\0
-
全部小写
-
最多64字节
一些特殊的数据库名: -
admin:这是root数据库,用于管理数据库的用户,要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或关闭服务器。
-
local:永远不会被复制,可以用来存储限于本地单台服务器的任意集合。
-
config:当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息
MongoDb连接
mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
- mongodb://固定格式
- username:password@可选,如果设置,在连接之后驱动都会尝试登录这个数据库。
- host1必须的指定至少一个host,host1是这个URL唯一要填写的,指定了要链接服务器的地址。如果要连接复制集,清指定多个主机地址。
- portX可选的指定端口,如果不填,默认为27017
- /database连接并验证登录指定数据库。若不指定,默认打开test数据库。
实例
先指定存储路径
[kiosk@foundation155 bin]$ ./mongod -dbpath=/usr/local/mongodb/data/db
在另一个终端执行启动命令
mongo
操作数据库
创建数据库
use 数据库名
如果该数据库不存在则创建,否则切换到这个数据库。
新创建并不会显示,除非向这个数据库中插入一些数据。
删除数据库
db.dropDatabase()
删除当前数据库,使用db命令来查看当前数据库名。
操作集合
创建集合
db.createCollection(name,options)
name:要创建的集合名称
options:可选参数
option参数:
|字段|类型|描述|
|-|-|
|capped|布尔|如果为true,则创建固定集合,固定集合是指有着固定的大小的集合,当达到最大值的时候,会自动覆盖最早的文档|
|autoIndexid|布尔|若为true|自动在_id字段创建索引。默认为false|
|size|数值|如果crapped为true,就要指定该字段|
|max|数值|指定固定集合中包含文档的最大数量|
实例
> use test
switched to db test
#创建名为runoob的集合
> db.createCollection("runoob")
{ "ok" : 1 }
#查看已有集合
> show collections
runoob
#创建固定集合mycol,整个集合大小6142800kb,文档最大个数10000个
> db.createCollection("mycol",{capped:true,autoIndexId:true,size:6142800,max:10000})
{
"note" : "the autoIndexId option is deprecated and will be removed in a future release",
"ok" : 1
}
在MongoDB中,你不需要创建集合,当你写入一些文档时,MongoDB会自动创建集合
> db.thecol.insert({"name":"Mymongo"})
WriteResult({ "nInserted" : 1 })
> show collections
mycol
runoob
thecol
删除集合
db.collection.drop()
实例
> show collections
mycol
runoob
thecol
> db.mycol.drop()
true
> show collections
runoob
thecol
操作文档
文档的数据结构和JSON格式一样,所有存储在集合中的数据都是BSON格式。BSON是json的一种二进制形式的储存格式。
插入文档
db.COLLECTION_NAME.insert(document)
实例
col是集合名,没有就创建,有就使用。
> db.col.insert({title:'MongoDB',description:'MongoDB is a Nosql'})
WriteResult({ "nInserted" : 1 })
> db.col.find()
{ "_id" : ObjectId("5b7abb6e4d4e76d95b766f49"), "title" : "MongoDB", "description" : "MongoDB is a Nosql" }
也可以将数据定义为一个变量,然后插入这个变量
> document=({title:'MongoDB',description:'MongoDB is a Nosql'})
{ "title" : "MongoDB", "description" : "MongoDB is a Nosql" }
> db.col2.insert(document)
WriteResult({ "nInserted" : 1 })
更新文档
> db.collection.update(
... <quert>,
... <update>,
... {
... upsert:<boolean>,
... mult:<boolean>,
... writeConcern:<document>
... }
... )
- query:update的查询条件
- update:update的对象和一些更新的操作符等
- upsert:可选,如果不存在update的记录,是否插入新的信息,true为插入,false为不插入。
- multi:可选,mongodb默认是false,只更新找到的第一条记录,如果这个参数为true,就把找到的所有记录都更新。
- writeConcern:抛出异常的级别
实例
先插入数据
> db.col3.insert({
... title:'MongoDB',
... desription:'MongoDB is a Nosql database',
... url:'http://www.runoob.com'
... })
WriteResult({ "nInserted" : 1 })
更新
> db.col3.update({'title':'MongoDB'},{$set:{'title':'MongoDB教程'}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.col3.find().pretty()
{
"_id" : ObjectId("5b7d62e4693160100b200eb7"),
"title" : "MongoDB教程",
"desription" : "MongoDB is a Nosql database",
"url" : "http://www.runoob.com"
}
>
这个只会修改找到的第一条,如果想修改全部
>db.col3.update({'title':'MongoDB'},{$set:{'title':'MongoDB 教程'}},{multi:true})
更多实例
只更新第一条记录:
db.col.update( { "count" : { $gt : 1 } } , { $set : { "test2" : "OK"} } );
全部更新:
db.col.update( { "count" : { $gt : 3 } } , { $set : { "test2" : "OK"} },false,true );
只添加第一条:
db.col.update( { "count" : { $gt : 4 } } , { $set : { "test5" : "OK"} },true,false );
全部添加加进去:
db.col.update( { "count" : { $gt : 5 } } , { $set : { "test5" : "OK"} },true,true );
全部更新:
db.col.update( { "count" : { $gt : 15 } } , { $inc : { "count" : 1} },false,true );
只更新第一条记录:
db.col.update( { "count" : { $gt : 10 } } , { $inc : { "count" : 1} },false,false );
删除文档
db.collection.remove(
<query>,
{
justOne: <boolean>,
writeConcern: <document>
}
)
- query:删除文档的条件
- justOne:如果为true或1,则只删除一个文档
- writeConcern:抛出异常的级别
实例
执行两次插入操作
> db.col3.insert({ title:'MongoDB', desription:'MongoDB is a Nosql database', url:'http://www.runoob.com' })
WriteResult({ "nInserted" : 1 }
移除title为MongoDB的数据
> db.col3.find()
{ "_id" : ObjectId("5b7d65ba010bdb2011d20591"), "title" : "MongoDB", "desription" : "MongoDB is a Nosql database", "url" : "http://www.runoob.com" }
{ "_id" : ObjectId("5b7d65bd010bdb2011d20592"), "title" : "MongoDB", "desription" : "MongoDB is a Nosql database", "url" : "http://www.runoob.com" }
> db.col3.remove({'title':'MongoDB'})
WriteResult({ "nRemoved" : 2 })
> db.col3.find()
>
查询文档
db.collection.find(query, projection)
- query:查询条件
- projection:使用投影操作符制定返回的键。
使用易读的方式来读取数据。
>db.col.find().pretty()
findOne方法只返回第一个找到的文档
MongoDB AND条件
find()方法可以传入多个key,每个key以逗号隔开,即传入多个条件进行查询。
>db.col.find({key1:value1, key2:value2}).pretty()
MongoDB OR条件
k>db.col.find(
{
$or: [
{key1: value1}, {key2:value2}
]
}
).pretty()
两种方法还可以联合使用