当前位置: 首页 > news >正文

NoSQL入门实战:MongoDB与Redis核心应用全解析

前言

在当今大数据时代,传统的关系型数据库已无法满足所有场景的需求,NoSQL数据库因其灵活的数据模型和出色的扩展性成为技术栈中不可或缺的部分。本文将带您深入浅出地学习两大主流NoSQL数据库——文档型数据库MongoDB和键值存储Redis的核心概念与实战应用,通过Python生态的PyMongo和redis-py库,快速掌握NoSQL开发技能。

一、MongoDB基础与PyMongo实战

1.1 MongoDB核心概念

MongoDB作为最流行的文档型数据库,与传统SQL数据库有着显著差异:

概念SQLMongoDB
数据库DatabaseDatabase
TableCollection
RowDocument
ColumnField
主键Primary Key_id(ObjectId)
索引IndexIndex
外键Foreign Key引用/嵌入文档

核心优势

  • 灵活模式:文档结构可动态变化

  • 水平扩展:分片集群轻松应对海量数据

  • 高性能:内存映射文件提高IO效率

  • 丰富查询:支持复杂条件与聚合操作

1.2 PyMongo基础操作

安装与环境配置

pip install pymongo

连接数据库

from pymongo import MongoClient
from pymongo.errors import ConnectionFailure# 基础连接
client = MongoClient('mongodb://localhost:27017/')# 带认证的连接
auth_client = MongoClient('mongodb://username:password@localhost:27017/',authSource='admin'
)# 连接测试
try:client.admin.command('ping')print("MongoDB连接成功")
except ConnectionFailure:print("MongoDB连接失败")

CRUD操作示例

# 获取数据库和集合
db = client['school']  # 使用school数据库
students = db['students']  # 使用students集合# 插入文档
student1 = {"name": "张三","age": 20,"major": "计算机科学","courses": ["数据结构", "算法"],"gpa": 3.8
}
insert_result = students.insert_one(student1)
print(f"插入ID: {insert_result.inserted_id}")# 批量插入
student_list = [{"name": "李四", "age": 21, "major": "数学"},{"name": "王五", "age": 19, "major": "物理"}
]
students.insert_many(student_list)# 查询文档
# 查找单个文档
zhangsan = students.find_one({"name": "张三"})
print(zhangsan)# 查找多个文档
cs_students = students.find({"major": "计算机科学"})
for student in cs_students:print(student)# 更新文档
update_result = students.update_one({"name": "张三"},{"$set": {"gpa": 3.9}, "$push": {"courses": "数据库"}}
)
print(f"匹配{update_result.matched_count}条, 修改{update_result.modified_count}条")# 删除文档
delete_result = students.delete_one({"name": "王五"})
print(f"删除{delete_result.deleted_count}条文档")

1.3 高级查询与聚合

复杂查询

# 比较操作符
# 年龄大于20且小于25的学生
students.find({"age": {"$gt": 20, "$lt": 25}})# 逻辑操作符
# 计算机科学或数学专业的学生
students.find({"$or": [{"major": "计算机科学"}, {"major": "数学"}]})# 数组查询
# 选修了算法的学生
students.find({"courses": "算法"})# 正则表达式
# 名字以"张"开头的学生
students.find({"name": {"$regex": "^张"}})

 聚合管道

pipeline = [{"$match": {"major": "计算机科学"}},  # 筛选条件{"$group": {  # 分组统计"_id": "$age","count": {"$sum": 1},"avg_gpa": {"$avg": "$gpa"}}},{"$sort": {"avg_gpa": -1}},  # 排序{"$limit": 5}  # 限制结果数
]results = students.aggregate(pipeline)
for r in results:print(f"年龄{r['_id']}: 人数{r['count']}, 平均GPA{r['avg_gpa']:.2f}")

二、Redis核心数据结构与实战

2.1 Redis核心特性

Redis作为内存型键值数据库,提供多种数据结构:

数据结构特点典型应用场景
String二进制安全的字符串缓存、计数器
Hash字段-值映射表对象存储
List双向链表消息队列、最新列表
Set无序唯一集合标签、好友关系
ZSet有序集合排行榜
Stream消息流事件日志

