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

Как в СУБД обеспечивается консистентность данных?

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).

Заключение

Консистентность обеспечивается через:

  1. Constraints (ограничения)
  2. ACID (транзакции)
  3. Locks (блокировки)
  4. MVCC (версионирование)
  5. Триггеры (проверки)
  6. Логирование (восстановление)
  7. 2PC (распределённые системы)
Как в СУБД обеспечивается консистентность данных? | PrepBro