← Назад к вопросам

Что такое нереляционные базы данных?

2.0 Middle🔥 181 комментариев
#Кэширование и NoSQL

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое нереляционные базы данных?

Нереляционные базы данных (NoSQL — Not Only SQL) — это системы управления базами данных, которые не используют традиционную реляционную модель с таблицами, строками и столбцами. Вместо этого они хранят данные в других форматах: документы, графы, ключ-значение, временные ряды.

Основные различия: SQL vs NoSQL

ХарактеристикаSQL (Реляционные)NoSQL (Нереляционные)
Модель данныхТаблицы, строки, столбцыДокументы, графы, ключ-значение
СхемаФиксированная схемаГибкая или без схемы
МасштабированиеВертикальное (мощнее сервер)Горизонтальное (больше серверов)
ТранзакцииACID гарантииBASE (базовая согласованность)
Язык запросовSQLСпецифичный для БД
ПримерыPostgreSQL, MySQL, OracleMongoDB, Redis, Cassandra, Neo4j

Типы NoSQL баз данных

1. Document Stores (MongoDB)

Хранят данные как документы (JSON, BSON).

import com.mongodb.client.*;
import org.bson.Document;
import com.mongodb.MongoClient;

public class MongoDBExample {
    
    public static void main(String[] args) {
        // Подключение к MongoDB
        MongoClient mongoClient = MongoClients.create("mongodb://localhost:27017");
        MongoDatabase database = mongoClient.getDatabase("myapp");
        MongoCollection<Document> users = database.getCollection("users");
        
        // ✅ Документ как JSON
        Document user = new Document()
            .append("_id", 1)
            .append("name", "John Doe")
            .append("email", "john@example.com")
            .append("age", 30)
            .append("tags", new String[]{"developer", "java", "spring"})
            .append("address", new Document()
                .append("street", "123 Main St")
                .append("city", "New York")
                .append("zip", "10001"));
        
        // Вставка документа
        users.insertOne(user);
        
        // Поиск
        Document found = users.find(new Document("email", "john@example.com")).first();
        System.out.println(found.toJson());
        
        // Обновление
        users.updateOne(
            new Document("_id", 1),
            new Document("$set", new Document("age", 31))
        );
        
        // Удаление
        users.deleteOne(new Document("_id", 1));
        
        mongoClient.close();
    }
}

2. Key-Value Stores (Redis)

Хранят данные как пары ключ-значение, очень быстро.

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import com.google.gson.Gson;

public class RedisExample {
    
    public static void main(String[] args) {
        JedisPool pool = new JedisPool("localhost", 6379);
        
        try (Jedis jedis = pool.getResource()) {
            // ✅ Простое хранилище ключ-значение
            jedis.set("user:1:name", "John");
            jedis.set("user:1:email", "john@example.com");
            
            // Чтение
            String name = jedis.get("user:1:name");
            System.out.println("Name: " + name);
            
            // Хеши (объекты)
            jedis.hset("user:1", "name", "John");
            jedis.hset("user:1", "email", "john@example.com");
            String userName = jedis.hget("user:1", "name");
            
            // Списки (очереди)
            jedis.lpush("messages:queue", "msg1", "msg2", "msg3");
            String msg = jedis.rpop("messages:queue");
            
            // Множества
            jedis.sadd("user:1:tags", "java", "spring", "database");
            
            // Сортированные множества
            jedis.zadd("leaderboard", 1000, "player1");
            jedis.zadd("leaderboard", 1200, "player2");
        }
    }
}

3. Wide-Column Stores (Cassandra)

Система типа таблиц, но распределённая и масштабируемая.

import com.datastax.oss.driver.api.core.CqlSession;
import com.datastax.oss.driver.api.core.cql.ResultSet;
import com.datastax.oss.driver.api.core.cql.Row;

public class CassandraExample {
    
    public static void main(String[] args) {
        // Подключение к Cassandra
        try (CqlSession session = CqlSession.builder().build()) {
            
            // Создание таблицы
            session.execute(
                "CREATE TABLE IF NOT EXISTS users (" +
                "  id UUID PRIMARY KEY," +
                "  name TEXT," +
                "  email TEXT," +
                "  age INT" +
                ")"
            );
            
            // Вставка данных
            session.execute(
                "INSERT INTO users (id, name, email, age) " +
                "VALUES (uuid(), 'John', 'john@example.com', 30)"
            );
            
            // Запрос данных
            ResultSet rows = session.execute("SELECT * FROM users WHERE email = 'john@example.com'");
            for (Row row : rows) {
                System.out.println("Name: " + row.getString("name"));
            }
        }
    }
}

4. Graph Databases (Neo4j)

Хранят данные как графы с вершинами и рёбрами.

import org.neo4j.driver.*;

public class Neo4jExample {
    
