Да, именно так. Чтобы не запутаться в старом коде и избежать ошибок, лучше всего **удалить всё и сделать заново по этой инструкции**.
Это — финальный, полностью готовый вариант твоей работы. Просто иди по шагам.
---
### ЧАСТЬ 1: Теория (говорим словами)
Когда тебя спросят по билету, отвечай так:
1. **Что такое аудит?** Это слежка за действиями в базе. Мы записываем, кто зашел, что удалил или изменил. В SQL Server это делается через «Server Audit», а в PostgreSQL — через **триггеры** и **таблицы логов**.
2. **Как защитить данные?**
* **Роли:** Создаем пользователей с разными правами (один может только смотреть, другой — менять).
* **Политики (RLS):** Ограничиваем доступ к строкам (например, каждый видит только свои записи).
* **Шифрование:** Используем SSL для защиты канала и расширение `pgcrypto` для шифрования паролей.
---
### ЧАСТЬ 2: Практика (делаем в pgAdmin)
Открой **Query Tool** и выполняй эти блоки кода по очереди (стирай старый — вставляй новый).
#### Шаг 1: Подготовка базы
```sql
DROP TRIGGER IF EXISTS trg_users_audit ON users;
DROP TABLE IF EXISTS users_log;
DROP TABLE IF EXISTS users;
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username TEXT NOT NULL,
email TEXT
);
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
);
```
#### Шаг 2: Настройка логики (Триггер и Уведомления)
```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));
ELSE
INSERT INTO users_log (user_id, operation, changed_by, data_json)
VALUES (NEW.id, TG_OP, current_user, to_jsonb(NEW));
END IF;
PERFORM pg_notify('user_mail_notification', 'Изменение в БД: ' || TG_OP || ' совершил ' || current_user);
IF (TG_OP = 'DELETE') THEN RETURN OLD; ELSE RETURN NEW; END IF;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trg_users_audit
AFTER INSERT OR UPDATE OR DELETE ON users
FOR EACH ROW EXECUTE FUNCTION log_users_changes();
```
---
### ЧАСТЬ 3: Демонстрация (что показывать учителю)
Вот сценарий твоего ответа:
**1. Подготовка (сделай это перед тем, как звать учителя):**
Вставь и выполни:
```sql
LISTEN user_mail_notification;
```
**2. Демонстрация аудита (покажи, что база «следит»):**
При учителе выполни:
```sql
INSERT INTO users (username, email) VALUES ('ivan_test', 'ivan@test.com');
UPDATE users SET email = 'new_ivan@test.com' WHERE username = 'ivan_test';
```
**3. Показ уведомления (вместо Database Mail):**
Нажми внизу на вкладку **Messages**.
*Скажи:* «Посмотрите, база отправила сигнал (NOTIFY). В реальной системе его ловит почтовый сервис и отправляет письмо администратору».
**4. Показ отчета за месяц:**
Выполни этот запрос:
```sql
SELECT * FROM users_log
WHERE changed_at >= NOW() - INTERVAL '1 month'
ORDER BY changed_at DESC;
```
*Скажи:* «Вот отчет обо всех изменениях в таблице за последний месяц. Мы видим время, тип операции и кто её совершил».
---
**Работа готова. Ты молодец!**