核心优势

  • 超高性能:内存操作,10万+ QPS

  • 持久化选项:RDB快照和AOF日志

  • 丰富数据结构:超越简单键值存储

  • 原子操作:单线程模型保证原子性

2.2 redis-py基础操作

安装与连接

pip install redis
import redis# 基础连接
r = redis.Redis(host='localhost', port=6379, db=0)# 连接池(推荐生产环境使用)
pool = redis.ConnectionPool(host='localhost', port=6379, db=0)
r = redis.Redis(connection_pool=pool)# 测试连接
try:r.ping()print("Redis连接成功")
except redis.ConnectionError:print("Redis连接失败")

2.3 String与Hash实战

String操作

# 基本操作
r.set("user:1000:name", "张三")  # 设置键值
name = r.get("user:1000:name")  # 获取值
print(name.decode('utf-8'))  # 返回bytes需要解码# 带过期时间的缓存
r.setex("article:1234:content", 3600, "文章内容...")  # 1小时后过期# 计数器
r.set("page:views", 0)
r.incr("page:views")  # +1
r.incrby("page:views", 10)  # +10
views = r.get("page:views")
print(f"总访问量: {views.decode()}")# 批量操作
r.mset({"user:1000:email": "zhangsan@example.com", "user:1000:age": 25})
values = r.mget(["user:1000:name", "user:1000:email"])
print(values)  # [b'\xe5\xbc\xa0\xe4\xb8\x89', b'zhangsan@example.com']

Hash操作

# 存储用户对象
user_data = {"name": "李四","age": 28,"email": "lisi@example.com"
}
r.hset("user:1001", mapping=user_data)# 获取字段
name = r.hget("user:1001", "name")
print(name.decode('utf-8'))# 获取所有字段
user = r.hgetall("user:1001")
print({k.decode('utf-8'): v.decode('utf-8') for k, v in user.items()})# 字段操作
r.hincrby("user:1001", "age", 1)  # 年龄+1
r.hset("user:1001", "phone", "13800138000")  # 添加字段
r.hdel("user:1001", "email")  # 删除字段# 批量设置
r.hmset("user:1002", {"name": "王五", "age": 22})

三、综合应用场景

3.1 用户会话管理(Redis)

import secrets
from datetime import timedeltadef create_session(user_id):"""创建用户会话"""session_id = secrets.token_hex(16)session_key = f"session:{session_id}"# 存储会话数据r.hset(session_key, mapping={"user_id": user_id,"ip": "192.168.1.100","login_time": datetime.now().isoformat()})# 设置30分钟过期r.expire(session_key, timedelta(minutes=30))return session_iddef get_user_id(session_id):"""获取会话用户ID"""session_key = f"session:{session_id}"if r.exists(session_key):r.expire(session_key, timedelta(minutes=30))  # 续期return r.hget(session_key, "user_id").decode()return None

3.2 商品评论系统(MongoDB)

from datetime import datetime# 评论文档结构
comment = {"product_id": "p10086","user_id": "u1001","rating": 5,"text": "质量非常好!","created_at": datetime.now(),"tags": ["好评", "物流快"]
}# 插入评论
db.comments.insert_one(comment)# 聚合查询:计算商品平均评分
pipeline = [{"$match": {"product_id": "p10086"}},{"$group": {"_id": "$product_id","avg_rating": {"$avg": "$rating"},"count": {"$sum": 1}}}
]result = db.comments.aggregate(pipeline).next()
print(f"商品{p10086}: 平均评分{result['avg_rating']:.1f}, 共{result['count']}条评论")

四、性能优化与最佳实践

4.1 MongoDB优化技巧

索引优化

# 创建单字段索引
db.students.create_index([("name", pymongo.ASCENDING)])# 创建复合索引
db.students.create_index([("major", 1), ("gpa", -1)])# 查看查询执行计划
explain = db.students.find({"major": "计算机科学"}).explain()
print(explain["executionStats"]["executionTimeMillis"])

批量操作

