Загрузка данных


Для работы в 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;`