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", "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)
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, "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的灵活性吧!🚀

相关推荐
数据库小学妹2 分钟前
金融数据库成本怎么算?五笔钱加一张TCO表
数据库·金融行业·数据库选型·国产化替代·tco·金融数据库
KaiwuDB19 分钟前
KaiwuDB 分布式集群扩缩容,从原理到完整操作踩坑总结
运维·数据库·分布式
auspicious航35 分钟前
PostgreSQL的备份与恢复
数据库·postgresql
这个DBA有点耶1 小时前
从 MySQL 到时序数据库:我帮朋友做迁移的完整记录
数据库·架构·dba
泡海椒1 小时前
深度解析JQuick-SQL AST到逻辑计划转换机制|分布式SQL原理
数据库·分布式·sql
心静财富之门1 小时前
Python 数据共享四种方案完整实例(同进程 / JSON / Redis / HTTP)
数据库·python·oracle
略略略咯咯1 小时前
啊啊啊啊啊
java·服务器·数据库
奇牙coding2 小时前
GPT-5.5 报 401 invalid_api_key 怎么办?换密钥前按 4 层排查请求头、项目权限和端点
数据库·gpt·ios·ai
IvorySQL2 小时前
PostgreSQL 日报| WAL summarizer 断言失败(10 月 26 日)
数据库·postgresql·区块链
这个DBA有点耶2 小时前
2026年国产数据库“实际用户增长最快”核验指南:口径优先级、可查数据与选型动作清单
数据库·mysql·架构