一、基础概念

1.数据:

能被输入到计算机中并被识别处理的信息集合

2.数据结构:

研究一个数据集合中,数据元素关系

3.数据库:

按照数据结构,存储管理数据的仓库。数据仓库是在数据库管理系统管理控制下在一定介质中创建的。

4.数据库管理系统:

数据库管理软件,用于建立维护操作数据库

5.数据库系统:

由数据库和数据库管理系统等构成的数据开发工具集合。

二、关系型数据库&非关系型数据库

1.关系型数据库

(MySql)
采用关系模型(二维表)来组织数据结构的数据库
(1)常见关系型数据库:Oracle DB2 SQLserver MySQL SQlite
(2)优缺点
优点:逻辑清晰,容易理解,结构类似常见表格
使用SQL语句,技术成熟,使用方便
比较成熟,可以使用一些复杂的操作(联合查询,函数,引擎选择等)
缺点:每次操作都需要专门的SQL解析
结构严格,内部加锁
在应对海量数据并发处理时读写速度差

2.非关系型数据库

(NoSql—>not noly sql)
不采用关系型模型构建的数据库
(1)常见的非关系型数据库
键值型:Redis 列存储:HBase 文档型:MongoDB 图形:Graph
(2)优缺点
优点:读写数度快,更好的针对并发处理
使用灵活,容易扩展
缺点:没有SQL那样统一成熟的语句
技术成熟度较差,缺少一些复杂操作
(3)应用场景
①. 对数据格式要求不严格,比较灵活
②. 对数据处理数度,特别是海量数据的并发处理速度要求比较高
③. 特定场景:需要灵活扩展,需要作为缓存

三、MongoDB数据库

1.mongodb 特点

非关系型数据库,是属于文档型数据库
开源数据库,使用广泛
由c++编写的数据库关系系统
支持丰富的存储类型和数据操作
提供了丰富的编程语言接口
方便扩展和部署

2.mongodb 安装

Linux: sudo apt-get install mongodb
Mac Os: brew install mongodb
windows: www.mongodb.com
Linux 安装目录
默认安装位置: /var/lib/mongodb..
配置文件: /etc/mongodb.conf
命令集: /usr/bin

3.进入mongodb交互界面

名称:mongodb shell
命令:mongo
退出: quit() ctrl+c

4.设置mongodb的基本信息

mongodb 默认端口:27017
mongod -h 查看帮助
mongod —dbpath [dir] 设置数据库存储位置
mongod —port [port] 设置数据库端口

5.数据结构

1. 数据组织结构:

键值对—>文档—>集合—>数据库

2. 基本概念对比

mysql mongodb 含义
database database 数据库
table collection 表/集合
clumon field 字段/域
row document 记录/文档
index index 索引

6.数据库操作

【1】库操作

1)创建数据库:

use [库名]
e.g. 创建一个叫stu的数据库 use stu
use 实际是选择使用哪个数据库,当这个数据库不存在则自动建立
use创建数据库并不会立即建立起来,而是当真正插入数据时才会建立

2)查看数据库:

show dbs show databases

3)删除库:

db.dropDatabase() -删除当前使用的库

4)数据库命名规则:

使用utf-8字符串
不能含有 空格 . / \ ‘\0’字符
不能超过64字节长度
不要和系统库重名

5)全局变量db:

代表当前正在使用的数据库
不选择任何数据库时 db = test

6)数据库的备份和恢复命令

备份命令: mongodump -h [host] -d [db] -o[path]
e.g. 将本机 stu 备份在当前目录下
mongodump -h 127.0.0.1 -d stu -o .
恢复命令: mongorestore -h [host:port] -d [db] [bak]
e.g. 将stu备份 恢复到本机student 数据库中
mongorestore -h -127.0.0.1:27017 -d stundet stu

7)数据库运行监控

查看数据库的运行状态:mongostat
insert query update delete: 每秒增查改删次数
查看数据库集合读写时长:mongotop
得到每个集合在一秒内的读写时间

【2】集合操作

1)创建集合

db.createCollection(集合名)
db.集合名.insert({键值对})
插入数据时如果集合不存在则自动创建

2)查看集合:

show tables
show collections

3)删除集合

db.集合名.drop()

4)重命名集合

db.原集合名.renameCollcction(“新集合名”)

5)集合命名规则

使用utf-8字符
不能含有 “\0”
不要以 system.开头,这是系统集合默认开头
不要和关键字重名 e.g. insert db 等

【3】文档操作

1)什么是文档:

文档是mongodb数据库中最基本的数据组织单元
文档由键值对构成,每个键值对表达一个数据项
mongodb文档数据是bson类型数据
文档键值对特点:
键—>mysql—>字段
值—>mysql—>数据
无序的
通过键取其值
不能重复
键是utf-8字符串,不能有”\0”字符
值为bson支持数据类型,即存储的数据
数据类型:
整型:int -整数
浮点型:double -浮点型
布尔:boolean true false
字符串:string:utf-8字符串
ObjectId: id对象 自动生成的不重复值
mongodb 插入文档时,每个文档都要有一个_id域,可以自己指定一个不重复的值,也可以由系统自动生成

2)集合中的文档设计

(1) 一个集合中的文档可以有不同的域,域的个数也可以不一致。
(2) 集合中的文档层次不宜嵌套过多,如果层次过多时,应考虑分为多个集合
(3) 在集合中的文档应该尽量表达相同类型的数据内容

【4】数据操作

1)插入

db.集合名.insertOne(doc)
功能:插入一条文档
参数:要插入的文档
e.g. db.class0.insertOne({“name”:”lucy”,”age”:21})
操作数据时,键可以不加引号
可以自己设置_id值,但是不能重复
db.集合名.insertMany( [ { },{ },{ }… ] )
功能:插入多个文档
参数:数组[ ] —里面可以有多个文档
数组:使用[ ]表示的一组数据有序集合
特点:有序,使用序列号取值 (类似python中list)
db.集合名.insert( ) -以后可能就用不了
功能:插入一条或多条文档
参数:{},{},{}……
db.集合名.save( )
功能:插入一条或多条文档
参数:{},{},{}……
使用save如果_id重复会替换掉原有文档
db.getCollection(“集合名”) 获取集合对象

2)查找

mysql SELECT字段1,字段2… FROM table WHERE [条件语句]
mongo : db.集合名.find(query,field)
功能:查找所有符合条件的文档
参数:query 查找条件 —>mysql —> WHERE[条件语句]
field 要查找的域 —>mysql —> 字段1,字段2…
返回值:返回所有查找到的文档
db.collection.find()—>SELECT*FROM table
query:是一个键值对文档{},空则表示以所有键值对为筛选条件,往往配合查找 操作符完成
field:是一个键值对文档{},field:0表示不查找这个域 1表示查找这个域
_id域如果不想查找 _id:0 其他域设置要么全为0,要么全为1
db.findOne(query,field)
功能:查找第一个复合条件的文档
参数:同find
返回:返回查找到的文档

query操作符使用

http://www.mongodb.com—>learn—>documentation—>Search—>操作符

普通操作符:

mongodb中使用$符号注明的一个有特殊意义的字符串,用以表达丰富的含义
括号成对写,格式最重要
db.集合名.find( {域:{普通操作符:条件}} , field)
$eq :条件值 等于 ==:条件值
$lt :条件值 小于 <:条件值
$gt :条件值 大于 >:条件值
$lte :条件值 小于等于 <=:条件值
$gte:条件值 大于等于 >=:条件值
$ne :条件值 不等于 !=:条件值
db.集合名.find( {域:{$gt:条件值1,$lt:条件值2}} , field)
查找域的值在条件值1到条件值2之间的集合
$in:条件数组 包含 在这个 数组 范围内
$nin:条件数组 不包含 不在这个 数组 范围内

逻辑操作符:

db.集合名.find(
{逻辑操作符:[
{ 域 : {普通操作符:条件值} },
{ 域:{普通操作符:条件值} }
….
] },feild )

{$and:[…] } 与
query中的多个键条本身也表示并且的关系 {$and:[… , …] } 等同于 { 域 : {…,…} }
{$or:[…] } 或
{$not :[…] } 非
{$nor:[…] } 异或
既不也不(相同为真,不同为假)

数组操作符:

【1】 查找数组中包含元素
db.集合名.find(域:条件值})
域对应的值是一个数组,查找包含条件值的域
【2】$all 查找数组中同时包含多项
【3】$size 根据数组的元素个数查找
【4】$slice 用于field参数,表示查找数组哪些项
【5】“数组对应域 . index” 通过数组索引进行查找
其他操作符
【1】$exitsts 判断一个域是否存在
【2】$mod 根据除数余数筛选
【3】$type 根据数据类型筛选
{ field: { $type: [ , , … ] } }
数据类型与对应的数据查看type表

type Number Alias Notes
Double 1 “double”
String 2 “string”
Object 3 “object”
Array 4 “array”
Binary data 5 “binData”
Undefined 6 “undefined” Deprecated.
ObjectId 7 “objectId”
Boolean 8 “bool”
Date 9 “date”
Null 10 “null”
Regular Expression 11 “regex”
DBPointer 12 “dbPointer” Deprecated.
JavaScript 13 “javascript”
Symbol 14 “symbol” Deprecated.
JavaScript (with scope) 15 “javascriptWithScope”
32-bit integer 16 “int”
Timestamp 17 “timestamp”
64-bit integer 18 “long”
Decimal128 19 “decimal” New in version 3.4.
Min key -1 “minKey”
Max key 127 “maxKey”

