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

В чем разница между BASE и ACID в БД?

2.0 Middle🔥 141 комментариев
#Архитектура и паттерны#Базы данных и SQL

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

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

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

Разница Между BASE и ACID в Базах Данных

Это фундаментальный вопрос о том, как разные БД обеспечивают надёжность данных. ACID и BASE — это два противоположных подхода к консистентности и надёжности.

ACID — Traditionnal Relational Databases

ACID — это четыре свойства транзакций, которые обеспечивают надёжность:

A — Atomicity (Атомарность) Транзакция либо полностью выполнится, либо полностью откатится. Нет "половины" транзакции.

// Пример: Перевод денег
BEGIN TRANSACTION;
  UPDATE accounts SET balance = balance - 100 WHERE id = 1;  // Минус 100
  UPDATE accounts SET balance = balance + 100 WHERE id = 2;  // Плюс 100
COMMIT;

// Если после первого UPDATE упадёт сервер:
// - БД откатит ОБА обновления (атомарность)
// - Первый счёт вернётся к исходному значению
// - Второй счёт тоже
// Деньги не потеряны!

Без атомарности можно потерять 100 рублей (они уйдут со счёта 1, но не придут на счёт 2).

C — Consistency (Консистентность) База данных переходит из одного консистентного состояния в другое. Все правила БД (constraints, foreign keys) выполняются.

-- Constraint: баланс не может быть отрицательный
ALTER TABLE accounts ADD CONSTRAINT check_balance CHECK (balance >= 0);

-- Эта транзакция никогда не выполнится (нарушает консистентность)
UPDATE accounts SET balance = -50 WHERE id = 1;
-- Error: Constraint violation

I — Isolation (Изолированность) Каждая транзакция работает так, как будто других транзакций не существует. Изменения одной не видны другой, пока не завершится.

// Транзакция 1
BEGIN;
  const balance1 = SELECT balance FROM accounts WHERE id = 1;  // 1000
  // Пока эта транзакция открыта, другие не видят её изменения
  UPDATE accounts SET balance = 900 WHERE id = 1;
COMMIT;

// Транзакция 2 (одновременно)
BEGIN;
  const balance2 = SELECT balance FROM accounts WHERE id = 1;
  // balance2 всё ещё 1000 (не видит изменения из транзакции 1)
COMMIT;

Без изолированности может быть "грязное чтение" (dirty read).

D — Durability (Надёжность) После коммита, данные сохранены навсегда, даже если упадёт сервер, питание или что-то ещё.

// После COMMIT
UPDATE accounts SET balance = 900 WHERE id = 1;
COMMIT;  // Данные на диске, защищены

// Даже если сейчас:
// 1. Упадёт питание
// 2. Упадёт процесс БД
// 3. Слетит RAM
// Данные ВСЁ РАВНО будут 900, потому что записаны на диск

Примеры ACID БД

PostgreSQL

BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
  UPDATE accounts SET balance = balance - 100 WHERE id = 1;
  UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;  -- Гарантия ACID

MySQL (InnoDB) ИнноДБ движок (по умолчанию) поддерживает ACID.

Oracle, SQL Server — тоже ACID.

BASE — NoSQL Databases

BASE — противоположный подход. Аббревиатура придумана как противовес ACID:

BA — Basically Available (Базово Доступна) Система ВСЕГДА доступна для чтения/записи, даже если данные временно неконсистентны.

// MongoDB пример
db.accounts.updateOne({ id: 1 }, { $inc: { balance: -100 } });
db.accounts.updateOne({ id: 2 }, { $inc: { balance: 100 } });

// Если после первого update упадёт сервер:
// - Первая запись записана (доступна)
// - Вторая не выполнилась
// - Система всё равно отвечает (доступна)
// - Но данные неконсистентны

S — Soft state (Мягкое состояние) Состояние системы может быть временно неконсистентным. Данные синхронизируются со временем (eventual consistency).

// Репликация в MongoDB
// Primary (master) пишет данные
db.accounts.updateOne({ id: 1 }, { $set: { balance: 900 } });
// Но Secondary replicas обновляются с задержкой (может быть секунда)

// Если прочитать со Secondary:
// const balance = db.accounts.findOne({ id: 1 });  // Может быть старое значение!

E — Eventually Consistent (Итоговая Консистентность) Система будет консистентной, но это может занять время.

