Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
ACID: Четыре основы надёжных баз данных
ACID это аббревиатура четырёх фундаментальных свойств транзакций в системах управления базами данных, обеспечивающих целостность и надёжность данных. Понимание ACID критично для любого Data Engineer.
A — Atomicity (Атомарность)
Транзакция либо полностью выполняется, либо полностью откатывается. Нет промежуточных состояний.
Пример — перевод денег между счётами:
BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 1; -- Снять с первого
UPDATE accounts SET balance = balance + 100 WHERE id = 2; -- Положить на второе
COMMIT;
Если произойдёт сбой между двумя UPDATE:
- Либо оба UPDATE выполнятся (деньги переведены)
- Либо оба откатятся (деньги остались как были)
- Никогда не произойдёт ситуация, когда снято со счёта 1, но не положено на счёт 2
Реальный сценарий:
BEGIN TRANSACTION;
INSERT INTO transactions (from_id, to_id, amount) VALUES (1, 2, 100);
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
-- Если здесь сбой БД, всё откатится
COMMIT; -- Либо всё успешно сохранится
C — Consistency (Консистентность)
База данных переходит из одного консистентного состояния в другое. Все правила и ограничения (constraints) остаются выполненными.
Пример с бизнес-правилом:
CREATE TABLE users (
id INT PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
age INT CHECK (age >= 18), -- Ограничение консистентности
account_balance DECIMAL >= 0 -- Баланс не может быть отрицательным
);
-- Попытка нарушить консистентность
INSERT INTO users (id, email, age, account_balance)
VALUES (1, "john@example.com", 15, -100); -- ОШИБКА!
-- Возраст < 18 и баланс < 0 нарушают constraints
-- Правильная вставка
INSERT INTO users (id, email, age, account_balance)
VALUES (1, "john@example.com", 25, 0); -- OK
Пример с внешним ключом:
CREATE TABLE orders (
id INT PRIMARY KEY,
user_id INT NOT NULL,
amount DECIMAL,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
-- Нельзя создать заказ с несуществующим пользователем
INSERT INTO orders (id, user_id, amount)
VALUES (1, 999, 100); -- ОШИБКА! user_id=999 не существует
Транзакция гарантирует, что после COMMIT база будет в консистентном состоянии.
I — Isolation (Изоляция)
Одновременные транзакции не влияют друг на друга. Каждая видит данные, как если бы она была единственной.
Проблема без изоляции (Dirty Read):
Транзакция 1: Транзакция 2:
BEGIN;
UPDATE balance SET x = 100
BEGIN;
SELECT balance; -- Вывод: 100 (грязное чтение!)
ROLLBACK; -- Откат!
SELECT balance; -- Вывод: 50 (было изначально)
С ISOLATION LEVEL = SERIALIZABLE (максимальная изоляция):
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN;
SELECT balance FROM accounts WHERE id = 1; -- Вид: 50
-- Параллельная транзакция не может менять этот счёт
COMMIT;
Уровни изоляции (от слабого к сильному):
READ UNCOMMITTED - минимальная изоляция, максимальная скорость
READ COMMITTED - стандартный уровень
REPEATABLE READ - средняя изоляция
SERIALIZABLE - максимальная изоляция, минимальная скорость
D — Durability (Долговечность)
Если транзакция выполнена (COMMIT), данные остаются в базе даже при сбое питания, краша системы или дисковых ошибок.
Механизм в современных БД:
1. Транзакция выполняется в памяти (буфер)
2. Изменения записываются в WAL (Write-Ahead Log) на диск
3. COMMIT подтверждает: данные безопасно на диске
4. Данные затем записываются в основные файлы БД
5. При сбое БД восстанавливается из WAL
Пример в PostgreSQL:
BEGIN;
INSERT INTO logs (message) VALUES ("Important data");
UPDATE balance SET x = 100; -- Оба в памяти
COMMIT; -- Гарантия: данные на диске, безопасны
-- Даже если сейчас выключится питание, данные останутся
Сравнение ACID свойств
| Свойство | Гарантия | Пример нарушения |
|---|---|---|
| Atomicity | Всё или ничего | Половина обновлений, половина откатилась |
| Consistency | Правила сохраняются | Отрицательный баланс при CHECK |
| Isolation | Транзакции независимы | Одна видит незакоммиченные изменения другой |
| Durability | Данные постоянны | После выключения питания данные потеряны |
ACID в контексте Data Engineering
Когда ACID критичны:
- Финансовые системы (потеря деньги — недопустимо)
- Критичные данные (инвентарь, заказы)
- Системы с высокими требованиями к надёжности
Когда ACID менее критичны:
- Аналитические БД (редко обновляются)
- Log-based системы (потеря одного лога — не катастрофа)
- Big Data системы, где ApacheHadoop отказывается от полного ACID
Базы данных и ACID
Полная поддержка ACID:
- PostgreSQL (отличный ACID)
- MySQL с InnoDB (полный ACID)
- SQLite (ACID на одной машине)
- Oracle Database
Частичная поддержка (BASE модель):
- MongoDB (в некоторых версиях) — многодокументные транзакции
- DynamoDB — условные операции вместо транзакций
- Cassandra — конечная консистентность вместо строгой ACID
Заключение
ACID представляет четыре столпа надёжности баз данных:
- A: либо выполнится всё, либо ничего
- C: правила и ограничения всегда соблюдены
- I: одновременные операции не мешают друг другу
- D: коммиченные данные永远 остаются в базе
Для Data Engineer важно выбирать БД в соответствии с требованиями ACID конкретного проекта.