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

发布于:2025-04-15 ⋅ 阅读:(25) ⋅ 点赞:(0)

一、为什么需要NoSQL?

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

NoSQL的核心特点:

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

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

1. 核心特性

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

2. Java操作示例

添加依赖(Maven)
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>4.3.1</version>
</dependency>
基本操作代码
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", "zhangsan@example.com");
            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)
<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongodb-driver-sync</artifactId>
    <version>4.6.0</version>
</dependency>
基本操作代码
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, "zhangsan@example.com", 
                    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的灵活性吧!🚀


网站公告

今日签到

点亮在社区的每一天
去签到