查询处理函数:

db.集合名.distinct(field)
功能:获取集合中某个域的值范围
参数:域名
返回值:取值的范围 数组
pretty()
功能:将find( )结果格式化显示
limit(n)
功能:显示find( )结果的前n条
skip(n)
功能:跳过find( )前n条,显示后面的文档
count()
功能:统计find( )结果数量
sort({field:1/-1})
功能:对find( )结果排序
参数:field 表示排序的域,1升序,-1降序
函数连续调用
如果上一个函数返回的仍是一个文档集合,则可以继续调用下一个操作函数
通过序列号直接获取文档集合中某一个
find( )…..[n] 获取find( )结果文档集合第n+1项

3)修改

a. 格式对比

image.png

b. 修改函数

updateOne(query,update,upsert)
功能:修改第一个符合条件文档
参数:query 筛选条件 同find( )
update 要修改的数据,需要同修改操作符一同使用
upsert 如果query没有筛选到文档是否插入新文档
update 键值对文档,表达将数据修改为什么样子—>mysql—>set
updateMany(query,update,upsert)
功能:修改所有符合条件的文档
参数:同updateOne
update(query,update,upsert,multi)
功能:修改文档
参数:query update 用法同 updateOne
upsert upsert=true 表示查找不到文档则插入新文档
multi 默认只修改一个文档—>updateOne
multi=true 表示修改所有符合条件文档—>updateMany
findOneAndUpdate(query,update)
功能:查找到一个文档并修改
参数:query 查找条件
update 修改数据
返回值:原文档

findOneAndReplace(query,doc)
功能:查找一个文档并替换之
参数:query 查找条件
doc 新的文档
返回值:原文档

c.修改操作符(修改器)

【1】$set:修改一个域的值或者增加一个域
一个修改器可以同时修改多项
【2】$unset: 删除一个域
【3】$rename: 给域重命名
【4】$setOnInesrt: 如果使用update*执行了插入操作,则作为插入的内容
【5】$inc: 域的值 加 操作数
【6】$mul: 域的值 乘 操作数
$inc $mul 操作数可以是整数、小数、正数、负数
【7】$max: 修改某个域的值,如果小于指定值则改为指定值,大于则不变
【7】$min: 修改某个域的值,如果大于指定值则改为指定值,小于则不变

d.数组修改器

【1】$push: 向数组中添加一项
【2】$pushAll: 向数组中添加多项
【3】$pull: 从数组中删除某个值
【4】$pullAll: 同时删除数组中多个值
【5】$pop: 弹出数组中一项 只能弹出数组两端的元素 -1表示数组的第一项,1表示数组的最后一项
【6】$addToSet: 向数组中添加一项,但是不能和已有的数组重复
【7】$each: 对多个值逐一操作
【8】$postion: 指定数据插入位置 配合$each使用
【9】$sort: 给数组排序 配合$each使用
-1降序,1升序

4)删除

a. 格式对比

MongoDB - 图2MongoDB - 图3MongoDB - 图4mysql: DELETE FROM table WHERE…
mongo: db.collection.deleteOne(query)

b. 删除函数

db.集合名deleteOne(query)
功能:删除第一个符合条件的文档
参数:查找条件
db.集合名.deleteMany(qury)
功能:删除所有符合条件的文件
参数:查找条件
db.集合名.remove(query,justOne)
功能:删除文档
参数:query 筛选条件
justOne 默认删除所有,justOne=>true 只删除第一个符合条件的文档
db.集合名.findOneAndDelete(query)
功能;查找一个文档并删除
参数:查找条件
返回值:返回查找到的文档

【5】索引操作

1)什么是索引:

索引是建立文档所在位置的查找清单,使用索引可以方便快速查找,减少遍历次数,提高查找效率。

2)索引约束:

数据量很小时不需要创建索引
创建索引会增加ipan的使用空间
对数据库操作大多是写操作而不是读操作时不宜创建索引

3)创建索引:

db.集合名.createIndex( {feild:1 or -1},name)
功能:创建索引
参数:feild索引域和索引选项 {feild:1} , {feild:-1} ,
name {name:”索引名称”} 不传默认为:域名_1
_id域会由系统自动生成索引 1表示正向索引,-1表示逆向索引
ensureIndex( )
功能:创建
db.集合名.createIndex( [{:},{:},{:}…])
功能:创建多个索引

4)查看索引:

db.集合名.getIndexes( )
功能:查看集合中的索引

5)删除索引:

