目录
简介
NO SQL
NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL",泛指非关系型的数据库。Nosql在处理和分发大量数据,针对高并发这种情况时,具有很优秀的表现。常见的nosql数据库:
NoSQL数据库在以下的这几种情况下比较适用:
2、需要灵活性更强的IT系统
3、对数据库性能要求较高
4、不需要高度的数据一致性
5、对于给定key,比较容易映射复杂值的环境
MongoDB
MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 json 的Bjson格式。字段值可以包含其他文档,数组及文档数组。MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库中功能最丰富,最像关系数据库的。
MongoDB连接
数据库安装配置完成后,直接在命令行输入mongo,即可进入数据库,如下图(以下演示全部在windows下):
出现此界面说明已经成功连接数据库,可以看到版本是4.4.6,端口号是27017等信息。
几个常用命令:
#查看当前库
db
#进入某个库
use [库名]
#查看所有的库
show dbs
如图,进入数据库输入db,显示test库,test库是进入mongodb的一个默认库,admin,config,local是mongodb自带的三个库
创建数据库
- admin: 从权限的角度来看,这是"root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。
- local: 这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合
- config: 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。
#有则进入数据库,没有这个数据库则创建
use [库名]
如下图,成功创建first_mongo这个库
可以看到,我们已经成功创建了这个库并且已经进入,但是show dbs却没有显示这个库,原因是我们没有往库里插入数据,所以没有显示。
可以看到,当向库里插入一条数据后,我们新建的库就可以看到了。
删除数据库
#删除数据库
db.dropDatabase()
进入需要删除的数据库,然后执行db.dropDatabase(),此时查看已经没有first_mongo这个库了,此时有个问题,虽然库删掉了,但是输入db,还是可以看到,我们在这个库下面,但是内部已经没有任何数据,只存在了这个库名,此时无法向这个数据库插入数据。
创建集合
mongoDB中的数据都是存在集合里面,类似于MySQL的表的概念。
'''
方法一:
name为创建的集合名,optoins是可选参数
'''
db.createCollection(name,options)
'''
方法二:
直接插入数据即可创建集合
collectionname为集合名称,data为插入数据
'''
db.collectionname.insert(data)
options的可选参数:
如上图,创建集合或者直接插入数据,都成功创建了集合,show collections和show tables是显示当前数据库下的所有集合。
删除集合
#collectionname为集合名
db.collectionname.drop()
插入文档
所有存储在集合中的数据都是 BSON 格式。BSON 是一种类似 JSON 的二进制形式的存储格式,是 Binary JSON 的简称。
#collectionname为集合名,data为插入的数据
db.collectionname.insert(data)
如上图,已经成功插入一条数据,find()为查看集合数据的命令,每个条数据都会有一个默认的ObjectId,ObjectId 类似唯一主键,可以很快的去生成和排序,包含 12 bytes,共24个字符含义是:
- 前 4 个字节表示创建 unix 时间戳,格林尼治时间 UTC 时间,比北京时间晚了 8 个小时
- 接下来的 3 个字节是机器标识码
- 紧接的两个字节由进程 id 组成 PID
- 最后三个字节是随机数
同时,我们可以把插入的数据定义为一个变量,如下图:
更新文档
#collectionname为集合名,query为需要修改的数据,updatedata为修改后的数据,后面为几个可选参数
db.collectionname.update(
query,
updatedata,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
})
- upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
- multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
- writeConcern :可选,抛出异常的级别
可以看到,找到第一条name为jack的然后更新成功,接下来我们加入可选参数:
加入multi参数为true,更新了所有符合的数据
还可以通过save()函数,更新数据,如下图:
删除文档
#collectionname为集合名称,query为需要更改的数据,option为可选参数
db.collectionname.remove(query,option)
可选参数option:
- justOne : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。
- writeConcern :(可选)抛出异常的级别。
如果要删除该集合所有的数据,使用
#collectionname为集合名称
db.collectionname.remove({})
注意:2.6版本之前remove可以不传参数,2.6之后必须传参数,否则会报错
查询文档
db.collectionname.find(query,query,fields,limit,skip)
可选参数:
- query:指明查询条件,相当于SQL中的where语句
- fields:用于字段映射,指定是否返回该字段,0代表不返回,1代表返回
- limit:限制查询结果集的文档数量,指定查询返回结果数量的上限
- skip:跳过一定数据量的结果,设置第一条返回文档的偏移量
不加入参数,则查询出集合所有的数据
条件查询语句
如上图,查询年龄大于20的数据
MongoDB And条件
#and查询,即输入多个查询条件,用逗号隔开
db.collectionname.find({key1:value1,key2:value2})
MongDB OR条件
db.collectionname.find({$or:[{key1:value1},{key2:value2}]})
如上图,查询name为wade或者high为195的,符合全部输出
limit和skip查询
如上图,查询name为wade的前两条数据,并且只显示age字段,或者不显示age字段
如上图,加入了limit和skip,查询name为wade,三条数据,跳过查询到的第一条数据。
注意:limit和skip可以写进find()函数里面当参数使用,也可以写在外面调用函数,fields只能当作参数使用
MongoDB $type 操作符
$type操作符是基于BSON类型来检索集合中匹配的数据类型,并返回结果。
类型 | 数字 | 备注 |
---|---|---|
Double | 1 | |
String | 2 | |
Object | 3 | |
Array | 4 | |
Binary data | 5 | |
Undefined | 6 | 已废弃。 |
Object id | 7 | |
Boolean | 8 | |
Date | 9 | |
Null | 10 | |
Regular Expression | 11 | |
JavaScript | 13 | |
Symbol | 14 | |
JavaScript (with scope) | 15 | |
32-bit integer | 16 | |
Timestamp | 17 | |
64-bit integer | 18 | |
Min key | 255 | Query with -1. |
Max key | 127 |
如上图,查询name类型为2的数据,2代表的是string,输入2或者string都可以
MongoDB排序
db.cllectionname.find().sort({key:value})
问题点:可以对字符串排序,但是具体是什么规则,没有找到
注意:sort函数可以加入多个参数,经测试,只会对第一个参数排序,后面的无效
MongoDB索引
索引是为了加速对表中数据行的检索而创建的一种分散的存储结构。索引是针对表而建立的,它是由数据页面以外的索引页面组成的,每个索引页面中的行都会含有逻辑指针,以便加速检索物理数据。
#值为1是升序创建索引,-1是降序创建索引
db.collectionname.createIndex({key:1})
如上图,getindexes函数可以查看所有的索引,可以看到我们创建了一个name_1的索引
问题:我只创建了一个索引,但是查询出来有两个,原来mongodb对id自动创建索引,而且这个索引不可删除
删除索引
#删除所有索引
db.collectionname.dropIndexes()
#删除指定索引
db.collectionname.dropIndex("索引名称")
MongoDB聚合方法
aggregate() 方法
db.clollectionname.aggregate(options)
如上图,根据name分组,求每个name的总数;根据name分组,求age的平均值
表达式 | 描述 | 实例 |
---|---|---|
$sum | 计算总和。 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}]) |
$avg | 计算平均值 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}]) |
$min | 获取集合中所有文档对应值得最小值。 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}]) |
$max | 获取集合中所有文档对应值得最大值。 | db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}]) |
$push | 在结果文档中插入值到一个数组中。 | db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}]) |
$addToSet | 在结果文档中插入值到一个数组中,但不创建副本。 | db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}]) |
$first | 根据资源文档的排序获取第一个文档数据。 | db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}]) |
$last | 根据资源文档的排序获取最后一个文档数据 | db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}]) |
$project | 修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档 |
$match | 用于过滤数据,只输出符合条件的文档,$match使用MongoDB的标准查询操作 |
$limit | 用来限制MongoDB聚合管道返回的文档数 |
$skip | 在聚合管道中跳过指定数量的文档,并返回余下的文档 |
$unwind | 将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值 |
$group | 将集合中的文档分组,可用于统计结果 |
$sort | 将输入文档排序后输出 |
$geoNear | 输出接近某一地理位置的有序文档 |
聚合函数内容较多,需要多练习,以加强理解和操作。
Python操作MongoDB
首先安装pymongo库
pip install pymongo
import pymongo
client = pymongo.MongoClient("mongodb://127.0.0.1:27017") #连接数据库
mydb = client['521mongo'] #新建一个数据库
mycol1 = mydb['collection1'] #新建一个集合
mycol1.insert_one({'name':'jack'}) #向集合内插入一条数据
doc = [{'name':'tom','age':12},{'name':'james','age':13},{'name':'wade','age':18}]
mycol1.insert_many(doc) #向集合中插入多条数据
for i in mycol1.find(): #查询所有数据
print('all',i)
for x in mycol1.find({'name':'wade'}): #查询指定条件
print('wade',x)
dblist = client.list_database_names() #查询所有的数据库
print('dblist',dblist)
colname = mydb.collection_names() #查询所有集合
print('colname',colname)
mycol1.update_one({'name':'wade'},{'$set':{'age':20}}) #更新一条数据
update_wade = mycol1.find_one({'name':'wade'})
print('update_wade',update_wade)
for m in mycol1.find().sort('age',1): #排序,1为升序,-1为降序,不填默认为1
print('sort',m)
mycol1.delete_one({'name':'jack'}) #删除一条数据
for n in mycol1.find():
print('delete',n)
打印结果:
all {'_id': ObjectId('5ec65800f468dcff9b4a890a'), 'name': 'jack'}
all {'_id': ObjectId('5ec65800f468dcff9b4a890b'), 'name': 'tom', 'age': 12}
all {'_id': ObjectId('5ec65800f468dcff9b4a890c'), 'name': 'james', 'age': 13}
all {'_id': ObjectId('5ec65800f468dcff9b4a890d'), 'name': 'wade', 'age': 18}
wade {'_id': ObjectId('5ec65800f468dcff9b4a890d'), 'name': 'wade', 'age': 18}
dblist ['521mongo', 'admin', 'config', 'first_mongo', 'local', 'mongo1', 'mongo2']
colname ['collection1']
update_wade {'_id': ObjectId('5ec65800f468dcff9b4a890d'), 'name': 'wade', 'age': 20}
sort {'_id': ObjectId('5ec65800f468dcff9b4a890a'), 'name': 'jack'}
sort {'_id': ObjectId('5ec65800f468dcff9b4a890b'), 'name': 'tom', 'age': 12}
sort {'_id': ObjectId('5ec65800f468dcff9b4a890c'), 'name': 'james', 'age': 13}
sort {'_id': ObjectId('5ec65800f468dcff9b4a890d'), 'name': 'wade', 'age': 20}
delete {'_id': ObjectId('5ec65800f468dcff9b4a890b'), 'name': 'tom', 'age': 12}
delete {'_id': ObjectId('5ec65800f468dcff9b4a890c'), 'name': 'james', 'age': 13}
delete {'_id': ObjectId('5ec65800f468dcff9b4a890d'), 'name': 'wade', 'age': 20}