MogoDB
关系型数据
Oracle\DB2\SQLServer\MySql\SqLite(python 标准库支持)
优点:1、容易理解,类似常见的表格;
2、使用方便,都是使用sql语句,sql语句非常成熟
3、数据一致性高,冗余度低,完整性好
4、技术成熟,可以用于外部链接等比较复杂的操作
缺点:1、不能很好满足高并发需求,每次都需要进行sql语句的解析;
2、针对海量数据的瞬间爆发读写性能不足;
3、关系型数据库内部每步操作都需要加锁保证操作的原子性;
4、数据扩展普遍比非关系型困难
5、数据一致性高,有时候会浪费大量空间
非关系型数据库(也叫Nosq,即Not only Sql)
优点:1、高并发,大数据读写能力强;
2、支持分布式,容易扩展;
3、弱化了数据结构,降低了数据的一致性,节省空间;
缺点:1、通用性差,没有像sql那样一致的操作
2、操作灵活,容易混乱
3、没有join、数据库事务支持等操作
Nosql的适用情况:
1、对数据一致性要求低
2、数据库并发处理要求高
3、数据库设计时对数据库空间大小估算不确定,需要分布拓展
4、给定的数据比较容易建立起Nosql的模型
Nosql分类;
1、键值型数据库
Redis\oracle\DBD\Tokyo
2、列存储数据库
HBase
3、文档型数据库
MongoDB\CouchDB
4、图形数据库
MongoDB
1、由c++编写的数据库管理系统
2、支持非常丰富的数据操作(增删改查)
3、支持非常丰富的数据类型
4、使用方便,便于部署,支持分布,容易拓展
5、支持众多的编程语言接口(python ruby c++ c# PHP)
安装:
sudo apt-get install mongodb
默认安装位置 /var/lib/mongodb
配置文件 /etc/mongodb.conf
命令集 /usr/bin /usr/local/bin
手动安装:
1、下载MongoDB
2、选择安装目录解压
tar解压后得到MongoDB文件夹
3、将文件夹下的命令集目录(bin目录)添加到环境变量
PATH=$PATH:/opt/mongo..../bin
export PATH
将以上两句写在/etc/rc.local
4、重启
设置数据库存储位置:
mongod --dbpath 目录
设置端口号:
mongod --port 8888
*如果不设置则使用默认端口号 27017
输入mongo进入mongodb的交互界面来操作数据库
退出:quit()
组成结构:键值对》
文档》
集合》
数据库
创建数据库
use databasename
例如:
创建一个叫st的数据库
use st
*use实际功能是表示选择使用哪个数据库,当这个数据库不存在时,即表示创建该数据库
*使用use后数据库并不会马上被创建,而是需要插入数据后,数据库才会创建。
查看数据库
show dbs
数据库名称规则
1、原则上是任意满足以下几个条的utf-8字符
2、不能是空字符,不能含有空格、“.”、‘\’、“/”、“\0”(是C语言中的特殊含义)
3、习惯上使用英文小写
4、长度不超过64个字节
5、不能使用admin 、local、config这样的名字
admin:存储用户
local:存储本地数据
config:存储分片配置信息
db:mongo系统全局变量 代表你当前正在使用的数据库
db 默认为test 如果插入数据即创建test数据库
数据库的备份和恢复:
备份:mongodump -h dbhost -d dbname -o dbdir
例子:mongodump -h 127.0.0.1 -d stu -o student
将本机下stu数据库备份到当前目录的student文件夹中,会在student文件夹中自动生成一个stu文件夹,里面则为备份文件。
恢复:mongorestore -h <dbhost>:<port> -d dbname <path>
例子: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 使用虚拟内存和物理内存
mongtotop:
监测每个数据库的读写时长
删除数据库
db.dropDatabase()
删除db所代表的数据库
集合的创建
db.createCollection(collection_name)
例如:db.createCollection("class2")
在当前数据库下创建一个名字为class2的集合
查看数据库中的集合
show tables
show collections
集合的命名规则:
1、不能为空字符串,不能有'\0'
2、不能以system.开头,这是系统集合的保留前缀
3、不能和保留字重复
当你向一个集合中插入文档时,如果该集合不存在,则自动创建集合
db.collectionName.insert()
例如;
db.class0.insert({a:1})
如果class0不存在,则会创建class0集合并插入给数据
删除集合
db.collectionName.drop()
例如:
db.class0.drop()
集合重命名
db.collectionName.renameCollection("newname")
例如:
db.class2.renameCollection("class0")
将class2重命名为class0
文档
mongodb 中文档的组织形式
-----mongodb中文档的数据组织形式为bson格式,类似python的字典,也是由键值对构成的
文档中键的命名规则;
1、utf-8格式字符串
2、不能有\0,习惯上不使用“.”和“$”
3、以"_"开头的多为保留键,自定义时一般不以_开头
*注意:文档键值对是有序的;
mongo中严格区分大小写;
值:mongodb的支持数据类型
objectId objectId字串
ObjetId:系统自动为每个文档生产的不重复的主键
键名称:_id
值:objectId("23bksdlcksdfeokd834")(24位16进制)
集合中文档特点;
1、集合中的文档域不一定相同,不保证数据一致性
2、集合中的文档中结构不一定相同
集合的设计原则:
1、集合中文档尽可能描述的数据类似;
2、同一类文档放在相同的集合,不同的文档分集合存放
3、层次的包裹不宜太多
插入文档
db.collectionName.insert()
例:
db.class0.insert({name:'lucy','age':16,'sex':'w'})
*当为文档插入时,键可以不加引号
查看插入结果,db.class0.find()
插入多条文档
db.collectionName.insert([{},{},{}])
例:
db.class0.insert([{name:'小话',age:29},{name:'小名',age:23},{name:'系吗',age:88}])
*_id为系统自动添加主键,如果自己写_id域,则会使用自己写的值。但是该值仍不允许重复
save 插入数据
db.collectionName.save()
db.class0.save({_id:01,name:'lu',age:199})
*在不加_id时,使用同insert
*如果使用save插入的时候加_id,则如果_id值不存在,则正常插入
如果该值存在,则修改原来内容
*save无法一次插入多个文档
获取集合对象:
db.getCollection('collection_name').insert()
db.getCollection("class0").insert({name:'monky',age:90})
查找操作:
find(query,field)
功能:查找所有符合条件的文档
参数:query:筛选条件 相当于where子句
field:展示的域 相当于select的展示部分
返回:返回所有查找的内容
field参数;选择要展示的域 传一组键值对
键表示域名
值表示是否显示该域 0表示不显示
1表示显示
*如果某个域给定0,则表示不显示该域,其他的域均显示
如果某个域给定1,则表示显示该域,其他的域都不显示
*_id 永远默认为显示,除非设置为0
*除_id外其他域,必须拥有相同的设置,全为0或全为1
query:以键值对的形式给出查找条件
例如:
查找年龄为88
db.class0.find({age:88},{_id:0})
*如果不写第一个参数,则表示查找所有内容
findOne()
功能参数与find()完全相同,只是返回第一个条查找到的文档
query的更多用法
操作符:
使用$符号注明一个特殊字符串,表示一定的含义
$eq 等于
例如:db.class0.find({age:{$eq:88}},{_id:0})
$lt 小于
$lte 小于等于
db.class0.find({age:{$lt:88}},{_id:0})
$gt 大于
$gte 大于等于
db.class0.find({age:{$gt:88}},{_id:0})
$ne 不等于
*如果一个文档没有域,怎显示不等于
$in 包含
> db.class0.find({age:{$in:[15,16,88]}},{_id:0,})
{ "name" : "lily", "age" : 15, "sex" : "w" }
{ "name" : "lucy", "age" : 16, "sex" : "w" }
{ "name" : "系吗", "age" : 88 }
{ "name" : "系吗", "age" : 88 }
$nin不包含
> db.class0.find({age:{$nin:[15,16,88]}},{_id:0,})
{ "name" : "小话", "age" : 29 }
{ "name" : "小名", "age" : 23 }
{ "name" : "小话", "age" : 29 }
{ "name" : "小名", "age" : 23 }
{ "name" : "lu", "age" : 199 }
{ "name" : "monky", "age" : 90 }
逻辑与操作:
$and
年龄小于29,并且性别为男
> db.class0.find({age:{$lt:29},sex:'w'},{_id:0})
{ "name" : "lily", "age" : 15, "sex" : "w" }
{ "name" : "lucy", "age" : 16, "sex" : "w" }
年龄大于15,并且小于29的
> db.class0.find({age:{$lt:29,$gt:15}},{_id:0})
{ "name" : "lucy", "age" : 16, "sex" : "w" }
{ "name" : "小名", "age" : 23 }
{ "name" : "小名", "age" : 23 }
$or
年龄小于23,或者名字是“小名”
> db.class0.find({$or:[{age:{$lt:23}},{name:'小名'}]},{_id:0})
{ "name" : "lily", "age" : 15, "sex" : "w" }
{ "name" : "lucy", "age" : 16, "sex" : "w" }
{ "name" : "小名", "age" : 23 }
{ "name" : "小名", "age" : 23 }
$not 逻辑非
年龄不等于88
> db.class0.find({age:{$not:{$eq:88}}},{_id:0})
{ "name" : "lily", "age" : 15, "sex" : "w" }
{ "name" : "lucy", "age" : 16, "sex" : "w" }
{ "name" : "小话", "age" : 29 }
{ "name" : "小名", "age" : 23 }
{ "name" : "小话", "age" : 29 }
{ "name" : "小名", "age" : 23 }
{ "name" : "lu", "age" : 199 }
{ "name" : "monky", "age" : 90 }
$nor 既不也不
年龄既不大于23,性别也不等于‘m’
> db.class0.find({$nor:[{age:{$gt:23}},{sex:'m'}]},{_id:0})
{ "name" : "lily", "age" : 15, "sex" : "w" }
{ "name" : "lucy", "age" : 16, "sex" : "w" }
{ "name" : "小名", "age" : 23 }
{ "name" : "小名", "age" : 23 }
(年龄小于23或者 姓名是小名) 并且性别为女的人
> db.class0.find({$and:[{$or:[{age:{$lt:23}},{name:'小名'}]},{sex:'w'}]},{_id:0})
{ "name" : "lily", "age" : 15, "sex" : "w" }
{ "name" : "lucy", "age" : 16, "sex" : "w" }
>
数组查找:
查看数组中包含某一项的
> db.class1.find({hobby:'吃饭'})
{ "_id" : ObjectId("5d2ed0c9226651eee5c79df3"), "name" : "刘英", "age" : 35, "hobby" : [ "吃饭", "睡觉", "打豆豆" ] }
{ "_id" : ObjectId("5d2ed0f8226651eee5c79df4"), "name" : "赵四", "age" : 56, "hobby" : [ "吃饭", "睡觉", "看戏" ] }
$all
查找一个数组中,同时包含多项的文档
查看hobby数组中,即吃饭又看戏的文档
>db.class1.find({hobby:{$all:['吃饭','看戏']}},{_id:0})
{ "name" : "赵四", "age" : 56, "hobby" : [ "吃饭", "睡觉", "看戏" ] }
$size
查找数组元素个数为指定个数的文档
查看hobby中有2个的文档
> db.class1.find({hobby:{$size:2}},{_id:0})
{ "name" : "广坤", "age" : 55, "hobby" : [ "二人转", "喝酒" ] }
>
数组 切片显示
$slice
对数组切片显示
显示hobby数组的前2项
> db.class1.find({hobby:{$size:3}},{_id:0,hobby:{$slice:2}})
{ "name" : "刘英", "age" : 35, "hobby" : [ "吃饭", "睡觉" ] }
{ "name" : "赵四", "age" : 56, "hobby" : [ "吃饭", "睡觉" ] }
{ "name" : "刘能", "age" : 55, "hobby" : [ "喝酒", "打飞机" ] }
> db.class1.find({hobby:{$size:3}},{_id:0,hobby:{$slice:[1,2]}})
{ "name" : "刘英", "age" : 35, "hobby" : [ "睡觉", "打豆豆" ] }
{ "name" : "赵四", "age" : 56, "hobby" : [ "睡觉", "看戏" ] }
{ "name" : "刘能", "age" : 55, "hobby" : [ "打飞机", "看戏" ] }
>