NoSQL入门指南:Redis与MongoDB的Java实战

一、为什么需要NoSQL?

在传统SQL数据库中,数据必须严格遵循预定义的表结构,就像把所有物品整齐摆放在固定尺寸的货架上。而NoSQL(Not Only SQL)数据库则像一个灵活的储物间,允许存储各种类型的数据,无需提前规划结构。

NoSQL的核心特点:

  • 非关系型:无需预定义表结构
  • 分布式:天然支持水平扩展
  • 高性能:适合处理海量数据
  • 灵活存储:支持键值、文档、列族等多种格式

二、Redis:内存中的超级储物柜

1. 核心特性

  • 数据类型丰富:支持字符串、哈希、列表、集合、有序集合等
  • 内存存储:读写速度极快(10万+操作/秒)
  • 持久化:支持RDB快照和AOF日志

2. Java操作示例

添加依赖(Maven)
xml 复制代码
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>4.3.1</version>
</dependency>
基本操作代码
java 复制代码
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

public class RedisExample {
    public static void main(String[] args) {
        try (Jedis jedis = new Jedis("localhost", 6379)) {
            // 存储用户信息
            jedis.set("user:1001", "{\"name\":\"张三\",\"age\":25}");

            // 存储哈希数据
            jedis.hset("user:1001:profile", "email", "[email protected]");
            jedis.hset("user:1001:profile", "phone", "13812345678");

            // 自增计数器
            jedis.incr("post:view:100");  // 阅读量+1

            // 有序集合存储排行榜
            jedis.zadd("rank:score", 95, "李四");
            jedis.zadd("rank:score", 88, "王五");

            // 事务操作
            Transaction transaction = jedis.multi();
            transaction.incr("counter");
            transaction.exec();
        }
    }
}

3. 典型应用场景

  • 缓存系统:存储高频访问数据
  • 会话管理:存储用户会话信息
  • 计数器:统计文章阅读量、点赞数
  • 实时消息:使用Pub/Sub功能实现消息队列

三、MongoDB:灵活的文档数据库

1. 核心特性

  • 文档存储:使用BSON格式存储半结构化数据
  • 动态模式:无需预定义字段
  • 水平扩展:支持分片集群
  • 强大查询:支持复杂的聚合操作

2. Java操作示例

添加依赖(Maven)
xml 复制代码
<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongodb-driver-sync</artifactId>
    <version>4.6.0</version>
</dependency>
基本操作代码
java 复制代码
import com.mongodb.MongoClientSettings;
import com.mongodb.client.*;
import org.bson.Document;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.codecs.pojo.PojoCodecProvider;

import java.util.Arrays;

import static org.bson.codecs.configuration.CodecRegistries.fromProviders;
import static org.bson.codecs.configuration.CodecRegistries.fromRegistries;

public class MongoDBExample {
    public static void main(String[] args) {
        // 配置POJO映射
        CodecRegistry pojoCodecRegistry = fromProviders(PojoCodecProvider.builder().automatic(true).build());
        CodecRegistry codecRegistry = fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), pojoCodecRegistry);

        // 连接MongoDB
        try (MongoClient mongoClient = MongoClients.create(
                MongoClientSettings.builder()
                        .codecRegistry(codecRegistry)
                        .applyToClusterSettings(builder ->
                                builder.hosts(Arrays.asList(new ServerAddress("localhost", 27017))))
                        .build())) {

            MongoDatabase database = mongoClient.getDatabase("mydatabase");
            MongoCollection<User> collection = database.getCollection("users", User.class);

            // 插入文档
            User user = new User("张三", 25, "[email protected]", 
                    new Address("长安街1号", "北京"));
            collection.insertOne(user);

            // 查询文档
            FindIterable<User> results = collection.find(Filters.eq("name", "张三"));
            for (User u : results) {
                System.out.println(u);
            }

            // 更新文档
            collection.updateOne(
                    Filters.eq("name", "张三"),
                    Updates.set("age", 26)
            );

            // 聚合查询
            AggregateIterable<Document> aggregate = collection.aggregate(Arrays.asList(
                    Aggregates.match(Filters.gte("age", 18)),
                    Aggregates.group("$address.city", Accumulators.sum("count", 1))
            ));

            for (Document doc : aggregate) {
                System.out.println(doc);
            }
        }
    }
}

// 定义实体类
class User {
    private String name;
    private int age;
    private String email;
    private Address address;

    // 构造方法、getter/setter省略
}

class Address {
    private String street;
    private String city;

    // 构造方法、getter/setter省略
}

3. 典型应用场景

  • 日志记录:存储非结构化日志数据
  • 内容管理:存储文章、评论等
  • 电商订单:存储包含复杂属性的订单
  • 实时分析:使用聚合框架处理海量数据

四、Redis vs MongoDB:如何选择?

特性 Redis MongoDB
数据模型 键值对(支持丰富数据结构) 文档型(BSON格式)
存储位置 内存优先 磁盘存储
查询能力 简单查询 复杂查询+聚合
扩展性 主从复制+哨兵 分片集群
适用场景 缓存、计数器、实时消息 日志、内容管理、实时分析

五、总结

NoSQL数据库为现代应用提供了更灵活的数据存储方式:

  • Redis适合需要高性能读写的场景
  • MongoDB适合处理半结构化数据和复杂查询
  • 传统SQL适合需要事务支持的场景

建议根据具体业务需求选择合适的工具,必要时可以混合使用多种数据库。

六、推荐学习资源

  1. Redis Java客户端文档
  2. MongoDB Java驱动文档
  3. 《Redis实战》
  4. 《MongoDB权威指南》

现在就动手用Java操作Redis和MongoDB,体验NoSQL的灵活性吧!🚀

相关推荐
极小狐1 小时前
极狐GitLab 容器镜像仓库功能介绍
java·前端·数据库·npm·gitlab
极小狐1 小时前
如何构建容器镜像并将其推送到极狐GitLab容器镜像库?
开发语言·数据库·机器学习·gitlab·ruby
阿四啊1 小时前
【Redis实战篇】分布式锁-Redisson
数据库·redis·分布式
_星辰大海乀2 小时前
数据库约束
java·数据结构·数据库·sql·链表
一只fish2 小时前
MySQL 8.0 OCP 1Z0-908 题目解析(1)
数据库·mysql
AI大模型顾潇2 小时前
[特殊字符] 本地部署DeepSeek大模型:安全加固与企业级集成方案
数据库·人工智能·安全·大模型·llm·微调·llama
FAQEW2 小时前
MongDB和MySQL的区别
数据库·mysql·mongdb·区别
码农飞哥2 小时前
互联网大厂Java面试实战:Spring Boot到微服务的技术问答解析
java·数据库·spring boot·缓存·微服务·消息队列·面试技巧
niechel3 小时前
02-GBase 8s 事务型数据库 客户端工具dbaccess
数据库
扫地生大鹏3 小时前
Mysql-OCP PPT课程讲解并翻译
数据库