# 批量插入比单条插入高效10倍以上
operations = [InsertOne(doc1), UpdateOne(filter, update), DeleteMany(filter)]
db.collection.bulk_write(operations)

读写分离

# 从secondary节点读取
client = MongoClient('mongodb://primary,secondary1,secondary2/',replicaSet='myReplSet',readPreference='secondaryPreferred'
)

4.2 Redis优化建议

管道(Pipeline)

pipe = r.pipeline()
pipe.set("counter", 0)
pipe.incr("counter")
pipe.incrby("counter", 10)
pipe.get("counter")
results = pipe.execute()  # 单次网络往返
print(results)  # [True, 1, 11, b'11']

Lua脚本

script = """
local key = KEYS[1]
local increment = tonumber(ARGV[1])
local current = tonumber(redis.call('GET', key) or 0)
local new = current + increment
redis.call('SET', key, new)
return new
"""
new_value = r.eval(script, 1, "my_counter", 5)

内存优化

  • 使用Hash代替多个String存储对象

  • 对长字符串进行压缩

  • 设置合理的过期时间

五、技术选型对比

特性MongoDBRedis
数据模型文档型键值型
持久化磁盘存储内存+持久化选项
查询能力丰富有限
事务支持多文档ACID事务单命令原子性
扩展性水平扩展(分片)主从复制/集群
适用场景内容管理、产品目录

缓存、会话、消息队列

典型应用场景

  • 选择MongoDB

    • 需要灵活模式的产品目录

    • 内容管理系统

    • 用户生成内容平台

    • 实时分析系统

  • 选择Redis

    • 会话缓存

    • 排行榜和计数器

    • 消息队列系统

    • 实时数据处理

结语

通过本文的学习,您应该已经掌握了MongoDB和Redis这两大NoSQL数据库的核心概念与实战技能。在实际项目中:

  1. 混合使用:多数系统会同时使用SQL和NoSQL技术

  2. 扬长避短:根据业务特点选择合适的数据存储

  3. 持续学习:关注MongoDB的Atlas服务和Redis模块扩展

进一步学习建议

  1. 研究MongoDB的Change Streams实现实时数据流

  2. 学习Redis的Stream数据结构实现消息队列

  3. 探索MongoDB Atlas云服务部署

  4. 了解Redis集群搭建与故障转移

如果您在NoSQL实践中遇到任何问题,欢迎在评论区留言讨论。觉得本文有帮助的话,请点赞收藏支持!

相关文章:

  • 从 Java 开发到 AI 工程师:全面学习指南
  • 【漫话机器学习系列】238.训练误差与测试误差(Training Error And Test Error)
  • Spring AI 实战:第十一章、Spring AI Agent之知行合一
  • 56认知干货:智能化产业
  • 《政治最后的日子》章节
  • 电动调节 V 型球阀:颗粒状含碱浆液介质的完美解决方案-耀圣
  • 原码、补码、反码、有符号整数、无符号整数
  • 【漫话机器学习系列】239.训练错误率(Training Error Rate)
  • SpringBoot智能排课系统源码开发与实现
  • 正态分布习题集 · 题目篇
  • 2025牛客五一集训派对day4
  • OpenCV入门指南:从环境搭建到第一个图像处理程序
  • 【RocketMQ Broker 相关源码】- broker 启动源码(2)
  • level2.5 函数高阶
  • 气泡图、桑基图的绘制
  • MySQL--索引精通详解
  • TestBench激励与待测
  • 驱动开发硬核特训 · Day 27(上篇):Linux 内核子系统的特性全解析
  • 引入spdlog后程序链接很慢
  • 系统思考:核心价值与竞争力
  • 干细胞从科研到市场应用有多远?发展还面临何挑战?
  • 这样喝酸奶相当于在喝糖水,会导致娃龋齿、肥胖
  • 两千万粉丝网红“大LOGO”带货茶叶被指虚假宣传,涉事茶企被立案调查
  • 多地晒五一假期前两日成绩单,湖南单日客流同比增长逾三成
  • 长三角铁路今日预计发送旅客420万人次,有望创单日客发量新高
  • 深交所修订创业板指数编制方案,引入ESG负面剔除机制