db.集合名.dropIndex(index or name)
功能:删除一个索引
参数:索引名称或者键值对
db.集合名.dropIndexes( )
功能:删除所有索引
_id索引不会被删除

6)其他索引:

【1】复合索引:根据多个域创建一个索引
db.集合名.createIndex({域1:1 or-1},{域2:1 or-1})

【2】object/数组索引:如果对object域或者数组创建索引,则针对object或者数组中某一个元素的查询也是索引查询
【3】唯一索引:要求创建索引的域不能有重复的值
db.集合名.createIndex({域:1 or -1},{unque:true})
【4】稀疏引:如果创建稀疏索引则对没有索引域的文档会忽略
db.集合名.createIndex({域:1 or -1},{sparse:true})
db.集合名.createIndex({域:1 or -1},{unque:true,sparse:true,name:索引名})

【6】聚合操作

1)什么是聚合:对文档进行数据整理统计,得到统计结果
2)聚合函数
db.集合名.aggregete(aggr)
功能:执行聚合操作
参数:聚合条件,配合聚合操作符使用
3)一些聚合操作符
$group 分组聚合 需要配合统计操作符
统计求和:$sum
求平均数:$avg
求最大/最小值:$max/$min
求第一个值/最后一个值:$first/$last
$natch: 筛选操作 操作值的写法基本同query参数
$limit: 获取集合中前几条文档
$skip: 跳过前几个文档
$sort: 对文档排序
4)聚合管道
db.集合名.aggregate( [ { : } , { : } , { : }… ] )
从左至右依次执行聚合操作,把前一个的聚合结果交给下一个聚合操作

7.一些数据类型

(1)时间类型

1)获取当前时间
new Date( ) 自动生成当前ISO时间
Date( ) 获取计算机当前时间生成字符串
2)时间函数
ISOdate( )
功能:将制定时间转换为标准时间存入
参数:默认 同new Date( ) 获取当前时间或者字符串定制时间
3)时间戳
标准时间.valueOf( )
功能:将标准时间转化为时间戳

(2)null类型

1)值:null
2)含义:表示某个域的值为空 查找时会找到域为null或者没有这个域的文档

(3)Object类型(内部文档)

1)定义:文档中某个域的值为内部文档,则该值为object类型数据
2)使用方法:当使用内部文档某个域的值时,需要采用{“外部域 . 内部域”:条件值}的方法,此时该域需要用引号表示为字符串

四、拓展

常用命令

  1. # 查询重复数据
  2. db.Collection.aggregate([
  3. {
  4. $group: { _id: '$externalno',count: {$sum: 1}}
  5. },
  6. {
  7. $match: {count: {$gt: 1}}
  8. }
  9. ])
  10. # 删除重复数据
  11. db.Collection.aggregate([
  12. {
  13. $group: { _id: '$externalno',count: {$sum: 1},dups: {$addToSet: '$_id'}}
  14. },
  15. {
  16. $match: {count: {$gt: 1}}
  17. }
  18. ]).forEach(function(doc){
  19. doc.dups.shift();
  20. db.house.remove({_id: {$in: doc.dups}});
  21. })
  22. # 重命名域名
  23. db.Collection.updateMany(
  24. {},
  25. {
  26. "$rename":{"old":"new"}
  27. }
  28. )
  29. # 添加新字段并赋值
  30. db.Collection.updateMany({}, {$set: {新字段名称: 默认值}}, false, true)
  31. # 找到不存在该字段的并赋值
  32. db.Collection.updateMany({direction:{$exists:false}}, {$set: {direction: 'default'}})
  33. 查找替换
  34. db.Collection.find({'litpic':{'$regex': /house/ }}).forEach(
  35. function(item) {
  36. var tmp = String(item.litpic)
  37. tmp = tmp.replace('house','house/')
  38. if (tmp == null){
  39. print(item.litpic)
  40. }
  41. item.litpic = tmp ;
  42. db.loupan.save(item);
  43. }
  44. );
  45. # 查找长度大于限定值的字段
  46. db.Collection.find({
  47. title: {
  48. $type:2, // 字段类型为2,表示有此字段,或者用: $exists: true
  49. $regex: /^.{600,}$/ // 长度大于600
  50. }
  51. });
  52. # 查找长度小于限定值的字段
  53. db.Collection.find({
  54. title: {
  55. $exists:true, // 字段类型为2,表示有此字段,或者用: $exists: true
  56. $regex: /^.{0,600}$/ // 长度大于600
  57. }
  58. })
  59. # 找到字段小于2的字符串后面添加字符串
  60. db.Collection.find({title:{$regex:/^.{0,2}$/}}).forEach(
  61. function(item){
  62. db.community.update({"_id":item._id},{$set:{"title":item.title+"string"}})
  63. }
  64. )