NoSQL
NoSQL,指的是非关系型的数据库, Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称。Nosql的存储格式丰富,如键-值对存储,列存储,文档存储,图形数据库。 NoSQL用于超大规模数据的存储。(例如谷歌或Facebook每天为他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。
mongoDB
- 来自于英文单词“Humongous”,“庞大”; mongo != mango
- 面向文档,非关系型的NoSQL数据库
- 分布式文件存储的数据库,由 C++ 语言编写
- mongodb 中文网站:www.mongoing.com
- mongodb 中文文档:docs.mongoing.com
主要功能特性:
- 文件存储格式BSON(一种json的扩展):数据结构松散,可存储复杂的数据类型
- 模式自由:数据格式不受限于表的结构
- 支持动态查询: 可通过字段,范围查询进行搜索,并且还支持正则表达式搜索
- 支持索引: 多种索引类型
- 支持复制(主从复制)和故障恢复:支持集群与分片
- 使用高效的二进制数据存储,包括大型对象
- 自动处理碎片,以支持云计算层次的扩展。 ??
- 支持Java、Ruby、Python、C++、PHP等多种语言
- 内部支持Javascript ??
缺陷:
- 不支持事务,不支持多表联合查询
- mongoDB占用空间过大
数据库概念:
- Database
>use db_name //创建并连接到该库
>show dbs //列出所有的数据库列表(注意:空数据库不显示)
>db //检查当前选择的数据库
>db.dropDatabase(): 删除当前所连接的数据库
>
show dbs
local
0.078GB
test
0.078GB
>
use
test
switched to db test
>
db
test
>
备注:
1.可建立多个数据库
2. 默认数据库:test,
若没有创建过任何数据库,则集合
/
文档将存储在
test
数据库中
- Collection
>
db.createCollection(name, options)
参数说明:
·
name:
要创建的集合名称
·
options:
可选参数
,
指定有关内存大小及索引的选项
> show collections :显示当前数据库所拥有的集合
> db.COLLECTION_NAME.drop(): 删除名为COLLECTION_NAME的集合
举例:
>
use
test
switched to db test
>
db
.
createCollection
(
"col"
)
{
"ok"
:
1
}
>
show collections
col
>db.col.drop()
true
- document
> db.COLLECTION_NAME.insert(document)
> db.COLLECTION_NAME.insertOne():向指定集合中插入一条文档数据
> db.COLLECTION_NAME.insertMany():向指定集合中插入多条文档数据
> db.COLLECTION_NAME.save(document)
> db.COLLECTION_NAME.find() :查找已插入的所有文档
> db.COLLECTION_NAME.find().count():查询数量
> db.COLLECTION_NAME.find().limit(NUMBER): 限制查询数量
> db.COLLECTION_NAME.find().skip(NUMBER):跳过文档数量
> db.COLLECTION_NAME.find().sort({KEY:1}):根据指定字段排序,1:升序, -1:降序
> db.COLLECTION_NAME.find({key1:value1, key2:value2}) :AND条件查询
> db.COLLECTION_NAME.find({$or:[{key1:value1, key2:value2}]}) :OR条件查询
> db.COLLECTION_NAME.deleteMany({ key : value })
> db.COLLECTION_NAME.deleteOne({ key : value })
>
db
.col.
insert
({
"title"
:
"MongoDB 教程"
,
"description"
:
"MongoDB 是一个 Nosql 数据库"
,
"by"
:
"菜鸟教程"
,
"url"
:
"http://www.runoob.com"
,
"tags"
:
[
"mongodb"
,
"database"
,
"NoSQL"
],
"likes"
:
100
})
>db.col.find()
{
"_id" : ObjectId("56064886ade2f21f36b03134")
,
"title"
:
"MongoDB 教程"
,
"description"
:
"MongoDB 是一个 Nosql 数据库"
,
"by"
:
"菜鸟教程"
,
"url"
:
"http://www.runoob.com"
,
"tags"
:
[
"mongodb"
,
"database"
,
"NoSQL"
],
"likes"
:
100
}
> db.col.find({"by":"菜鸟教程", "title":"MongoDB 教程"}).pretty()
{
"_id" : ObjectId("56063f17ade2f21f36b03133"),
"title" : "MongoDB 教程",
"description" : "MongoDB 是一个 Nosql 数据库",
"by" : "菜鸟教程",
"url" : "http://www.runoob.com",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 100
}
>db.col.find().limit(1).skip(2); //仅显示第三个文档
Mongodb与RDBMS 的条件语句查询比较:
备注:
- 在插入的文档中,如果不指定_id参数,那么 MongoDB 会为此文档分配一个唯一的ObjectId,作为主键, _id为集合中的每个文档唯一的12个字节的十六进制数
- save 与 insert的区别:
指定_id: 若_id已存在,insert报错;save替换全部数据
不指定_id:insert 和 save 会为此文档分配一个唯一的ObjectId
索引:
- single field index (单字段索引)
>db.COLLECTION_NAME.ensureIndex({KEY:1})
Key
:要创建的索引字段,
1
:升序创建索引,
-1:
降序创建索引
- compound index(复合索引):
复合索引是
Single Field Index
的升级版本,它针对多个字段联合创建索引,先按第一个字段排序,第一个字段相同的文档按第二个字段排序,依次类推
.
>db.COLLECTION_NAME.ensureIndex({KEY1:1,KEY2:1})
举例:
>
db
.
person
.
ensureIndex
({
"age"
:
1
}) //单字段索引
>
db
.
person
.
ensureIndex
({
"title"
:
1,
"description"
:
-1
}) //复合索引
备注:
1.复合索引的字段顺序,最左前缀索引:复合能满足的查询场景比单字段索引更丰富,不光能满足多个字段组合起来的查询,比如db.person.find( {"age": 18, "name": "jack"} ),也能满足能匹配符合索引前缀的查询,这里{"age": 1}即为{"age": 1, "name": 1}的前缀,所以类似db.person.find( {"age": 18} )的查询也能通过该索引来加速;但db.person.find( {"name": "jack"} )则无法使用该复合索引。如果经常需要根据『name字段』以及『name和age字段组合』来查询,则应该创建如下的复合索引:
>db.person.createIndex( {name: 1, age: 1} )
2. 字段的值分布: 即使person集合所有的查询都是『name和age字段组合』(指定特定的name和age),字段的顺序也是有影响的。age字段的取值很有限,即拥有相同age字段的文档会有很多;而name字段的取值则丰富很多,拥有相同name字段的文档很少;显然先按name字段查找,再在相同name的文档里查找age字段更为高效。
- multikey index (多key索引)
当索引的字段为
数组
时,创建出的索引称为多
key
索引。多
key
索引会为数组的每个元素建立一条索引,比如
person
表加入一个
habbit
字段(数组)用于描述兴趣爱好,需要查询有相同兴趣爱好的人就可以利用
habbit
字段的多
key
索引。
举例:
{"name" : "jack", "age" : 19, habbit: ["football, runnning"]}
>db.person.ensureIndex( {habbit: 1} ) // 自动创建多key索引
>db.person.find( {habbit: "football"} )
- text index (文本索引)
支持对collection中的string内容进行搜索操作,即文本搜索,分词;
索引的建立:
db
.
COLLECTION_NAME
.
ensureIndex({key: "text"}) //
单键的文本搜索
db
.
COLLECTION_NAME
.
ensureIndex({key1: "text", key2: "text"}) //
多键的文本搜索
db
.
COLLECTION_NAME
.
ensureIndex({"$**":"text"}) //
给所有字段建立全文索引
索引的查询
db
.
COLLECTION_NAME.find({$text:{$search:"coffee"}}) //
查询
db
.
COLLECTION_NAME.find({$text:{$search:"coffee cola -tea"}}) //
非查询,加
-
即为排除该字段:
举例:
>
db.col.find()
{ "_id" : ObjectId("56064886ade2f21f36b03134"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }
>db
.
col
.
ensureIndex
({
"
description
"
:
"
text
"
}) //创建文本索引
>
db
.
col.find
(
{$text:{$search:"MongoDB "}
) //复合索引
{ "_id" : ObjectId("56064886ade2f21f36b03134"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100 }
>db.col.find({$text:{$search:"MongoDB"}})
>db.col.find({$text:{$search:"MongoDB Nosql"}}) //空格代表或操作,MongoDB或Nosql
>db.col.find({$text:{$search:"Nosql -Nosql"}}) //-号为非操作,即不包含Nosql的
>db.Col.find({$text:{$search: "\" MongoDB \" \" Nosql \""}}) //加双引号可以提供与关系操作
备注:
1.
使用文本索引查询不需要指定文本索引的字段名字——直接使用$text,$search即可
2.在MongoDB中每个数据集合只允许创建一个全文索引,不过这个全文索引可以针对一个、多个、全部的数据集合的字段来创建。
3. 每次查询,只能指定一个$text查询
4.
MongoDB全文索引还不支持中文
- 其他类型索引
哈希索引(Hashed Index)是指按照某个字段的hash值来建立索引,目前主要用于MongoDB Sharded Cluster的Hash分片,hash索引只能满足字段完全匹配的查询,不能满足范围查询等。
地理位置索引(Geospatial Index)能很好的解决O2O的应用场景,比如『查找附近的美食』、『查找某个区域内的车站』等。