// AWS DynamoDB пример
const params = {
  Item: {
    id: 'user123',
    name: 'John',
    email: 'john@example.com'
  }
};

await dynamodb.putItem(params);
// putItem возвращает успех
// Но данные могут быть ещё не реплицированы на все серверы
// В течение 100-200ms данные распространятся везде (eventual consistency)

Примеры BASE БД

MongoDB

db.accounts.updateOne({ _id: 1 }, { $inc: { balance: -100 } });
db.accounts.updateOne({ _id: 2 }, { $inc: { balance: 100 } });
// Это две отдельные операции
// Если упадёт сервер между ними — неконсистентность
// Но данные доступны!

DynamoDB, Cassandra, Redis — BASE системы.

Таблица Сравнения

┌─────────────────────┬────────────────────────┬─────────────────────────┐
│ Свойство            │ ACID (SQL)             │ BASE (NoSQL)            │
├─────────────────────┼────────────────────────┼─────────────────────────┤
│ Консистентность     │ Всегда (Strong)        │ Итоговая (Eventual)     │
│ Доступность         │ Может быть недоступна  │ Всегда доступна         │
│ Скорость            │ Медленнее (блокировки) │ Быстрее                 │
│ Масштабируемость    │ Сложнее (вертикальная)│ Проще (горизонтальная) │
│ Гарантии            │ Высокие                │ Мягкие                  │
│ Транзакции          │ Поддерживает           │ Не поддерживает (или    │
│                     │                        │  очень ограниченно)     │
│ Примеры             │ PostgreSQL, Oracle     │ MongoDB, DynamoDB       │
└─────────────────────┴────────────────────────┴─────────────────────────┘

Практические Примеры

Когда нужен ACID (PostgreSQL)

// Банковская система
// Необходимо гарантировать: если один счёт минус 100,
// то другой счёт плюс 100 ВСЕГДА

BEGIN;
  UPDATE accounts SET balance = balance - 100 WHERE id = 1;
  UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;  // ACID гарантирует корректность

Когда нужен BASE (MongoDB)

// Счетчик просмотров видео
// Если 1000 человек смотрят видео одновременно,
// нужна быстрая запись в БД

db.videos.updateOne({ id: 'video123' }, { $inc: { views: 1 } });
// Счётчик не обязательно идеально точен (может быть off на 1-2)
// Главное — быстро отвечает

CAP Theorem

Учитывая ACID vs BASE, есть ещё CAP theorem:

В распределённой системе можно гарантировать только 2 из 3:

Consistency (Консистентность) — все узлы видят одинаковые данные
Availability (Доступность) — система отвечает на запросы
Partition tolerance (Устойчивость к разделению) — система работает при разрыве сети

ACID БД часто выбирают: Consistency + Availability (но есть один сервер)
BASE БД выбирают: Availability + Partition tolerance (и жертвуют консистентностью)

Мой Подход в Production

Я выбираю БД на основе требований:

PostgreSQL (ACID), если:

  • Данные критичны (платежи, финансы, заказы)
  • Нужны транзакции
  • QPS < 10K

MongoDB/DynamoDB (BASE), если:

  • Скорость критична
  • Данные не критичны (логи, аналитика, счётчики)
  • Нужна горизонтальная масштабируемость
  • Допустима временная неконсистентность
// Пример: e-commerce платформа

// Критичные данные — PostgreSQL (ACID)
const order = await postgres.transaction(async (trx) => {
  // Гарантия: если заказ создан, товар зарезервирован
  await trx.orders.insert(orderData);
  await trx.inventory.decrement(productId, quantity);
  return order;
});

// Аналитика — MongoDB (BASE)
await mongodb.analytics.insertOne({
  userId: user.id,
  action: 'viewed-product',
  timestamp: new Date()
});
// Если данные потеряются — ничего страшного

Заключение

ACID:

  • Гарантирует надёжность и консистентность
  • Медленнее
  • Подходит для критичных данных

BASE:

  • Быстрее и масштабируемее
  • Гарантирует доступность
  • Подходит для некритичных данных

Нет "лучшего" варианта. Вопрос в том, что тебе важнее:

  • Надёжность и консистентность? → ACID → PostgreSQL
  • Скорость и доступность? → BASE → MongoDB

Модные разработчики говорят: "NoSQL better". Опытные разработчики говорят: "Use the right tool for the job". Я согласен со вторыми.

В чем разница между BASE и ACID в БД? | PrepBro