NoSQL
简介
NoSQL
介绍
NoSQL
全名为Not Only SQL
, 指的是非关系型数据库, 在现代的计算系统上每天网络上都会产生庞大的数据量, 网站的数据库性能可能出现问题, NoSQL
便应运而生了
NoSQL
是一项全新的数据库革命性运动, 提倡运用非关系型的数据存储
NoSQL
用于超大规模数据的存储, 这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展
NoSQL
的优点: 高扩展性、分布式计算、低成本、构架灵活
NoSQL
的缺点: 没有标准化、有限的查询功能
NoSQL
数据库分类
类型 |
部分代表 |
特点 |
列存储 |
Hbase 和 Cassandra 和 Hypertable |
顾名思义,是按列存储数据的。最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,对针对某一列或者某几列的查询有非常大的IO优势。 |
文档存储 |
MongoDB 和 CouchDB |
文档存储一般用类似json的格式存储,存储的内容是文档型的。这样也就有有机会对某些字段建立索引,实现关系数据库的某些功能 |
key-value 存储 |
Tokyo Cabinet/Tyrant 和 Berkeley DB 和 MemcacheDB 和 Redis |
可以通过key 快速查询到其value 。一般来说,存储不管value 的格式,照单全收。(Redis 包含了其他功能) |
图存储 |
Neo4J 和 FlockDB |
图形关系的最佳存储。使用传统关系数据库来解决的话性能低下,而且设计使用不方便 |
对象存储 |
db4o 和 Versant |
通过类似面向对象语言的语法操作数据库,通过对象的方式存取数据 |
xml数据库 |
Berkeley DB XML 和 BaseX |
高效的存储XML 数据,并支持XML 的内部查询语法,比如XQuery , Xpath |
这里主要介绍`MongoDB`和`Redis`的相关介绍和使用
什么是MongoDB
MongoDB
介绍
MongoDB
是由C++
编写的, 是一个基于分布式文件存储的开源数据库系统
MongoDB
旨在为WEB
应用提供可扩展的高性能数据存储解决方案
MongoDB
将数据库存储为一个文档, 数据结构由键值对组成
MongoDB
文档类似于JSON
对象, 字段值可以包含其他文档, 数组以及文档数组
MongoDB
主要特点
MongoDB
提供了一个面向文档存储, 基本思路就是将原来的行概念换成更加灵活地文档模型, 一条记录可以表示非常复杂的层次关系
MongoDB
支持丰富的查询表达式, 查询指令使用json
形式的标记, 可轻易查询文档中内嵌的对象及数组
MongoDB
支持RUBY
、Python
、Java
、C++
、PHP
、C#
等多种编程语言
MongoDB
包含索引、存储JavaScript
、聚合、固定集合、文件存储等操作
MongoDB
的安装
- 这里提到的都是在
Mac
环境下MongoDB
的安装过程, 其他环境下请自行百度, 这里就不在介绍了
- 安装方式有两种安装包安装和使用
brew
安装, 我是使用安装包安装的, 为了不误导大家, 这里就不介绍brew
安装方式了
安装包安装
可以在官网下载安装包: 下载地址
接下来我们使用如下命令来下载安装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
cd /usr/local
sudo curl -O https://fastdl.mongodb.org/osx/mongodb-osx-x86_64-4.0.0.tgz
sudo tar -zxvf mongodb-osx-x86_64-4.0.0.tgz
sudo mv mongodb-osx-x86_64-4.0.0 mongodb
export PATH=/usr/local/mongodb/bin:$PATH
|
运行MongoDB
- 首先我们创建一个数据库存储目录
/data/db
- 启动
mongodb
,默认数据库目录即为 /data/db
1 2 3 4 5
| sudo mongod
# 如果没有创建全局路径 PATH,需要进入以下目录 cd /usr/local/mongodb/bin sudo ./mongod
|
打开浏览器, 在浏览器内输入`127.0.0.1:27017`, 如果出现下面这种则说明安装成功
- 再打开一个终端进入执行以下命令:
1 2
| $ cd /usr/local/mongodb/bin $ ./mongo
|
安装可视化工具Studio 3T
- 这里推荐官网下载: 下载地址
- 安装之后打开软件, 选择左上角
Connection
, 弹出一个新的弹窗
- 在点击新弹窗上面的
New Connection
, 弹出一个新的弹窗
- 在新窗口中输入名字和电脑IP, 点击
Save
- 最后选择你新添加的电脑IP, 点击
Connect
链接
- 详细步骤如下图所示:
MongoDB
基本命令操作
操作mongodb数据库
创建数据库
- 如果数据库不存在则创建数据库,否则切换到指定的数据库
- 如果刚刚创建的数据库不在列表内,如果要显示它,我们需要向刚刚创建的数据库中插入一些数据
1 2
| db.student.insert({name:"titan", age:18, sex:1,address:"北京", isDelete:0})
|
其他相关命令
1 2 3 4 5 6 7 8 9 10 11 12 13
| db.dropDatabase()
show dbs
db db.getName()
exit
help
|
集合操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| show collections
db.createCollection("class") db.student.insert({name:"titan1", age:18, sex:1,address:"上海", isDelete:0})
db.class.drop()
|
文档操作
插入文档
- 使用
insert()
方法插入文档
1 2 3 4 5 6 7 8 9 10 11
| db.集合名.insert(文档) db.student.insert({name:"jun", age:19, sex:1,address:"北京", isDelete:0})
db.集合名.insert([文档1, 文档2, ……, 文档n]) db.student.insert([{name:"titan2", age:17, sex:0,address:"深圳", isDelete:0},{name:"coder", age:20, sex:0,address:"上海", isDelete:0}])
|
- 使用
save()
方法插入文档
- 语法:
db.集合名.save(文档)
- 说明:如果不指定
_id
字段,save()
方法类似于insert()
方法。如果指定_id
字段,则会更新_id
字段的数据
1 2 3 4 5
| db.student.save({name:"pro", age:22, sex:1,address:"安徽", isDelete:0})
db.student.save({_id:ObjectId("59950962019723fe2a0d8d17"),name:"poi", age:23, sex:1,address:"安徽", isDelete:0})
|
文档更新
1、update()
方法用于更新已存在的文档
1 2 3 4 5 6 7 8 9
| db.集合名.update( query, update, { upset:<boolean>, multi:<boolean>, writeConcern:<document> } )
|
- 参数说明:
query
:update
的查询条件,类似于sql
里update
语句内where
后面的内容
update
:update
的对象和一些更新的操作符($set,$inc)
等,$set
直接更新,$inc
在原有的基础上累加后更新
upset
:可选,如果不存在update
的记录,是否当新数据插入,true
为插入,False
为不插入,默认为false
multi
:可选,mongodb
默认是false
,只更新找到的第一条记录,如果这个参数为true
,就按照条件查找出来的数据全部更新
writeConcern
:可选,抛出异常的级别
- 需求:将
pro
的年龄更新为25
- 示例:
1 2 3 4 5 6 7
| db.student.update({name:"pro"},{$set:{age:25}})
db.student.update({name:"titan"},{$inc:{age:25}})
db.student.update({name:"titan1"},{$set:{age:42}},{multi:true})
|
2、save()
方法通过传入的文档替换已有文档
1 2 3 4 5 6 7 8
| db.集合名.save( document, { writeConcern:<document> } )
|
文档删除
在执行remove()
函数前,最好先执行find()
命令来判断执行的条件是否存在
1 2 3 4 5 6 7
| db.集合名.remove( query, { justOne:<boolean>, writeConcern:<document> } )
|
- 参数说明:
query
:可选,删除的文档的条件
justOne
:可选,如果为true或1,则只删除一个文档
writeConcern
:可选,抛出异常的级别
- 示例:
1 2
| db.student.remove({name:"poi"})
|
文档查询
1、find()
方法查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| db.集合名.find( query, { <key>:1, <key>:1 } )
db.student.find({sex:0},{name:1,age:1}) db.student.find({},{name:1,age:1})
|
2、其他查询方法
1 2 3 4 5 6 7 8
| db.student.find()
db.student.find().pretty()
db.student.findOne({gender:0})
|
查询条件操作符
条件操作符用于比较两个表达式并从Mongodb
集合中获取数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| db.集合名.find({<key>:{$gt:<value>}}) db.student.find({age:{$gt:20}})
db.集合名.find({<key>:{$gte:<value>}})
db.集合名.find({<key>:{$lt:<value>}})
db.集合名.find({<key>:{$lte:<value>}})
db.集合名.find({<key>:{$gte:<value>,$lte:<value>}})
db.集合名.find({<key>:<value>})
db.student.find({"_id":ObjectId("id值")}) db.student.find({"_id":ObjectId("5995084b019723fe2a0d8d14")})
db.student.find().count()
db.student.find({name:/ile/})
db.student.find({name:/^li/})
|
条件查询and
和or
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| db.集合名.find({条件1,条件2,……,条件n}) db.student.find({gender:0,age:{$gt:16}})
db.集合名.find( { $or:[{条件1},{条件2},……,{条件n}] } ) db.student.find({$or:[{age:17},{age:{$gte:20}}]})
db.集合名.find( { 条件1, 条件2, $or:[{条件3},{条件4}] } )
|
limit
和skip
1 2 3 4 5 6 7 8 9 10 11
| db.student.find().limit(3)
db.student.find().skip(3)
db.student.find().skip(3).limit(3)
|
排序
1 2 3 4 5
| db.集合名.find().sort({<key>:1|-1})
db.student.find().sort({age:1})
|
MongoDB
和Python
的交互
MongoDB
数据类型
下表为MongoDB
中常用的几种数据类型
数据类型 |
描述 |
String |
字符串。存储数据常用的数据类型。在MongoDB 中,UTF-8 编码的字符串才是合法的 |
Integer |
整型数值。用于存储数值, 根据你所采用的服务器,可分为32位或64位 |
Boolean |
布尔值。用于存储布尔值(真/假) |
Double |
双精度浮点值。用于存储浮点值。 |
Min/Max keys |
将一个值与BSON (二进制的 JSON)元素的最低值和最高值相对比 |
Array |
用于将数组或列表或多个值存储为一个键。 |
Timestamp |
时间戳。记录文档修改或添加的具体时间。 |
Object |
用于内嵌文档。 |
Null |
用于创建空值。 |
Symbol |
符号。该数据类型基本上等同于字符串类型,但不同的是,它一般用于采用特殊符号类型的语言。 |
Date |
日期时间。用UNIX 时间格式来存储当前日期或时间, 你可以指定自己的日期时间:创建Date 对象,传入年月日信息。 |
Object ID |
对象 ID。用于创建文档的 ID。 |
Binary Data |
二进制数据。用于存储二进制数据。 |
Code |
代码类型。用于在文档中存储JavaScript 代码。 |
Regular expression |
正则表达式类型。用于存储正则表达式。 |
ObjectId
ObjectId
类似唯一主键,可以很快的去生成和排序,包含12 bytes
,含义是:
- 前 4 个字节表示创建 unix 时间戳,格林尼治时间 UTC 时间,比北京时间晚了 8 个小时
- 接下来的 3 个字节是机器标识码
- 紧接的两个字节由进程 id 组成 PID
- 最后三个字节是随机数
MongoDB
中存储的文档必须有一个_id
键, 这个键的值可以是任何类型的,默认是个ObjectId
对象
插入数据
集合中插入文档使用insert_one()
方法和insert_many()
方法
插入一条数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| from pymongo import MongoClient
conn = MongoClient("localhost", 27017)
db = conn.mydb
collection = db.student
try: one = collection.insert_one({"name": "coder19", "age": 19, "gender": 1, "address": "北京", "isDelete": 0}) print(one)
print(one.inserted_id)
print('添加成功') except: print('添加失败')
conn.close()
|
insert_one()
方法返回InsertOneResult
对象,改对象包含inserted_id
属性,它是插入文档的id
值
1 2 3 4 5 6 7 8 9 10
| one = collection.insert_one({"name": "coder19", "age": 19, "gender": 1, "address": "北京", "isDelete": 0}) print(one)
print(one.inserted_id)
|
插入多个文档
insert_many()
方法返回InsertManyResult
对象,该对象包含 inserted_ids
属性,该属性保存着所有插入文档的id
值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| try: mylist = [ {'name': '个人博客', 'age': 10, 'address': 'https://www.titanjun.top'}, {'name': 'Github', 'age': 11, 'address': 'https://github.com/CoderTitan'} ] many = collection.insert_many(mylist)
print(many) print(many.inserted_ids)
print('添加成功') except: print('添加失败')
|
插入指定_id
的多个文档
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| mylist = [ {'_id': 1, 'name': '简书', 'age': 12, 'address': 'https://www.jianshu.com/u/5bd5e9ed569e'}, {'_id': 2, 'name': 'csdn', 'age': 13, 'address': 'https://blog.csdn.net/shmilycoder'}, {'_id': 3, 'name': '掘金', 'age': 14, 'address': 'https://juejin.im/user/5a7a64ae6fb9a0636323fd06'}, ] many = collection.insert_many(mylist)
print(many) print(many.inserted_ids)
|
查询数据
返回所有/第一条数据
1 2 3 4 5
| print(collection.find_one())
print(collection.find())
|
根据id查询指定数据
1 2 3 4 5 6 7 8 9 10 11 12
| res3 = collection.find({'_id': ObjectId('5b52cdbbd87e53d6306f3585')}) print(res3)
res12 = collection.find_one({'_id': ObjectId('5b52cdbbd87e53d6306f3585')}) print(res12)
|
根据指定条件查询
查询集合中所有符合key
为value
的所有的数据
1 2 3
| res10 = collection.find({'age': 19}) for row in res10: print(row)
|
指定条件查询
1 2 3 4 5 6 7 8 9 10 11 12
| res2 = collection.find({'age': {'$gt': 19}})
res2 = collection.count_documents({'age': {'$gt': 19}})
res2 = collection.count_documents({'age': {'$gt': 19}, 'gender': 0})
res11 = collection.find({'name': {'$regex': '^c'}})
|
返回指定条数记录
如果我们要对查询结果设置指定条数的记录可以使用limit()
方法,该方法只接受一个数字参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| res5 = collection.find()limit(3)
res12 = collection.find({'age': {'$gt': 19}})
res13 = collection.find({'age': {'$gt': 19}}).skip(2)
res5 = collection.find().skip(3).limit(3)
|
修改文档
- 在
MongoDB
中使用update_one()
和update_many()
方法修改文档中的记录, 第一个参数为查询的条件,第二个参数为要修改的字段
- 在
update_one()
方法中, 如果查找到的匹配数据多余一条,则只会修改第一条
- 在
update_many()
方法中, 会修改所有符合条件的数据
1 2 3 4 5
| collection.update_one({'name': 'coder1'}, {'$set': {'age': 80}})
collection.update_many({'name': 'coder2'}, {'$set': {'age': 90}})
|
除了`update`方法之外还有一个`replace`方法, 两者的区别是
update
只会修改key
值对应的value
值, 对其他的value
值不做修改
replace
方法是除id
不变, 其他值都会改变, 若未指定新值, 则赋值为空
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| print('修改前') print(collection.find_one({'name': 'coder1'})) print(collection.find_one({'name': 'coder19'}))
collection.update_one({'name': 'coder1'}, {'$set': {'age': 80}})
collection.replace_one({'name': 'coder19'}, {'age': 90, 'name': 'coder19'})
print('修改后') print(collection.find_one({'name': 'coder1'})) print(collection.find_one({'name': 'coder19'}))
|
删除文档
- 我们可以使用
delete_one()
和delete_many()
方法来删除, 参数为查询对象,指定要删除哪些数据
delete_one()
: 删除符合条件的第一条数据
delete_many()
: 删除符合条件的所有数据, 若参数为空, 则表示删除所有数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| res = collection.delete_one({'age': 90})
res1 = collection.delete_many({'age': 90})
print(res1.deleted_count)
res1 = collection.delete_many({})
print(res1.deleted_count)
collection.drop()
|
排序
- 使用
sort
进行排序, 默认降序排列
- 降序:
DESCENDING
, 升序: ASCENDING
- 参数二也可以用1和-1: 1 为升序,-1 为降序
1 2 3 4 5 6
| res4 = collection.find().sort('age')
res5 = collection.find().sort('age', pymongo.ASCENDING) res5 = collection.find().sort('age', 1)
|
参考文档
至此, MongoDB
所有相关的内容这里也就全部都介绍完了