    public static void main(String[] args) {
        // Подключение к Neo4j
        Driver driver = GraphDatabase.driver("bolt://localhost:7687",
            AuthTokens.basic("neo4j", "password"));
        
        try (Session session = driver.session()) {
            // Создание узлов и отношений
            session.executeWrite(tx -> {
                tx.run(
                    "CREATE (user1:User {name: 'John', email: 'john@example.com'}) " +
                    "CREATE (user2:User {name: 'Jane', email: 'jane@example.com'}) " +
                    "CREATE (user1)-[:FOLLOWS]->(user2)"
                );
                return null;
            });
            
            // Запрос: найти подписчиков
            Result result = session.run(
                "MATCH (user:User)-[:FOLLOWS]->(following:User) " +
                "WHERE user.name = 'John' " +
                "RETURN following.name as name"
            );
            
            while (result.hasNext()) {
                Record record = result.next();
                System.out.println("John follows: " + record.get("name"));
            }
        }
        
        driver.close();
    }
}

Преимущества NoSQL

// 1. ГИБКОСТЬ СХЕМЫ
// В MongoDB можно хранить данные разной структуры
Document user1 = new Document("name", "John").append("age", 30);
Document user2 = new Document("name", "Jane")
    .append("phone", "+1234567890")
    .append("premium", true); // У user2 другие поля!

// 2. ГОРИЗОНТАЛЬНОЕ МАСШТАБИРОВАНИЕ
// Cassandra и MongoDB легко масштабируются на множество серверов
// Просто добавляешь ноды

// 3. ПРОИЗВОДИТЕЛЬНОСТЬ
// Redis может обрабатывать 100,000+ операций в секунду
// Идеален для кэша и очередей

// 4. СТРУКТУРИРОВАННЫЕ ДАННЫЕ
// MongoDB хранит JSON — нативно совместимо с Java

Недостатки NoSQL

// 1. ОТСУТСТВИЕ ACID ГАРАНТИЙ
// Данные могут быть в промежуточном состоянии при отказе
// Нужно самостоятельно обеспечивать консистентность

// 2. НЕТУ JOINS
// Вместо одного запроса нужно несколько запросов и merge в коде
public List<Order> getUserOrders(String userId) {
    // Запрос 1: получить пользователя
    Document user = usersCollection.find(new Document("_id", userId)).first();
    
    // Запрос 2: получить его заказы
    List<Document> orders = new ArrayList<>();
    ordersCollection.find(new Document("userId", userId))
        .into(orders);
    
    // Merge в коде — сложнее
    return orders.stream()
        .map(this::documentToOrder)
        .collect(Collectors.toList());
}

// 3. ДУБЛИРОВАНИЕ ДАННЫХ
// Для лучшей производительности часто дублируют данные
// Это создаёт проблемы с синхронизацией

// 4. ЛИМИТЫ ПАМЯТИ
// Redis хранит всё в памяти
// Может быть дорого для больших объёмов

Когда использовать NoSQL

// ✅ MongoDB — для документов и гибкой схемы
// Примеры: CMS, content platforms, flexible data

// ✅ Redis — для кэша и очередей
// Примеры: session store, leaderboards, rate limiting

// ✅ Cassandra — для time-series и больших объёмов
// Примеры: logs, metrics, IoT data

// ✅ Neo4j — для графов и отношений
// Примеры: social networks, recommendations, relationships

Гибридный подход: SQL + NoSQL

public class HybridDataStore {
    
    private DataSource postgresPool; // SQL для критических данных
    private MongoCollection<Document> mongoUsers; // NoSQL для гибких данных
    private JedisPool redisPool; // Redis для кэша
    
    public void saveUser(User user) {
        // 1. Сохранить в PostgreSQL (source of truth)
        saveToDB(user);
        
        // 2. Кэшировать в Redis (для быстрого доступа)
        cacheInRedis(user);
        
        // 3. Сохранить расширенные данные в MongoDB
        saveExtendedDataToMongo(user);
    }
    
    public User getUserWithCache(String id) {
        // 1. Попробовать Redis
        User cached = getFromRedis(id);
        if (cached != null) return cached;
        
        // 2. Если нет — получить из PostgreSQL
        User user = getFromDB(id);
        
        // 3. Кэшировать
        cacheInRedis(user);
        return user;
    }
}

Примеры использования в Spring Boot

Spring Data MongoDB

import org.springframework.data.mongodb.repository.MongoRepository;

public interface UserRepository extends MongoRepository<User, String> {
    User findByEmail(String email);
    List<User> findByAgeGreaterThan(int age);
}

Spring Data Redis

import org.springframework.data.redis.core.RedisTemplate;

@Service
public class CacheService {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    public void cacheUser(User user) {
        redisTemplate.opsForValue().set("user:" + user.getId(), user);
    }
}

Ключевые выводы

  • NoSQL — не замена SQL, а дополнение для специфичных задач
  • Выбор зависит от характера данных и требований
  • Полиглотная персистентность — использование разных БД в одном приложении
  • Trade-offs — в обмен на scalability теряем некоторые гарантии
  • Знай оба мира — хороший разработчик должен уметь работать с SQL и NoSQL

Не думай о NoSQL как о замене SQL — это инструменты для разных задач!

Что такое нереляционные базы данных? | PrepBro