← Назад к вопросам
Как в СУБД обеспечивается консистентность данных?
2.0 Middle🔥 171 комментариев
#SQL и базы данных
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как в СУБД обеспечивается консистентность данных?
Определение
Консистентность - это гарантия что данные остаются в корректном состоянии. Это часть ACID.
1. Ограничения целостности (Constraints)
PRIMARY KEY: уникальность
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(100) NOT NULL
);
FOREIGN KEY: связность
CREATE TABLE orders (
id INT PRIMARY KEY,
user_id INT REFERENCES users(id)
);
UNIQUE: уникальность
CREATE TABLE users (
id INT PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL
);
CHECK: проверка значения
CREATE TABLE orders (
id INT PRIMARY KEY,
amount DECIMAL(10,2),
CONSTRAINT positive CHECK (amount > 0)
);
2. Транзакции и ACID
Atomicity: либо всё, либо ничего
BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 'A';
UPDATE accounts SET balance = balance + 100 WHERE id = 'B';
COMMIT;
Либо обе UPDATE выполнятся, либо ни одна.
3. Уровни изоляции (Isolation Levels)
Предотвращают конфликты при одновременных операциях:
READ UNCOMMITTED -- низкая безопасность
READ COMMITTED -- стандарт
REPEATABLE READ -- выше безопасность
SERIALIZABLE -- максимум, медленнее
4. Блокировки (Locks)
READ LOCK: несколько транзакций могут читать
SELECT * FROM users WHERE id = 1 FOR SHARE;
WRITE LOCK: только одна может писать
SELECT * FROM users WHERE id = 1 FOR UPDATE;
5. Версионирование (MVCC)
Multi-Version Concurrency Control:
Данные: id=1, name=Alice, version=100
Транзакция A: UPDATE name = Bob (новая версия 101)
Транзакция B: видит версию 100 (Alice)
Транзакция A: COMMIT
Транзакция B: видит версию 101 (Bob)
Каждая транзакция видит снимок БД на момент начала.
6. Каскадное удаление (Referential Integrity)
CREATE TABLE users (id INT PRIMARY KEY);
CREATE TABLE orders (
id INT PRIMARY KEY,
user_id INT REFERENCES users(id) ON DELETE CASCADE
);
DELETE FROM users WHERE id = 1; -- удалятся и его заказы
7. Триггеры
Автоматические проверки при изменении:
CREATE TRIGGER check_balance
BEFORE UPDATE ON accounts
FOR EACH ROW
BEGIN
IF NEW.balance < 0 THEN
RAISE EXCEPTION "Balance cannot be negative";
END IF;
END;
8. Логирование (Write-Ahead Logging)
1. Операция записывается в лог (на диск)
2. Операция выполняется в памяти
3. При сбое: БД восстанавливается из лога
9. Двухфазный коммит (2PC)
Для распределённых транзакций:
Фаза 1: БД A "Готова!" + БД B "Готова!"
Фаза 2: Обе коммитят OR обе откатываются
10. Пример: Перевод денег
BEGIN TRANSACTION;
SELECT * FROM accounts WHERE id IN ('A', 'B') FOR UPDATE; -- LOCK
UPDATE accounts SET balance = balance - 100 WHERE id = 'A';
UPDATE accounts SET balance = balance + 100 WHERE id = 'B';
COMMIT; -- ATOMICITY: либо оба UPDATE, либо ничего
Если ошибка - ROLLBACK. Если успех - данные на диске (DURABILITY).
Заключение
Консистентность обеспечивается через:
- Constraints (ограничения)
- ACID (транзакции)
- Locks (блокировки)
- MVCC (версионирование)
- Триггеры (проверки)
- Логирование (восстановление)
- 2PC (распределённые системы)