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的应用场景,比如『查找附近的美食』、『查找某个区域内的车站』等。