Для работы в PostgreSQL мы будем использовать **pgAdmin 4** (стандартная утилита) или любую другую среду (DBeaver, psql).
### Часть 1: Теория (для ответа на билет)
1. **Аудит базы данных** — это процесс мониторинга действий пользователей. В PostgreSQL он реализуется либо через расширение `pgaudit`, либо через триггеры, которые записывают изменения в отдельную таблицу логов.
2. **Защита данных**:
* **Управление доступом**: Команды `CREATE ROLE`, `GRANT` (дать права), `REVOKE` (забрать права).
* **Политики безопасности (RLS)**: Команда `ALTER TABLE ... ENABLE ROW LEVEL SECURITY`. Позволяет скрыть строки таблицы от определенных пользователей.
* **Шифрование**: Модуль `pgcrypto` (для данных внутри таблиц) и SSL (для защиты сетевого трафика).
---
### Часть 2: Практика (пошаговое выполнение)
#### Шаг 1: Создание основной таблицы
Откройте **Query Tool** (кнопка с молнией в pgAdmin) и выполните:
```sql
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username TEXT NOT NULL,
email TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```
#### Шаг 2: Создание таблицы для хранения аудита
В эту таблицу будут записываться все изменения.
```sql
CREATE TABLE users_log (
log_id SERIAL PRIMARY KEY,
user_id INT,
operation TEXT,
changed_by TEXT,
changed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
data_json JSONB
);
```
#### Шаг 3: Создание функции аудита
Эта функция определяет, что именно будет сохраняться при изменениях.
```sql
CREATE OR REPLACE FUNCTION log_users_changes()
RETURNS TRIGGER AS $$
BEGIN
IF (TG_OP = 'DELETE') THEN
INSERT INTO users_log (user_id, operation, changed_by, data_json)
VALUES (OLD.id, TG_OP, current_user, to_jsonb(OLD));
RETURN OLD;
ELSE
INSERT INTO users_log (user_id, operation, changed_by, data_json)
VALUES (NEW.id, TG_OP, current_user, to_jsonb(NEW));
RETURN NEW;
END IF;
END;
$$ LANGUAGE plpgsql;
```
#### Шаг 4: Привязка триггера к таблице
Теперь при каждом INSERT, UPDATE или DELETE функция будет срабатывать автоматически.
```sql
CREATE TRIGGER trg_users_audit
AFTER INSERT OR UPDATE OR DELETE ON users
FOR EACH ROW EXECUTE FUNCTION log_users_changes();
```
#### Шаг 5: Генерация отчета за последний месяц
Этот запрос выводит все события аудита за последние 30 дней.
```sql
SELECT
log_id,
user_id,
operation,
changed_by,
changed_at,
data_json
FROM users_log
WHERE changed_at >= NOW() - INTERVAL '1 month'
ORDER BY changed_at DESC;
```
#### Шаг 6: Настройка уведомлений (LISTEN / NOTIFY)
В PostgreSQL нет прямого SMTP-клиента внутри ядра (как Database Mail в SQL Server). Профессиональный способ — использование системы сигналов.
Добавьте эту строку внутрь функции `log_users_changes` (перед `RETURN`):
```sql
PERFORM pg_notify('user_change_event', 'Action: ' || TG_OP || ' by ' || current_user);
```
**Как это работает:**
1. База отправляет сигнал `pg_notify`.
2. Внешний скрипт (например, на Python) слушает этот канал и отправляет Email.
Если на экзамене требуют именно SQL-код для отправки почты (имитация Database Mail), можно использовать расширение `plpython3u`, но для базового уровня достаточно описать механизм **NOTIFY** или использование триггера для внешней очереди.
---
### Как проверить работу:
1. Выполните: `INSERT INTO users (username, email) VALUES ('admin', 'admin@test.com');`
2. Выполните: `UPDATE users SET email = 'new@test.com' WHERE id = 1;`
3. Проверьте результат в таблице логов: `SELECT * FROM users_log;`