head
数据存储阶段
文件管理阶段 (.txt .doc .xls)
优点 : 数据便于长期保存
数据可以大量存储
使用简单
缺点 : 数据的存储结构比较随意
数据的查找修改效率低
不方便扩展和程序调用
数据库管理阶段
优点 : 数据格式化存储,便于操作
降低了数据的冗余,提高了增删改查的效率
方便程序调用和扩展
缺点 : 使用上往往需要特定的语句或者操作,相对复杂
几个概念
数据 : 能够输入到计算机中并被识别处理的信息集合
数据结构:研究一个数据集合中,数据之间关系的学科
数据库:按照数据结构,存储管理数据的仓库。数据库是在数据库管理系统管理和控制下在一定介质上存储的数据集合。
数据库管理系统 : 数据库管理软件,用于维护建立数据库。
数据库系统 : 由数据库和数据库管理系统等开发工具组成的集合
关系型数据库
采用关系模型来组织数据结构的数据库(二维表)
e.g. Oracle DB2 SQLServer Mysql Sqlite
优点 : 容易理解,逻辑类似常见的表格
使用方便,都使用sql语句进行数据操作,sql语句很成熟
数据的一致性高,冗余低,完整性好
技术成熟,可以使用表关联等复杂操作
缺点 : 每次数据操作都需要sql解析,消耗较大
关系型数据库内部操作往往需要加锁,也影响了处理速度
不能很好的处理海量数据的高并发需求,读写能力差
由于数据的一致性等规定,灵活性也不高
非关系型数据库(NoSql —> Not Only Sql)
优点 : 并发能力强读写速度快,可以更好应对海量数据并发需求
普遍比较灵活,容易扩展,弱化了数据的一致性
缺点 : 通用性差,没有像sql那样一致的语句操作
灵活性强会导致一定的操作混乱
技术成熟度比关系型数据库要差
Nosql 使用情况
1. 对数据一致性要求较低
2. 应对数据高并发存储的可能性较大
3. 比较容易建立非关系性数据库模型
Nosql 分类
键值型数据库: Redis
列存储数据库:HBase
文档型数据库:MongoDB
图形数据库
MongoDB数据库 (非关系型,文档型数据库)
特点:
1. 由c++编写的数据库管理系统
2. 支持丰富的增删该查操作
3. 由丰富的存储类型,技术相对成熟
4. 支持众多的编程语言操作
5. 使用方便,便于扩展和部署
MongoDB 安装
linux : sudo apt-get install mongodb
安装位置: /var/lib/mongodb
配置文件: /etc/mongodb.conf
命令集 : /usr/bin
手动安装 :1. www.mongodb.com 下载对应系统的安装包
2. 将压缩包解压到一个目录下 /usr/local
3. 进入解压后的目录,里面的bin目录即命令集所在目录,将这个目录(bin)路径加入环境变量即可
e.g. 将/opt/mongodb/bin 加入环境变量,终端执行:
PATH=$PATH:/opt/mongodb/bin
export PATH
如果不想每次启动都执行则将以上两句写入主目录 下的 .bashrc中
MongoDB 命令
设置数据库的存储位置 : mongod —dbpath 目录
e.g. 将database目录设置为数据库存储目录
mongod —dbpath database
设置数据库连接端口 : mongod —port port
如果不设置默认端口为27017
启动MongoDB 操作界面(mongo shell): mongo
退出该界面用 ctrl-c 或者 quit()
mongodb数据库结构
键值对 —》 文档 —》 集合 —》 数据库
—————————————-
ID | NAME | AGE
—————————————-
1 | Lily | 18
—————————————-
2 | Lucy | 17
—————————————-
{
“_id”:1,
“NAME”:”Lily”,
“AGE”:18
},
{
“_id”:2,
“NAME”:”Lucy”,
“AGE”:17
}
mysql mongodb 含义
database database 数据库
table collection 表/集合
column field 字段/域
row document 记录/文档
index index 索引
创建数据库
use database
e.g. 创建一个叫stu的数据库
use stu
use 实际是选择使用哪个数据库,当这个数据库不存在时会自动创建这个数据库
使用use创建数据库,并不会马上建立起来。而是需要真正插入数据时才会产生
查看系统中数据库 : show dbs
数据库命名规则:
1. 使用utf-8字符
2. 不能含有 空格 . / \ ‘\0’ 字符
3. 长度不超过64字节
4. 不要和系统数据库重名
全局变量db : db变量代表当前正在使用的数据库
如果不选择任何数据库 db 为test
删除数据库: db.dropDatabase() 删除db代表的数据库
数据库的备份和恢复
备份数据库:mongodump -h dbhost -d dbname -o dir
e.g. 备份 本机中 stu数据库 到当前目录
mongodump -h 127.0.0.1 -d stu -o .
数据库文件恢复:
mongorestore -h dbhost:port -d dbname path
e.g. 获取数据 到本机 student数据库中 从stu
mongorestore -h 127.0.0.1:27017 -d student ./stu
数据库监控命令
mongostat 查看数据库运行状态
insert query update delete : 每秒执行增查改删的次数
command : 每秒执行mongo命令次数
flushes : 和磁盘交互情况
vsize res : 使用虚拟内存和物理内存情况
time : 运行时间
mongotop 检测每个数据库中数据表的读写情况
ns 数据集合
total 总时长
read 读时长
write 写时长
创建集合
方法1: db.createCollection(collection)
e.g. 创建集合class1
db.createCollection(‘class1’)
方法2: 当插入数据时,需要指定集合,此时如果集合不存在则自动创建
e.g. 插入数据时class2不存在则自动创建这个集合
db.class2.insert({‘name’:’宝’,’age’:35,’sex’:’m’})
查看数据库中集合 : show collections
show tables
集合命名规则:
1. 使用utf-8字符
2. 不能含有 \0 字符
3. 不要以system.开头,这是系统集合默认开头
4. 不要和关键字重复
删除集合: db.collection.drop()
e.g. 删除数据库中class集合
db.class.drop()
集合重命名: db.collection.renameCollection(‘new_name’)
e.g. 将集合class重命名为class0
db.class.renameCollection(“class0”)
文档
什么是文档?
文档是mongodb数据库中基本的数据组成形式类似字典
文档由键值对构成,每个键值对表达一个数据项
mongodb文档属于bson类型数据
文档中的键值对是有序的
键 :即文档的域,表达值是什么内容
键的命名规则:
1. 使用utf-8字符串
2. 不能使用\0
3. 一个文档中的键不能重复
值 : 即数据库存储的数据
类型 值
数字 整数 小数
布尔类型 true false
Array 数组
Date 日期时间
Timestamp 时间戳
String 字符串
Binary data 二进制字符串
Null 空 null
Object 内部文档(对象)
regex 正则表达式
code 代码
ObjectId ObjectId字串
ObjectId类型
“_id” : ObjectId(“5bd13b8049c6eee82a51e915”)
_id: 当插入mongodb文档时会自动生成_id域作为主键id
值 : ObjectId数据,为了和其他的值不重复
24位16进制编码
8位文档创建时间 6位机器ID 4位进程id 6位计数器
集合中的文档
1. 每个集合中的文档格式可以不同
2. 一个集合中存储的数据尽量体现相同的内容
3. 文档的表达尽量层次不要太多
插入文档
插入单个文档 : db.collection.insertOne()
功能 : 插入一条文档
参数 : 要插入的文档
e.g. 向class0中插入一个条文档
db.class0.insertOne({‘name’:’Lucy’,’age’:17,’sex’:’w’})
db.class.find()查看插入结果
数据操作时,键可以不加引号
可以自己添加_id域,但是_id域的值不能重复
一个集合中插入的文档是有序的
插入多条文档 : db.collection.insertMany([{},{}…])
功能: 插入多个文档
参数: 数组中包含多个文档
e.g. 向class2中插入多个文档
db.class2.insertMany([{name:’阿蓉’,age:28,sex:’w’},{name:’阿哲’,age:34,sex:’m’}])
插入文档: db.collection.insert()
功能 : 等于 insertOne + insertMany
e.g.
db.class0.insert([{name:’Emma’,age:19,sex:’w’},{name:’Abby’,age:17,sex:’w’}])
save 插入文档
db.collection.save()
功能 : 插入文档 用法同insert
参数 : 与insert相同够可以插入一条或者多条文档
e.g. 可以插入一条或者多条文档
db.class1.save({‘name’:’小红’,age:8,sex:’w’})
e.g. 如果要插入的文档_id已经存在则会替换掉原有文档内容
db.class0.save({_id:1,name:’Levi’,age:17,sex:’m’})
获取集合对象
db.getCollection(collection_name)
功能:获取到集合对象,等同于 db.collection
e.g.
db.getCollection(‘class0’) <====> db.class0
查找操作
mysql : select … from table where ….
mongo : db.collection.find(query,field)
查找集合中所有内容 :
db.collection.find() —> select from table
find(query,field)
功能 : 查找所有符合条件的文档
参数 : query 表示筛选条件,是一个键值对文档,默认表示查找所有内容
e.g. 筛选所有年龄为17的文档
db.class0.find({age:17})
field 表示查找的域,是一个键值对文档,用0值表示不查找某个域,1表示查找某个域
e.g. 不查找_id域,只查找name域内容
db.class0.find({},{_id:0,name:1})
当某个普通域设置为0时表示该域不查找,其他的域查找。如果设置为1则表示该域查找,其他的不查找。
对于普通域在表达式值0 和 1不能再参数中同时出现
_id域比较特殊,如果不想查找必须明确_id:0
findOne(query,field)
功能 : 查找第一条符合条件的文档
参数 : 使用同find
e.g. 查找第一个年龄为17的文档
db.class0.findOne({age:17},{_id:0})
day02
前情回顾
关系型数据库和非关系型数据库的比较- 不是关系模型构建的数据结构,不保证数据的一致性,结构更加 灵活自由
- 非关系型数据库弥补了关系型数据库在处理高并发存储时读写效 率低的问题
- 非关系型数据库种类多样,技术不如关系型数据库成熟,没有统 一的操作语句,处于不断发展更新阶段
Mongodb特点,安装,基本设置
创建数据库
use database
db.dropDatabase() 删除数据库
show dbs 查看数据库
mongodump 备份
mongorestore 恢复
mongostat 数据库监测
mongotop 数据库读写时长
集合操作
db.createCollection() 创建集合
db.collection.insert() 创建集合
db.getCollection() 获取集合对象
db.collection.drop() 删除集合
db.collection.renameCollection() 集合重命名
show collections 集合查看
插入文档
insertOne()
insertMany()
insert()
save()
查找操作
find(query,field)
findOne()
query的筛选功能
操作符 : 使用$符号注明的一个有特殊意义的字符串,用以表达丰富 的含义。 比如 $lt 表示小于
比较操作符:
$eq 等于 =
e.g. 年龄等于17
db.class0.find({age:{$eq:17}},{_id:0})
$lt 小于 <
e.g. 姓名小于Tom (字符串也可以比较大小)
db.class0.find({name:{$lt:"Tom"}},{_id:0})
$gt 大于 >
e.g. 找到大于16且小于19的 (条件文档中可以有多个键值对,多个键值对为并且关系)
db.class0.find({age:{$gt:16,$lt:19}},{_id:0})
$lte 小于等于 <=
e.g. db.class0.find({age:{$lte:17}},{_id:0})
$gte 大于等于 >=
e.g. db.class0.find({age:{$gte:17}},{_id:0})
$ne 不等于 !=
e.g. db.class0.find({age:{$ne:17}},{_id:0})
$in 包含
e.g. 查找年龄在数组范围中的文档
db.class0.find({age:{$in:[16,18,20]}},{_id:0})
$nin 不包含
e.g. :查找年龄不在数组范围中的文档
db.class0.find({age:{$nin:[17,19,21]}},{_id:0})
逻辑操作符
表示逻辑与
1. 在query文档中逗号隔开的多个键值对即表示与关系
e.g. 年龄等于17 并且 性别为女
db.class0.find({age:17,sex:'w'},{_id:0})
2. $and 表示逻辑与
e.g. 年龄等于17 并且 性别为女
db.class0.find({$and:[{age:17},{sex:'w'}]},{_id:0})
表示逻辑或 $or
e.g. 年龄小于17 或者 性别为女
db.class0.find({$or:[{age:{$lt:17}},{sex:'w'}]},{_id:0})
表示逻辑非 $not
e.g. 年龄不大于17
db.class0.find({age:{$not:{$gt:17}}},{_id:0})
表示逻辑既不也不 $nor not (A or B) (not A) and (not B)
e.g. 既不是男生,年龄也不大于18
db.class0.find({$nor:[{sex:'m'},{age:{$gt:18}}]},{_id:0})
条件混合
年龄(大于18 或者 小于17) 并且 要求性别为女
db.class0.find({$or:[{age:{$gt:18}},{age: {$lt:17}}],sex:'w'},{_id:0})
年龄大于等于17的男生 或者 姓名为Abby
db.class0.find({$or:[{age:{$gte:17},sex:'m'}, {name:'Abby'}]},{_id:0})
数组类型查找
数组 : 一组数据的有序集合 ,使用[]表示
有序的
数据类型可以不相同
查找数组中包含某一项
e.g. 查找score数组中包含90的文档
db.class3.find({score:90},{_id:0})
查找数组中同时包含多项 $all
e.g. 查找score数组中同时包含88,90的文档
db.class3.find({score:{$all:[88,90]}},{_id:0})
根据数组项数查找 $size
e.g. 查找数组中包含3项的文档
db.class3.find({score:{$size:3}},{_id:0})
选择数组的查询部分 $slice (用于field参数)
e.g. 显示数组的前两项
db.class3.find({name:'小明'},{_id:0,score:{$slice:2}})
e.g. 跳过数组第一项显示后面两项
db.class3.find({name:'小明'},{_id:0,score:{$slice:[1,2]}})
其他查找操作符
$exists 判断一个域是否存在 操作符值为bool
e.g.查找不存在sex域的文档(false表示不存在,true表示存在)
db.class0.find({sex:{$exists:false}},{_id:0})
$mod 通过除数余数筛选文档
e.g. 筛选年龄除以2余数为1的文档
db.class0.find({age:{$mod:[2,1]}},{_id:0})
$type 根据数据类型筛选
e.g. 查找name数据类型为 ‘2’ 的文档
db.class0.find({name:{$type:2}},{_id:0})
* mongo数据类型和数字的对照参看文档
double : 1
string : 2
* 可以通过查看 www.mongodb.com 下的docs文档查找新的操作符 使用方法
数据处理函数
db.collection.distinct(field)
功能 : 获取集合中某个域取值范围
e.g. 查看class0中age域的取值范围
db.class0.distinct('age')
pretty()
功能 : 将find查找结果格式化显示
limit(n)
功能:限制显示前n条文档
e.g. 显示查找结果前三条文档
db.class0.find({},{_id:0}).limit(3)
skip(n)
功能 : 跳过前n条文档,显示后面的文档内容
e.g. 跳过查找结果前3条文档,显示后面内容
db.class0.find({},{_id:0}).skip(3)
count()
功能:对查找结果计数统计
e.g.统计年龄等于17的文档(使用count query参数要写筛选条件)
db.class0.find({age:17},{_id:0}).count()
sort({field:1/-1})
功能:对查找结果按照指定的域排序显示
e.g. 按照年龄对查找结果升序排序(1 表示升序,-1表示降序)
db.class0.find({},{_id:0}).sort({age:1})
* 复合排序 : 对多个域进行排序,当第一排序项相同时,参考第 二排序项排序,依次类推。
e.g. 当年龄相同时按照姓名升序排序
db.class0.find({},{_id:0}).sort({age:1,name:1})
函数可以连续调用
* 当一个函数的返回结果仍然是文档集合,可以继续调用函数
e.g. 查找年龄最大的三位同学文档信息
db.class0.find({},{_id:0}).sort({age:-1}).limit(3)
* 对筛选的文档集合,可以使用索引序号取某一项
e.g. 通过序列号 1 取到删选结果的第二项
db.class0.find({},{_id:0})[1]
文档删除操作
mysql : delete from table where …
mongo : db.collection.deleteOne(query)
功能 : 删除符合条件的第一个文档
参数 : 筛选条件 用法同find query
e.g. 删除第一个性别为男的文档
db.class1.deleteOne({sex:'m'})
db.collection.deleteMany(query)
功能 : 删除所有符合条件的文档
参数 : 筛选条件 用法同find query
e.g. 删除所有性别为男的文档
db.class2.deleteMany({sex:'m'})
* 如果筛选条件为空则表示删除集合中所有文档
db.collection.remove(query,justOne)
功能:删除文档
参数:query 筛选条件 用法同find query
justOne 默认为false此时remove用法同deleteMany
如果为true 此时remove用法同deleteOne
e.g. 删除第一个年龄为17岁的文档(当第二个参数为 false时表示删除所有符合条件文档)
db.class0.remove({age:17},true)
db.collection.findOneAndDelete(query)
功能 : 查找某个文档并删除
参数 : query
返回 : 显示查找到的文档
e.g. 查找不存在sex域的文档并删除
db.class0.findOneAndDelete({sex:{$exists:false}})
练习 :
创建数据库 名字 grade
use grade
在数据库中创建集合 class
在集合中插入数据若干(8条左右) 格式如下:
{name:xxx,age:10,sex:’m’,hobby:[‘draw’,’dance’]}
年龄 7—14
hobby: draw dance running sing football basketball computer
db.class.insert({name:’Lily’,age:10,sex:’m’,hobby:[]})
查找练习
查看班级所有人信息
db.class.find()
查看班级中年龄为8岁的人员信息
find({age:8})
查看年龄大于10岁的学生信息
find({age:{$gt:10}})
查看年龄在8-12岁的学生信息
find({age:{lte:12}})
查看年龄为9岁且喜欢画画的女生
find({age:9,hobby:’draw’})
查看年龄小于8岁或者大于12岁的学生
find({lt:8}},{age:{$gt:12}}]})
找到年龄为9岁或者11岁的学生
find({age:{$in:[9,11]}})
找到有两项兴趣爱好的同学
find({hobby:{$size:2}})
找到兴趣爱好中有计算机的同学
find({hobby:’computer’})
找到既喜欢画画又喜欢跳舞的同学
find({hobby:{$all:[‘draw’,’dance’]}})
同学兴趣爱好有三项的学生人数
find(hobby:{$size:3}).count()
找到本班年龄第二大的同学
find().sort({age:-1})[1]
查看本班同学兴趣爱好的涵盖范围
db.class.distinct(‘hobby’)
找到本班年龄最小的三个同学
find().sort({age:1}).limit(3)
删除所有年龄大于12或者小于8岁的同学
deleteMany({lt:8}},{age:{$gt:12}}]})
修改文档
mysql : update table set … where …
mongo : db.collection.updateOne(query,update,upsert)
功能 : 修改第一个符合条件的文档
参数 : query 筛选条件 用法同find
update 要修改的数据项,需要和修改操作符一同 使用
upsert bool值 默认为false表示如果query没有筛 选到文档,则不做任何操作
如果设置为true则如果没有筛选到 文档会根据query update插入新的 文档
e.g. 将年龄17的第一个文档修改为年龄18
db.class0.updateOne({age:17},{$set:{age:18}})
e.g. 如果query内容不存在则会插入新文档
db.class0.updateOne({name:'Jame'},{$set{age:18}},
{upsert:true})
db.collection.updateMany(query,update,upsert)
功能:修改所有符合条件文档
参数: 参数用法同updateOne
e.g. 修改所有年龄为17的文档为年龄20
db.class0.updateMany({age:17},{$set:{age:20}})
db.collection.update(query,update,upsert,multi)
功能:修改筛选文档
参数: query 筛选条件
update 修改内容
upsert 如果为true则如果query文档不存在可以插入 新的文档
multi 默认为false 表示只能修改一条文档
设置为true 表示可以修改多条文档
e.g. 修改所有不存在sex域的文档年龄为20
db.class0.update({sex:{$exists:false}},{$set: {age:20}},false,true)
db.collection.findOneAndUpdate(query,update)
功能 : 查找一个文档并修改
参数 : query 查找条件
update 修改内容
返回 : 修改前的文档内容
e.g. 查找一个文档并修改年龄为17
db.class0.findOneAndUpdate({name:'Jame'},{$set: {age:17}})
db.collection.findOneAndReplace(query,docuemnt)
功能: 查找并替换一个文档
参数: query
document:要替换的文档
返回:返回原有文档内容
e.g. 用新的文档替换查找到的文档
db.class0.findOneAndReplace({abc:123}, {name:'Lily',age:19})
作业 : 复习mongodb的增删改查操作
day03
前情回顾
query的应用
操作符使用:
比较 : $lt $gt $lte $gte $ne $eq $in $nin
逻辑 : $and $or $not $nor
数组 : $all $size
其他 : $exists $mod $type
数据处理函数 : pretty() limit() skip() sort() count()
distinct()
删除操作: deleteOne() deleteMany() remove()
findOneAndDelete()
修改操作: updateOne() updateMany() update()
findOneAndUpdate() findOneAndReplace()
修改器的使用
db.collection.update(query,update,upsert,multi)
$set : 修改一个域的值,或者增加一个域
e.g. 当一个域不存在时可以增加一个域
db.class0.update({name:'Jame'},{$set:{sex:'m'}})
$unset : 删除一个域
e.g. 删除一个文档sex域
db.class0.update({name:'Tom'},{$unset:{sex:''}})
$rename : 修改一个域的域名
e.g. 修改sex域名为gender
db.class0.updateMany({},{$rename:{sex:'gender'}})
$setOnInsert : 当update插入文档时,作为补充插入内容
e.g. : 插入新的文档时,gender:'w' 也会作为文档的域
db.class0.update({name:'Lucy'},{$set:{age:20}, $setOnInsert:{gender:'w'}},true)
$inc : 加法修改器
e.g. 所有人的age域值加1
db.class0.updateMany({},{$inc:{age:1}})
$mul : 乘法修改器
e.g. 将所有age域的值 乘以 0.5
db.class0.updateMany({},{$mul:{age:0.5}})
- $inc $mul 值可以是整数 小数,正数 负数
$max : 指定某个域的值如果小于规定值则改为规定值,大于规定值则 不变
e.g. 如果Alex age小于18则改为18,大于18则不变
db.class0.update({name:'Alex'},{$max:{age:18}})
$min : 指定某个域的值如果大于规定值则改为规定值,小于规定值则 不变
e.g. 如果lily age 大于20则改为20 小于20则不变
db.class0.update({name:'Lily'},{$min:{age:20}})
数组修改器
$push : 向数组中添加一项
e.g. 向score数组中增加5
db.class3.update({name:'小明'},{$push:{score:5}})
$pushAll : 向数组中增加多项
e.g. 向数组中添加多项内容
db.class3.update({name:'小红'},{$pushAll:{score: [10,5]}})
$pull : 从数组中删除某一个值(如果有重复值则都删除)
e.g. 删除score中所有的 5
db.class3.update({name:'小红'},{$pull:{score:5}})
$pullAll : 同时删除数组中多个值
e.g. 同时删除score中多个值
db.class3.update({name:'小红'},{$pullAll:{score: [82,10]}})
$pop : 弹出数组一项
e.g. 从数组中弹出一项 1表示最后一项 -1表示第一项
db.class3.update({name:'小亮'},{$pop:{score:-1}})
$addToSet : 向数组中添加一项,但是不能添加数组中已有数值
e.g. 如果score中没有88则添加,如果有则添加不上
db.class3.update({name:’小红’},{$addToSet:{score:88}})
$each : 对多个值进行逐一操作
e.g. 利用each同时添加90 10到数组
db.class3.update({name:’小明’},{each: [90,10]}}})
$position :指定位置插入数值 搭配each使用
e.g. 将91插入到数组的1号位置
db.class3.update({name:’小红’},{each: [91],$position:1}}})
$sort : 对数组进行排序 搭配each使用
e.g. 对数组进行升序排序
db.class3.update({name:’小亮’},{each: [],$sort:1}}})
时间类型
获取当前时间:
1. new Date() 自动生成当前时间
e.g.
db.class1.insert({book:'Python入门',date:new Date()})
2. ISODate() 自动获取当前时间
e.g.
db.class1.insert({book:'Python精通',date:ISODate()})
3. Date() 获取系统时间生成时间字符串
e.g.
db.class1.insert({book:'Python疯狂',date:Date()})
获取任意时间:
ISODate()
功能 : 将指定的时间转换为MongoDB的存储时间类型
参数 : 指定的时间
"2018-01-01 11:11:11"
"20180101 11:11:11"
"20180101"
e.g. 将字符串中的时间转换为ISODate存储
db.class1.insert({book:'Python崩溃',date:ISODate ('20180101 11:11:11')})
时间戳
valueOf() : 将标准时间转换为时间戳
e.g. 记录当前标准时间的时间戳
db.class1.insert({book:'Python涅磐',date:ISODate ().valueOf()})
Null类型数据
值 : null
1. 表示某个域的值为空
e.g. price域的值为空
db.class1.insert({book:'Python放生',price:null})
2. 表达某个域不存在
e.g. 查找gender域不存在的文档(或者gender域值为null)
db.class0.find({gender:null},{_id:0})
内部文档 (Object)
文档中某个域的值还是一个文档则这个文档为内部文档
* 当使用内部文档某个域的值时,需要用外部文档域 . 内部文档域的方法引用。此时需要加引号注明
e.g. 通过 book.title 进行查找
db.class2.find({'book.title':'狂人日记'},{_id:0})
e.g.
db.class2.update({'book.title':'骆驼祥子'},{$set: {'book.price':46.5}})
通过数组下标直接引用数组项
* 在使用数组时,可以通过数组域 . 数组下标的方式选中数组中具体某一项进行操作。
e.g. 查找数组第一项大于80的文档
db.class3.find({'score.0':{$gt:80}},{_id:0})
练习 :
基于之前的 grade 数据库
将小红的年龄修改为8岁,兴趣爱好变为跳舞画画
update({name:’小红’},{$set:{age:8,hobby:[‘dance’,’draw’]}})
追加小明兴趣爱好 唱歌
update({name:’小明’},{$push:{hobby:’sing’}})
小王多了兴趣爱好 吹牛 打篮球
update({name:’小王’},{$pushAll:{hobby:[‘吹牛’,’basketball’]}})
小李兴趣爱好要增加跑步,唱歌,但是不要和之前的兴趣重复
update({name:’小李’},{each:[‘running’,’sing’]}}})
该班级所有同学年龄加1
updateMany({},{$inc:{age:1}})
删除小明的sex属性
update({name:’小明’},{$unset:{sex:’’}})
删除小李兴趣中的第一个
update({name:’小李’},{$pop:{hobby:-1}})
删除小红的兴趣画画唱歌
update({name:’小红’},{$pullAll:{hobby:[‘draw’,’sing’]}})
为小王增加一个域 备注 :{民族:‘回族’,习俗:“不吃猪肉”}
update({name:’小王’},{$set:{备注 :{民族:‘回族’,习俗:“不吃猪肉”}}})
在小王的备注中增加一项 宗教:“伊斯兰教”
update({name:’小王’},{$set:{‘备注.宗教’:’伊斯兰教’}})
索引
什么是索引?
索引是建立文档所在位置的查找清单,使用索引可以方便进行快速查找,减少遍历次数,提高查找效率
索引约束
1. 索引本身也占有数据库空间,所以当数据量很小的时候这种消耗是没有必要的
2. 索引表需要根据数据的修改及时修改,否则索引就会不和内容配套,也就失去了意义。因此如果数据库操作是频繁的修改操作而不是查找操作则不适合创建索引
创建索引
db.collection.createIndex()
功能: 创建索引
参数: 索引域 和 索引选项
e.g. 为name域创建索引
db.class0.createIndex({name:1})
* _id域会由系统自动创建索引
* 1 表示正向索引,-1表示逆向索引
查看集合中的索引
db.collection.getIndexes()
自定义索引名
e.g. 通过索引选项name定义索引名称
db.class0.createIndex({age:1},{name:"ageIndex"})
其他创建索引方法
ensureIndex()
功能 : 创建索引
参数 : 同createIndex()
e.g. 创建方法和createIndex用法一致
db.class1.ensureIndex({book:1})
createIndexes([{},{}])
功能 : 同时创建多个索引
参数 : 数组中存入创建索引键值对
e.g. 创建name和score两个域的索引
db.class3.createIndexes([{name:1},{score:-1}])
删除索引
db.collection.dropIndex()
功能 : 删除一个索引
参数 : 索引名称或者索引键值对
e.g. 通过名称删除索引
db.class3.dropIndex('name_1')
e.g. 通过键值对删除索引
db.class3.dropIndex({score:-1})
db.collection.dropIndexes()
功能 :删除集合中的所有索引 (不会删除_id索引)
e.g. 删除class0中所有索引
db.class0.dropIndexes()
索引类型
复合索引 : 根据多个域创建一个索引
e.g. 根据name age创建复合索引
db.class0.createIndex({name:1,age:-1})
子文档和数组索引:如果对某个域创建索引,该域的值为数组或者 子文档,则对数组中某一项或者子文档中某个 域的查找也是索引查找
e.g. 对book创建索引后,该查找也为索引查找
db.class2.find({'book.title':'围城'})
唯一索引 : 要求创建索引的域不能有重复的值
e.g. 对name域创建唯一索引
db.class0.createIndex({name:1},{unique:true})
稀疏索引 :会在创建索引时忽略没有指定域的文档
e.g. 对gender域创建稀疏索引
db.class0.createIndex({gender:1},{sparse:true})
聚合操作
对文档进行数据整理和统计
db.collection.aggregate()
功能 : 完成聚合操作
参数 : 聚合条件 需要配合聚合操作符使用
聚合操作符
$group 分组聚合 往往需要配合一定的统计操作符完成
统计求和 : $sum
e.g. 按照gender域的值分组,统计结果叫num,方法为加和
db.class0.aggregate({$group:{_id:"$gender",num: {$sum:1}}})
统计平均数 : $avg
e.g. 按照性别分组,求平均年龄
db.class0.aggregate({$group:{_id:"$gender",num:{$avg:'$age'}}})
求最大值 : $max
e.g. 按性别分组求最大年龄
db.class0.aggregate({$group:{_id:"$gender",num:{$max:'$age'}}})
求最小值 : $min
求第一个数: $first
求最后一个数: $last
$project : 用于格式化的显示文档内容
* 值得用法同find中field参数
e.g. 按照指定名称显示文档内容
db.class0.aggregate({$project:{_id:0,Name:'$name',Age:'$age'}})
$match : 筛选数据
* match值得写法同find 中的query参数
e.g. 筛选年龄大于19岁的文档
db.class0.aggregate({$match:{age:{$gt:19}}})
作业 : 修改操作符熟练使用
索引操作和聚合操作复习
复习pymysql使用
day04
前倾回顾:
1.修改器 : $set $unset $rename $setOnInsert
$inc $mul $max $min
$push $pushAll $pull $pullAll
$each $position $sort
$addToSet $pop
2.数据类型
时间类型 : Date() ISODate() valueOf()
Null 类型: null 表示空或者匹配某个域不存在
内嵌文档 :通过 . 获取内部文档值
索引操作
createIndex() ensureIndex() createIndexes()
dropIndex() dropIndexes()
getIndexes()
数据库比较大,并且查询操作较多的时候更适合使用索引
聚合操作
aggregate()
$group ---> $sum $avg $max $min $first $last
$project
$match
$limit 显示前几条文档
e.g. 显示出先3条文档
db.class0.aggregate({$limit:3})
$skip 跳过前几条文档显示后面内容
e.g. 跳过前3条文档显示后面内容
db.class0.aggregate({$skip:3})
$sort 对所选的域排序
e.g. 对文档按年龄升序排序
db.class0.aggregate({$sort:{age:1}})
聚合管道
指的是将多个聚合操作合并到一起完成,即将上一个聚合的结果作为下一个聚合的操作对象继续操作
db.collection.aggregate([{聚合1},{聚合2}....])
e.g. 先排序然后通过project进行显示设置
db.class0.aggregate([{$sort:{age:1}},{$project: {_id:0}}])
1. 将所有男生按照年龄排序,不显示_id
$match---> $sort --->$project
db.class0.aggregate([{$match:{gender:'m'}},{$sort: {age:1}},{$project:{_id:0}}])
2. 统计一下班里有名字重复的同学
$group --> $match
db.class0.aggregate([{$group:{_id:'$name',num: {$sum:1}}},{$match:{num:{$gt:1}}}])
固定集合
指的是mongodb中创建的固定大小的集合,称之为固定集合
特点:能够淘汰早期数据
可以控制集合的大小
插入,查找速度较快
使用:日志处理,临时缓存
创建:db.createCollection(collection, {capped:true,size:10000,max:1000})
capped:true 创建固定集合
size:10000 固定集合大小 字节
max : 1000 最多存放多少文档
e.g. 创建固定集合size 1000 max 3
db.createCollection('log',{capped:true,size:1000,max:3})
文件存储
文件存储数据库的方式
1. 存储路径 : 将本地文件所在的路径以字符串存储到数据库
优点 : 节省数据库空间
缺点 : 当数据库或者文件发生移动时必须要修改数据库内容
2. 存储文件本身 : 将文件转换为二进制存储到数据库
优点 : 文件随数据库移动,数据库在文件即在
缺点 : 占用数据库空间大,存储效率低
GridFS文件存储方案
目的 : 更好的存储MongoDB中超过16M的大文件
方案解释:在mongodb数据库中创建两个集合共同存储文件,一个存储文件信息,一个存储文件内容。两个集合相互配合
fs.files : 存储文件信息(文件名,大小等)
fs.chunks : 以mongodb二进制格式存储文件内容
存储方法 : mongofiles -d dbname put file
数据库 要存储的文件
* 数据库不存在会自动创建
e.g. 将img.jpg 存到grid数据库中
mongofiles -d grid put ./img.jpg
文件获取 : mongofiles -d dbname get file
* file目标文件为fs.files集合文档中 filaname值
e.g. 从grid数据库中获取文件
mongofiles -d grid get ./img.jpg
优缺点:
优点 :存储方便,提供了较好的命令,方便数据库移动
缺点 :读写效率较低,不建议用来存储小文件
mongo shell对javascript支持
在mongo shell下可以直接运行基本的js代码
游标 : 获取数据库操作结果集合的量
var cursor = db.class0.find() 获取游标
cursor.next() 通过游标获取文档内容
cursor.hasNext() 查看是否有下一个文档
python 模块 —》 pymongo 第三方模块
安装 : sudo pip3 install pymongo
操作步骤:
1. 创建mongodb数据库连接对象
conn = pymongo.MongoClient('localhost',27017)
2. 生成要操作的数据库对象 (__getitem__ __setitem__)
db = conn.stu
db = conn['stu']
3. 生成操作的集合对象
myset = db.class0
myset = db['class0']
4. 通过集合对象调用函数进行数据库操作
5. 关闭数据库连接
conn.close()
插入操作
insert() 插入一条或者多条文档
insert_many() 插入多条文档
insert_one() 插入一个文档
save() 插入一条文档,当有_id域时_id域重复会替换原文档
- pymongo中save参数是字典不能为列表
查找操作
find()
功能: 查找所有文档
参数: 同mongo shell 中find
返回: 游标变量
- pymongo 操作数据库时中所有的操作符均使用引号引起来当做字符串 传入
- mongodb中 true false 使用python的 True False即可
null 使用python的None即可
cursor游标对象属性函数
next() 获取下一个文档
limit() 显示前几条文档
skip() 跳过前几条显示后面内容
count() 统计计数
sort() 排序
pymongo : sort([(‘age’,1),(‘name’,-1)])
mongo shell: sort({age:1,name:-1})
- 当使用游标对象调用limit skip sort等函数时,要求游标对象必须 为初始游标,即没有被for或next取值过
find_one()
功能:查找一条文档
参数: 同find
返回: 返回一个字典
修改操作
update()
update_one()
update_many()
删除操作
remove(query,multi=True)
- 默认删除多个,当multi设置为False时只删除一个
delete_one()
delete_many()
索引操作
create_index()
功能 : 创建索引
参数 : 域名 则默认对该域创建正向索引
传入列表,列表中每个二维元组代表一个索引项
e.g. [(age,-1)] 表示对age创建逆向索引
list_indexes() 查看索引
drop_index() 删除一个索引
drop_indexes() 删除所有索引
聚合操作
aggregate([])
参数 : 同mongoshell中的聚合
返回值 : 返回一个和find函数相同的游标对象
文件操作
GridFS文件提取
import gridfs
1.连接数据库,生成数据库对象
2.生成gridfs对象
fs = gridfs.GridFS(db)
3.通过fs获取存储的文件集合
files = fd.find()
4.挑选想获取的文件进行读取
GridFS文件存储
1.连接数据库,生成数据库对象
2.生成gridfs对象
fs = gridfs.GridFS(db)
3.通过fs.put()函数将读取出来的文件内容存入数据库
fs.put(data,filename)
参数 : data 要存入的二进制内容
filename 文件存入的名称
作业 : 总结mongodb知识点