第一天
数据库 MongoDB(芒果数据库)
数据存储阶段
文件管理阶段(.txt .doc .xls)
优点:数据可以长期保存
可以存储大量的数据
使用简单
缺点:数据一致性差
数据查找修改不方便
数据冗余度可能比较大
数据库管理阶段
优点:数据组织结构化降低了冗余度
提高了增删改查的效率
容易扩展
方便程序调用,做自动化处理
缺点:需要使用sql 或者 其他特定的语句,相对比较复杂
几个概念
数据:能够输入到计算机中并被识别处理的信息集合
数据结构:研究一个数据集合体中数据之间关系的
数据库:按照数据结构,存储管理数据的仓库。数据库是在数据库管理系统管理和控制下,在一定截止上的数据集合
数据库管理系统:管理数据库的软件,用于建立和维护数据库
数据库系统:由数据库和数据库管理系统,开发工具等组成的集合
关系型数据库:
采用关系模型来组织数据结构的数据库(二维表)
oracle DB2 SQLServer MySql Sqlite(Python标准库的支持)
优点:容易理解,类似我们常见的表格
使用方便,都是使用sql语句,sql语句非常成熟
数据一致性高,冗余度低,完整性好
技术成熟,可以使用外部链接等比较复杂的操作
缺点:不能很好的满足高并发需求,每次都需要进行sql语句的解析
针对海量数据的瞬间爆发读写性能不足,关系型数据库内部每步都需要加锁保证操 作的原子性
数据扩展普遍比非关系型困难
数据一致性高,有时会浪费大量空间
非关系型数据库(Nosql----->Not only Sql)
优点:高并发,大数据读写能力强
支持分布式,容易扩展
弱化了数据结构,降低了数据的一致性
缺点:通用性差,没有像sql那样一致的操作
操作灵活,容易混乱
没有join,事务支持等操作
NOsql的使用起情况:
1、数据一致性要求低
2、数据库并发处理要求高
3、数据库设计时对大小的估算不确定,需要分布拓展
4、给定的数据比较容易建立起Nosql
Nosql分类:
1、键值型数据库
Redis oracle BDB Tokyo
2、列存储数据库
HBase
3、文档型数据库
MongoDB CouchDB
4、图形数据库
MongoDB(非关系型---》文档型数据库)
1、由c++编写的数据库管理系统
2、支持非常丰富的增删改查数据操作
3、支持非常丰富的数据类型
4、使用方便,便于部署,支持分布,容易扩展
5、支持众多的编程语言接口(python ruby c++ C# PHP )
MongoDB安装
自动安装
sudo apt-get install mongodb
默认安装位置 /var/lib/mongodb
配置文件 etc/mongodb.conf
命令集 /usr/bin /usr/local/bin
手动安装:
1、下载mongodb
www.mongodb.com----->Download------>community server
选择适合版本下载
2、选择安装目录解压(/usr/local /opt)
tar解压后得到mongo文件夹
3、将文件夹下的命令集目录(bin目录)添加到环境变量
PATH=$PATH:/opt/mongo..../bin
export PATH
将以上两句写在 /etc/rc.local
4、重启
mongodb 命令
设置数据库存储位置
mongod --dbpath 目录
设置端口号
mongodb--port 8888
*如果不设置则使用默认端口号 27017
mongo
进入mongo shell界面 mongodb的交互界面用来操作数据库
退出mongo shell :quit()
组成结构:键值对-----》文档-----》集合---》数据库
Mysql和mongodb 概念对比
mysql mongo 含义
database database 数据库
table collection 表/集合
column field 字段/域
row document 记录/文档
index index 索引
创建数据库
use databasename
e.g
创建一个叫stu的数据库
use stu
*use实际功能是表示选择使用哪个数据库,当这个数据库不存在时,即表示创建该数据库
*使用use后数据库并不会马上被创建,而是需要插入数据后数据库才会被创建
查看数据库
show dbs
数据库名称规则
1、原则上是任意满足以下几条的utf-8字符
2、不能是空字符,不能含有空格 ' ' 点 '.' '/' '\' '\0'
3、习惯上使用英文小写
4、长度不超过64字节
5、不能使用admin local config这样的名字
admin:存储用户
local:存储本地数据
config:存储分片配置信息
db:mongo系统全局变量 代表你当前正在使用的数据库
db 默认为test 如果插入数据即创建test数据库
数据库的备份和恢复
备份 mongodump -h dbhost -d dbname -o dbdir
e.g mongodump -h 127.0.0.1 -d stu -o stu
将本机下stu数据库备份到当前目录的student文件夹中会在student文件夹中自动生成一个stu文件夹则为备份文件
恢复 mongorestore -h 127.0.0.1:27017 -d test student/stu
将student文件夹下的备份文件stu恢复到本机的test数据库
数据库的监测命令
mongostat
insert query update delete :每秒增删改查的次数
getmore command :每秒运行命令次数
dirty used flushes :每次操作磁盘的次数
vsize res :使用虚拟内存和物理内存
qrw arw net_in net_out conn time
mongotop
监测每个数据库的读写时长
ns total read write
数据集合 总时长 读时长 写时长
删除数据库
db.dropDatabase()
删除db所代表的的数据库
集合的创建
db.createCollection(collection_name)
e.g db.createCollection("class2")
当前数据库下创建一个名字为class2的集合
查看数据库中集合
show tables
show collections
集合的命名规则:
1、不能为空字符串,不能有‘\0’
2、不能以system.开头 这是系统集合的保留前缀
3、不能和保留字重复
创建集合2
当向一个集合中插入文档时,如果该集合不存在则自动创建
db.collectionName.insert()
e.g db.class0.insert({a:1})
如果class0不存在则会创建class0集合号并插入该数据
删除集合
db.collectionName.drop()
e.g db.class0.drop()
删除class0集合
集合重命名
db.collectionName.renameCollection('new_name')
e.g db.class2.renameCollection('class0')
将class2重命名为class0
文档
mongodb中文档的组织形式
键值对组成文档----》类似python中的字典
bson
mongodb中文档的数据结构形式为bson格式,类似python的字典,也是由键值对构成
文档中键的命名规则:
1、utf-8格式字符串
2、不能有\0 习惯上不用 .和$
3、以_开头的多位保留键,自定义时一般不以_开头
注意:文档键值对是有序的,
mongodb中严格区分大小写
值:mongodb的支持数据类型
支持的数据类型
类型 值
整型 整数
布尔类型 true false
浮点型 小数
Arrays 数组类型[1,2,3,]
Timestamp 时间戳
Date 时间日期
Object 内部文档
Null 空值
Symbol 特殊字符
string 字符串
Binary data 二进制子串
code 代码
regex 正则表达式
ObjectID ObjectID子串
ObjectID:系统自动为每个文档生成的不重复的主键
键名称: _id
值:ObjectId("5b03b832992bae77a9b217da")
24位16进制数
8 文档创建时间 6机器ID 4进程ID 6计数器
文档中键------》域
文档--------》记录
集合中文档特点:
1.集合中的文档域不一定相同----》不保证数据一致性
2、集合中文档中的结构不一定相同
集合的设计原则:
1、集合中的文档尽可能描述的数据类似
2、同一类文档放在相同的集合,不同的文档分集合存放
3、层次的包裹不宜太多
插入文档
db.collection.insert()
e.g
db.class0.insert({name:'Lucy',age:16,sex:'w'})
*当作为文档插入时键可以不加引号
查看插入结果 db.class0.find()
插入多条文档
db.collectionName.insert([{},{},{}])
e.g db.class0.insert([{'name':'阿花',age:28},{name:'阿红',age:26},{name:'阿彪',age:23}])
注意_id为系统自动添加主键,如果自己写_id域则会使用自己写的值。但是该值扔不允许重复。
save插入数据
db.collectionName.save()
e.g
db.class0.save({_id:2,name:'八戒',age:17,sex:'m'})
*在不加_id是使用同insert
*如果使用save插入的时候加了_id,则如果_id值不存在则正常插入,如果该值存在,则修改原来内容
*save无法一次插入多个文档
第二天:===============================================================
db.coolectionName 集合对象
获取集合对象 : db.getCollection('collection_name')
e.g:
db.getCollection("class0").insert({'name':'悟空',age:1700})
查找操作:
select ... from tableName where....
db.collectionName.find() ---->select * from tableName
find(query,field)
功能:查找所有符合条件的文档
参数:query:筛选条件 相当于where字句
field:展示的域 相当于select的展示部分
返回:返回所有查找到的内容
field参数:选择要展示的域 传一组键值对
值表示域名
值表示是否显示该域 0表示不显示 1表示显示
*如果某个域给定0 则表示不显示该域,其他的域均显示
*如果某个域给定1 则表示显示该域,其他的域都不显示
*_id永远默认显示,除非设置为0
*_id外其他域,必须拥有相同的设置,全为0或者全为1
*如果不写该参数则表示显示所有域内容
e.g> db.class0.find({},{_id:0,name:1,age:1})
query:以键值对的形式给出查找条件
查找年龄为17
db.class0.find({age:17},{_id:0})
*如果不写第一个参数则表示查找所有内容
findOne()
功能参数和find()完全相同,只是只返回第一条查找到的文档
e,g db.class0.findOne({age:17},{_id:0})
query的更多用法
操作符:使用$符号注明一个特殊字符串,表示一定的含义
e.g $lt 表示 小于
比较操作符
$eq 等于
e.g db.class0.fin({age:{$eq:17}},{_id:0})
筛选年龄等于17的
======>db.class0.find({age:17},{_id:0})
$lt 小于 <
e.g > db.class0.find({age:{$lt:20}},{_id:0})
*mongo中字符串也可以比较大小
$lte 小于等于 <=
e.g db.class0.find({age:{$lte:17}},{_id:0})
$gt 大于 >
e.g > db.class0.find({age:{$gt:17}},{_id:0})
$gte 大于等于>=
数组查找:
查看数组中的包含某一项
db.class1.find({hobby:'吃'},{_id:0}
$all
查找一个数组中同时包含多项的文档
e.g > db.class1.find({hobby:{$all:['拍电影','代言']}},{_id:0})
查找hobby数组中既有拍电影,又有代言的文档
$size
查找数组元素个数为指定个数的文档
e.g> db.class1.find({hobby:{$size:3}},{_id:0})
查看hobby数组中包含三项的文档
数组切片显示:
$slice
对数组切片显示
e.g
db.class1.find({hobby:{$size:3}},{_id:0,hobby:{$slice:2}})
显示数组的前两项
e.g
db.class1.find({hobby:{$size:3}},{_id:0,hobby:{$slice:[1,2]}})
跳过第一项,显示后面两项
其他查找方法:
$exists
判断一个域是否存在
e.g 查找不存在sex域的文档
db.class0.find({sex:{$exists:false}},{_id:0})
$mod
做除数余数查找
e.g.
查找年龄 被2除余1的文档
> db.class0.find({age:{$mod:[2:1]}},{_id:0})
$type
查找指定数据类型的文档
进一步的信息筛选
distinct()
功能:查看一个集合中某个域值的覆盖范围
e.g查看集合中age域的值都有哪些
db.class0.distinct('age')
pretty()
功能:将查询功能格式化显示
limit(n)
功能:查询结果显示前n条
e.g查询结果显示前三个
db.class0.find({},{_id:0}).limit(3)
skip(n)
功能:显示时跳过前n条
e.g显示时跳过前三条
db.class0.find({},{_id:0}).skip(3)
count()
功能:对查找结果计数统计
e.g 统计sex为m的文档数量
db.class0.find({sex:'m'},{_id:0}).count()
sort({键:1/-1})
功能:对查找结果进行排序
1表示按照升序排列,-1表示按照降序排序
对查找结果按照年龄升序排列
db.class0.find({age:{$exists:true}},{_id:0}).sort({age:1})
复合排序:当第一排序项相同的时候,按照第二排序项排序
> db.class0.find({age:{$exists:true}},{_id:0}).sort({age:1,name:-1})
函数的连续使用
获取集合中年龄最小的三个文档
db.class0.find({age:{$exists:true}},{_id:0}).sort({age:1}).limit(3)
删除文档:
db.collectionNmae.remove(query,justOne)
功能:删除指定的文档
参数:query :筛选要删除的文档,类似where子句
用法同 查找操作
justOne:布尔值 默认为 false 表示删除所有筛选数据
如果赋值为true,则表示只删除第一条复合的文档
e.g
> db.class0.remove({$or:[{age:{$exists:false}},{age:{$gt:100}}]})
删除第一符合条件的文档:
> db.class0.remove({sex:{$exists:false}},true)
删除集合中所有文档
db.collectionName.remove({})
修改数据
update tableName set ....where ....
db.collectionName.update(query,update,upsert,multi)
功能:修改一个文档
参数:query:删选要修改的文档,相当于where子句,用法同查找
update:将数据更新为什么内容,相当于set操作符 需要使用修改器操作符
upsert:bool值,默认为false 表示如果query的文档不存在则无法修改
如果设置为true 表示如果query的文档不存在则根据query和update 参数插入新的文档
multi:bool值 默认值false 如果由多条符合筛选条件的文档只修改第一条
如果设置为true 则修改所有符合条件的文档
e.g 将阿红年龄改为24
> db.class0.update({name:'阿红'},{$set:{age:24}})
e.g如果筛选数据不存在则插入一个新的文档
> db.class0.update({name:'阿花'},{$set:{age:18,sex:'w'}},true)
e,g可以同时修改多条匹配到的文档
> db.class0.update({sex:'w'},{$set:{age:{$gt:20}}},false,true)
修改器操作符:
$set
修改一个域的值
增加一个域
e.g> db.class0.update({name:'阿红'},{$set:{sex:'w'}})
$unset
删除一个域
e.g 删除文档的sex和age域(后面数字习惯写1,0都表示删除)
> db.class0.update({name:'gg'},{$unset:{sex:0,age:0}})
$rename
修改一个域的名称
e.g 修改所有的sex域为gender
> db.calss0.update({},{$rename:{sex:'gender'}},false,true)
$setOnInsert
若夫哦update操作插入新的文档,则补充插入内容
$inc
加减修改器
e.g 年龄减2
> db.class0.update({age:{$lt:19}},{$inc:{age:-2}},false,true)
*$inc 可加整数 复数 小数都可以
$mul
乘法修改器
> db.class0.update({name:'阿华'},{$mul:{age:2}},false,true)
$min
设定的最小值:如果筛选的文档指定的域值小于min值则不修改,如果大于min值则改为min值
> db.class0.update({},{$min:{age:18}},false,true)
$max
设置最大值:如果筛选的文档指定值大于max值则不变,如果小于max值则修改为max值
> db.class0.update({},{$max:{age:20}},false,true)
数组修改器
$push 向数组中添加一项
> db.class1.update({name:'Abby'},{$push:{score:30}})
$pushAll 向数组中添加多项
> db.class1.update({name:'Jame'},{$pushAll:{score:[10,20]}})
$each 逐个操作
e.g 利用each添加多项
> db.class1.update({name:'Lily'},{$push:{score:{$each:[10,20]}}})
$position
选择数据位置进行操作 必须和each合用
$sort
对数组进行排序 必须和each合用
> db.class1.update({name:'Tom'},{$push:{score:{$each:[10,20],$sort:1}}})
$pull 从数组中删除一个元素
> db.class1.update({name:'Lily'},{$pull:{score:10}})
$pullAll 从数组中删除多个元素
e.g > db.class1.update({name:'Lucy'},{$pullAll:{score:[10,20]}})
$pop 弹出数组的一项
> db.class1.update({name:'Lily'},{$pop:{score:-1}})
*-1表示弹出数组中的第一项 1表示数组最后一项
$addToSet 向数组中插入一个元素,但是该元素不能和其他元素重复
e.g 如果已经存在66则无法插入,如果不存在则插入66
> db.class1.update({name:'Lily'},{$addToSet:{score:66}})
数据类型补充:
时间类型
mongo中存储时间的格式: ISODate
方法1 自动生成当前时间
> db.class2.insert({title:'Python入门',date:new Date()})
方法2 自动生成当前时间
> db.class2.insert({title:'Python精通',date:ISODate()})
方法3 将生成的时间变为字符串存储
> db.class2.insert({title:'Python AI',date: Date()})
指定时间的转换
ISODate()
功能:生成mongo时间类型
参数:如果不加参数则生成当前时间
参数格式 “2018-11-11 11:11:11”
“20180101 11:11:11”
e.g
null
1、如果某个域存在却没有值可以设置为null
> db.class2.insert({title:'Python墨迹',price:null})
2、如果摸个域不存在可以通过null进行匹配
> db.class2.find({date:null},{_id:0})
可以查找到date不存在的文档
Object类型(值是一个文档)
*当使用外层文档引用内部文档的时候可以用.的方法引用
在使用时需要加上引号
> db.class2.find({'publication.publisher':'机械工业'},{_id:0})
> db.class2.update({title:'Python数据'},{$set:{'publication.price':58.8}})
数组的下标引用
使用一个数组时,可以使用.下表的方式使用数组具体的某一项
同样需要用引号
> db.class1.update({name:'Lily'},{$set:{'score.0':60}})
> db.class1.find({'score.2':{$gt:90}},{_id:0})
文档查找结果的有序性
可以通过[]查找结果序列的某一项
> db.class1.find({},{_id:0})[1]
索引
指的是建立指定键值及所在文档中存储位置的对照清单。使用索引可以防病我们进行快速查找,减少遍历次数,提高查找效率
mongo中如何创建索引
ensureIndex()
功能:创建索引
参数:索引类别,索引选项
*1表示为该域创建正想索引,-1表示逆向索引
*_id域会自动创建索引
查看一个集合中的索引
db.class0.getIndexs()
删除索引
dropIndex()
功能:删除索引
参数:删除索引的名称
e.g 可以通过索引名称或者索引键值对删除
> db.class0.dropIndex('name_1')
> db.class0.dropIndex({name:1})
dropIndexes()
功能:删除所有索引
索引类型
复合索引
根据多个域创建一个索引
> db.class0.ensureIndex({'name':1,'age':1})
数组索引
如果对某个数组域创建索引,那么表示对数组中的每个值均创建了索引,通过数组中单个值查询,也是索引查询
> db.class1.ensureIndex({'score':1})
子文档索引
如果对一个域创建索引,值是一个文档则也会创建索引
如果对子文档一个域进行索引创建,则只有通过子文档中的该域查找为索引查找
> db.class2.ensureIndex({'publication.publisher':1})
覆盖索引
查找时只获取索引项的内容,而不必去获取元数据中的其他内容,这样就不去
e.g name为索引项,显示也只要name域
> db.class0.find({name:'Lily'},{_id:0,name:1})
唯一索引
创建索引时希望索引域的值均不相同,也可以据此限制一个域的值
> db.class0.ensureIndex({age:1},{'unique':true})
*当对某个域创建了唯一索引后,既不允许在插入相同的值的文档
稀疏索引(间隙索引)
只针对指定域的文档创建索引表,没有改域的文档,不会插入到索引表中
> db.calss2.ensureIndex({'date':1},{sparse:true})
索引约束:
1.影响数据的插入,删除,修改操作。当数据发生改变时,索引表必须同步更新
2.索引也是需要占用一定的空间资源
综上:当数据库大量的操作是插入,修改,删除操作,而非查询操作时,不适合创建索引。数据量比较小时,考虑到空间成本也不适合创建索引,即使适合创建索引的情况,也不是索引越多越好
聚合:
多数据文档进行整理统计
db.collectionName.aggregate()
功能:聚合函数,配合聚合条件进行数据整理统计
参数:聚合条件
聚合操作符
$group 分组 和分组操作符配合使用确定按什么分组
+++++++++++++++++++++++++++++
分组操作符(和$group)
$sum 求和
统计每组个数
> db.class0.aggregate({$group:{_id:'$sex',num:{$sum:1}}})
聚合 分组 按gender分组 统计结果名
统计每组年龄和
db.class0.aggregate({$group:{_id:'$sex',num:{$sum:'$age'}}})
$avg 求平均数
db.class0.aggregate({$group:{_id:'$sex',num:{$avg:'$age'}}})
$min 求最小值
db.class0.aggregate({$group:{_id:'$sex',num:{$min:'$age'}}})
$max
求每组姓名的最大值
db.class0.aggregate({$group:{_id:'$sex',num:{$max:'$age'}}})
++++++++++++++++++++++++++++++
第四天
修改
update(query,update,upsert,multi)
====================================================
固定集合
mongo中可以创建大小固定的集合,称之为固定集合,固定集合的性能出色,适用于很多场景
比如:日志处理,临时缓存
特点:插入速度快
顺序查询速度快
能够淘汰早期数据
可以控制集合空间
创建:
db.createCollection(collectionName,{capped:true,size:10000,max:1000})
size:设置固定集合的大小 kb
max: 最多能容纳多少文档
创建一个最多包含三条
> db.createCollection('log',{capped:true,size:10,max:3})
数据库存储文件的方式
1、在数据库中以字符串的方式存储文件在本地的路径
优点:节省数据库空间
缺点:当数据库或者文件位置发生变化既需要相应修改数据库内容
2、将文件以二进制数据的方式存放在数据库里
优点:文件存入数据库,数据库在,文件即不会丢失
缺点:当文件较大时,数据库空间占用大,提取困难
mongo中 GridFS 大文件存储
GridFS:是mongodb中大文件存储的一种方案,mongo中认为大于16M的文件为大文件
方案解释:
在mongodb创建两个集合 共同完成对文件的存储
fs.files:存储文件的相关信息,比如:文件名 文件类型
fs.chunks:实际存储文件内容,以二进制方式分块存储。将大文件分为多个小块,每块占一个空间,
mongofiles -d dbname put file
数据库 要存储的文件
*如果数据库不存在则自动创建
获取数据库中文件
mongofiles -d grid get xly.zip
优缺点:
优点:存储方便,方便数据库移植,方便数据库移植,对文件个数没有太多限制
缺点:读写效率低
游标
为什么使用游标
1、防止网络拥塞,造成数据传输慢
2、提高用户解析体验,可以后端解析
var cursor=db.class0.find() 创建游标
cursor.hasNext()查看是否有下一个值
cursor.next() 获取下一个数据源
通过Python操作mongodb数据库
Python----->mongodb编程接口 pymongo
安装
sudo pip3 install pymongo
操作步骤
1、创建mongo数据库的链接对象
conn=MongoClient('localhost',27017)
2、生成数据库对象
db=conn.stu
3、生成集合对象
my_set=db.class0
4、增删改查索引聚合操作
插入数据 insert() insert_many() insert_one() save()
删除数据 remove({},multi=True)
multi 默认为True 表示删除所有符合条件的数据
设置为False 表示只删除一条
数据查找
find()
功能:查找数据库内容
参数:同mongo sell find()
返回值:返回一个游标----->迭代器
cursor 可迭代对象属性
next()
count()
limit()
skip()
sort()
mongoshell----->sort({'name',1})
pymongo------->sort([('name',1)])
*进行排序时游标要确保没有访问过
find_one()
返回值是一个字典
修改操作
update()
参数和mongoshell中update相同
update_many():匹配到多个文档时全部修改
update_one():只修改匹配到的第一条文档
*编程中mongo的数据类型null可以用None
索引
ensure_index()
create_index()
create_indexes()创建多个索引
查看集合中的索引
list_indexes()
删除索引
drop_index() 删除某一个索引
drop_indexes() 删除所有索引
聚合操作
aggregate([])
参数:与mongoshell中聚合参数写法一致
返回值:迭代器 同find的返回值