Add initial documentation for MongoDB, Neo4j, pgAdmin, PostgreSQL, and Redis in Docker
This commit is contained in:
commit
699dd0d18f
93
README.md
Normal file
93
README.md
Normal file
@ -0,0 +1,93 @@
|
||||
# Практикум: «Работа с реляционными и нереляционными СУБД»
|
||||
|
||||
|
||||
|
||||
#### Установка Docker Desktop на Windows
|
||||
|
||||
- Требования:
|
||||
- Windows 10 21H2/22H2 (19044/19045) или Windows 11
|
||||
- Включенная виртуализация в BIOS/UEFI (Intel VT-x/AMD-V)
|
||||
- Рекомендовано: WSL 2
|
||||
|
||||
- Включить компоненты Windows (PowerShell от имени администратора):
|
||||
```powershell
|
||||
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
|
||||
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
|
||||
```
|
||||
Перезагрузите компьютер.
|
||||
|
||||
- Установить ядро WSL2 (если требуется):
|
||||
```powershell
|
||||
wsl --install --no-distribution
|
||||
wsl --update
|
||||
```
|
||||
|
||||
- Скачать и установить Docker Desktop: см. страницу загрузки [Docker Desktop for Windows](https://www.docker.com/products/docker-desktop/). Во время установки оставьте галочку «Use WSL 2 based engine».
|
||||
|
||||
- Первый запуск и базовые настройки:
|
||||
- Войти с Docker ID (или пропустить для локальной работы)
|
||||
- Settings → General: убедитесь, что «Use the WSL 2 based engine» включен
|
||||
- Settings → Resources → WSL Integration: включите интеграцию для нужных дистрибутивов WSL
|
||||
|
||||
- Проверка установки:
|
||||
```powershell
|
||||
docker version
|
||||
docker run hello-world
|
||||
docker run --rm -it alpine:3.20 echo "Docker OK"
|
||||
```
|
||||
|
||||
## PostgreSQL with Docker
|
||||
|
||||
- **Установите Docker Desktop**: Убедитесь, что Docker установлен и запущен на вашем компьютере.
|
||||
|
||||
- **Скачать образ Postgres**:
|
||||
```bash
|
||||
docker pull postgres:16
|
||||
```
|
||||
|
||||
- **Запустить контейнер PostgreSQL**:
|
||||
```bash
|
||||
docker run --name pg-local -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=appdb -p 5432:5432 -v pgdata:/var/lib/postgresql/data -d postgres:16
|
||||
```
|
||||
|
||||
- **Проверить, что контейнер запущен**:
|
||||
```bash
|
||||
docker ps
|
||||
```
|
||||
|
||||
- **Подключение к PostgreSQL**:
|
||||
- С хоста через psql (Windows PowerShell, macOS, Linux):
|
||||
```bash
|
||||
psql -h localhost -p 5432 -U postgres -d appdb
|
||||
```
|
||||
При запросе пароля введите: `postgres`.
|
||||
- URI‑строка подключения (подходит для приложений/GUI‑клиентов):
|
||||
```
|
||||
postgres://postgres:postgres@localhost:5432/appdb
|
||||
```
|
||||
- Через psql внутри контейнера:
|
||||
```bash
|
||||
docker exec -it pg-local psql -U postgres -d appdb
|
||||
```
|
||||
- Параметры для GUI‑клиента (pgAdmin, DBeaver и др.):
|
||||
- Host: `localhost`
|
||||
- Port: `5432`
|
||||
- User: `postgres`
|
||||
- Password: `postgres`
|
||||
- Database: `appdb`
|
||||
- Быстрая проверка подключения (внутри psql):
|
||||
```sql
|
||||
SELECT version();
|
||||
```
|
||||
|
||||
- **Полезные команды**:
|
||||
```bash
|
||||
# Остановить / запустить / удалить контейнер
|
||||
docker stop pg-local
|
||||
docker start pg-local
|
||||
docker rm -f pg-local
|
||||
|
||||
# Удалить том с данными (необратимо)
|
||||
docker volume rm pgdata
|
||||
```
|
||||
|
||||
111
mongo.md
Normal file
111
mongo.md
Normal file
@ -0,0 +1,111 @@
|
||||
# MongoDB: установка и базовое использование
|
||||
|
||||
Краткая инструкция по установке MongoDB на Windows и запуску в Docker, подключению через `mongosh` и базовым операциям.
|
||||
|
||||
## Вариант A: Docker (рекомендуется для практикума)
|
||||
|
||||
```bash
|
||||
# Запуск MongoDB (порт 27017), создание пользователя root
|
||||
# Замените StrongPass! на свой пароль
|
||||
|
||||
docker run -d --name mongo -p 27017:27017 -e MONGO_INITDB_ROOT_USERNAME=root -e MONGO_INITDB_ROOT_PASSWORD=StrongPass! -v mongo_data:/data/db mongo:7
|
||||
```
|
||||
|
||||
Подключение `mongosh` (если установлен локально):
|
||||
```bash
|
||||
mongosh "mongodb://root:StrongPass!@localhost:27017/?authSource=admin"
|
||||
```
|
||||
|
||||
Создание приложения БД/пользователя:
|
||||
```javascript
|
||||
use appdb
|
||||
|
||||
db.createUser({
|
||||
user: "appuser",
|
||||
pwd: "AppUserPass!",
|
||||
roles: [ { role: "readWrite", db: "appdb" } ]
|
||||
})
|
||||
```
|
||||
|
||||
Проверка записи/чтения:
|
||||
```javascript
|
||||
db.items.insertOne({ name: "sensor-1", type: "pressure", value: 28.5 })
|
||||
db.items.find()
|
||||
```
|
||||
|
||||
Останов/старт/удаление контейнера:
|
||||
```bash
|
||||
docker stop mongo && docker start mongo && docker rm -f mongo
|
||||
```
|
||||
|
||||
## Полезные команды `mongosh`
|
||||
```javascript
|
||||
// Показать базы/коллекции
|
||||
show dbs
|
||||
use appdb
|
||||
show collections
|
||||
|
||||
// CRUD
|
||||
db.devices.insertMany([{name:"compressor-A", status:"online"},{name:"compressor-B", status:"offline"}])
|
||||
db.devices.find({status:"online"})
|
||||
db.devices.updateOne({name:"compressor-B"}, {$set: {status:"online"}})
|
||||
db.devices.deleteOne({name:"compressor-A"})
|
||||
|
||||
// Индекс
|
||||
db.devices.createIndex({status:1})
|
||||
|
||||
// Фильтры (сравнение, логика, диапазоны)
|
||||
db.devices.find({status: {$in: ["online", "maintenance"]}})
|
||||
db.readings.find({value: {$gte: 10, $lt: 50}})
|
||||
db.readings.find({$and: [{type:"pressure"}, {value: {$gt: 100}}]})
|
||||
|
||||
// Проекция полей (включение/исключение)
|
||||
db.devices.find({}, {name:1, status:1, _id:0})
|
||||
|
||||
// Сортировка, лимит, пропуск
|
||||
db.readings.find({type:"temperature"}).sort({timestamp:-1}).limit(10)
|
||||
db.readings.find({type:"temperature"}).sort({timestamp:1}).skip(20).limit(10)
|
||||
|
||||
// Составной запрос: фильтр + проекция + сортировка + пагинация
|
||||
db.devices.find({status:"online"}, {name:1, status:1, _id:0}).sort({name:1}).skip(0).limit(5)
|
||||
|
||||
// Поддокументы/массивы
|
||||
db.wells.insertOne({name:"Well-1001", sensors:[{type:"pressure", value:2800},{type:"temperature", value:85}]})
|
||||
db.wells.find({"sensors.type":"pressure", "sensors.value": {$gt: 2500}})
|
||||
|
||||
|
||||
// Встроенные (embedded) документы: вложенные поля, запросы и обновления
|
||||
db.wells.insertOne({
|
||||
name: "Well-1002",
|
||||
location: { field: "Permian", coords: { lat: 31.77, lon: -102.39 } },
|
||||
equipment: {
|
||||
compressor: { model: "CMP-900", status: "online" },
|
||||
valve: { type: "pressure_relief", lastService: ISODate("2025-10-01") }
|
||||
}
|
||||
})
|
||||
|
||||
// Поиск по вложенным полям (dot-notation)
|
||||
db.wells.find({ "location.field": "Permian", "equipment.compressor.status": "online" }, { _id:0, name:1 })
|
||||
|
||||
// Проекция поддокумента
|
||||
db.wells.find({ name: "Well-1002" }, { _id:0, equipment:1 })
|
||||
|
||||
// Обновление вложенного поля
|
||||
db.wells.updateOne(
|
||||
{ name: "Well-1002" },
|
||||
{ $set: { "equipment.compressor.status": "maintenance" } }
|
||||
)
|
||||
|
||||
// Добавление нового вложенного поля, если его не было
|
||||
db.wells.updateOne(
|
||||
{ name: "Well-1002" },
|
||||
{ $set: { "equipment.sensorHub": { firmware: "1.2.3", ports: 8 } } }
|
||||
)
|
||||
|
||||
// Удаление вложенного поля
|
||||
db.wells.updateOne(
|
||||
{ name: "Well-1002" },
|
||||
{ $unset: { "equipment.valve.lastService": "" } }
|
||||
)
|
||||
```
|
||||
|
||||
55
neo4j.md
Normal file
55
neo4j.md
Normal file
@ -0,0 +1,55 @@
|
||||
# Neo4j в Docker: установка и базовое использование
|
||||
|
||||
Краткая инструкция по запуску Neo4j в Docker, подключению к Browser/bolt и базовым операциям.
|
||||
|
||||
## Запуск Neo4j (одной командой)
|
||||
|
||||
```bash
|
||||
# Откроет порты 7474 (HTTP)
|
||||
|
||||
docker run -d --name neo4j -p 7474:7474 -e NEO4J_AUTH=neo4j/neo4j -v neo4j_data:/data -v neo4j_logs:/logs -v neo4j_import:/var/lib/neo4j/import -v neo4j_plugins:/plugins neo4j:5
|
||||
```
|
||||
|
||||
- Откройте `http://localhost:7474` (Neo4j Browser)
|
||||
- Подключение по bolt: `bolt://localhost:7687`
|
||||
|
||||
## Управление контейнером
|
||||
|
||||
```bash
|
||||
docker restart neo4j
|
||||
|
||||
docker stop neo4j
|
||||
|
||||
docker rm -f neo4j
|
||||
```
|
||||
|
||||
## Переменные окружения (часто используемые)
|
||||
|
||||
- `NEO4J_AUTH=neo4j/<password>` — пароль пользователя `neo4j` (или `none` для тестов)
|
||||
|
||||
|
||||
## Подключение из CLI (cypher-shell)
|
||||
|
||||
Если установлен `cypher-shell` на хосте:
|
||||
```bash
|
||||
cypher-shell -u neo4j -p MyStrongPassword! -a bolt://localhost:7687
|
||||
```
|
||||
|
||||
Или из контейнера:
|
||||
```bash
|
||||
docker exec -it neo4j cypher-shell -u neo4j -p MyStrongPassword!
|
||||
```
|
||||
|
||||
## Базовые команды Cypher (пример)
|
||||
|
||||
```cypher
|
||||
// Создать узел
|
||||
CREATE (:Person {name: "Alice", age: 30});
|
||||
|
||||
// Найти узлы
|
||||
MATCH (p:Person) RETURN p LIMIT 10;
|
||||
|
||||
// Создать связь
|
||||
MATCH (a:Person {name:"Alice"})
|
||||
CREATE (a)-[:KNOWS]->(:Person {name:"Bob"});
|
||||
```
|
||||
46
pgadmin.md
Normal file
46
pgadmin.md
Normal file
@ -0,0 +1,46 @@
|
||||
# pgAdmin (Docker): установка и подключение к существующему PostgreSQL
|
||||
|
||||
Инструкция по запуску pgAdmin 4 в Docker и подключению к контейнеру Postgres `pg-local`.
|
||||
|
||||
## 1) Запуск pgAdmin в Docker
|
||||
|
||||
- Вариант по умолчанию (порт 5050):
|
||||
```bash
|
||||
docker run -d --name pgadmin -e PGADMIN_DEFAULT_EMAIL=admin@example.com -e PGADMIN_DEFAULT_PASSWORD=admin -p 5050:80 -v pgadmin_data:/var/lib/pgadmin dpage/pgadmin4:latest
|
||||
```
|
||||
|
||||
- Открыть интерфейс:
|
||||
- Браузер: http://localhost:5050
|
||||
- Войти с значениями `PGADMIN_DEFAULT_EMAIL` и `PGADMIN_DEFAULT_PASSWORD`.
|
||||
|
||||
## 2) Подключение к текущему Postgres (`pg-local`)
|
||||
|
||||
У вас уже запущен контейнер PostgreSQL (см. README):
|
||||
```bash
|
||||
docker run --name pg-local -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=appdb -p 5432:5432 -v pgdata:/var/lib/postgresql/data -d postgres:16
|
||||
```
|
||||
|
||||
### Подключение через опубликованный порт хоста..
|
||||
- В pgAdmin: Add New Server → вкладка General:
|
||||
- Name: `Local Postgres`
|
||||
- Вкладка Connection:
|
||||
- Host: `localhost` (если pgAdmin установлен на хосте)
|
||||
- Host: `host.docker.internal` (если pgAdmin запущен в Docker без общей сети)
|
||||
- Port: `5432`
|
||||
- Maintenance DB: `appdb` (или `postgres`)
|
||||
- Username: `postgres`
|
||||
- Password: `postgres`
|
||||
- Save Password: включить (по желанию)
|
||||
- Сохранить. Подключение установится сразу.
|
||||
|
||||
Примечание: pgAdmin открыт в вашем браузере, поэтому доступ к `localhost:5432` идёт с вашей машины.
|
||||
|
||||
## 3) Проверка соединения
|
||||
После добавления сервера в pgAdmin, раскройте дерево:
|
||||
- Servers → ваш сервер → Databases → `appdb` → Schemas → `public` → Tables
|
||||
- Откройте Query Tool и выполните:
|
||||
```sql
|
||||
SELECT version();
|
||||
SELECT current_database(), current_user, now();
|
||||
```
|
||||
|
||||
314
postgres.md
Normal file
314
postgres.md
Normal file
@ -0,0 +1,314 @@
|
||||
# Работа с PostgreSQL
|
||||
|
||||
Минимальные команды для работы с одной таблицей: подключение, создание с первичным ключом, CRUD и основные команды ALTER.
|
||||
|
||||
## Подключение (контейнер Docker)
|
||||
|
||||
```bash
|
||||
docker exec -it pg-local psql -U postgres -d appdb
|
||||
```
|
||||
## Важные slash-команды psql
|
||||
|
||||
```psql
|
||||
\? -- помощь по psql
|
||||
\l -- список баз данных
|
||||
\c appdb -- подключиться к базе appdb
|
||||
\dt -- список таблиц
|
||||
\du -- список ролей/пользователей
|
||||
\dn -- список схем
|
||||
\d contacts -- описание таблицы contacts
|
||||
\i file.sql -- выполнить SQL-скрипт из файла
|
||||
\q -- выход
|
||||
```
|
||||
Выйти: `\q`.
|
||||
|
||||
## Рекомендации по именованию (best practices)
|
||||
|
||||
- Таблицы и столбцы: `snake_case`, английские названия; будьте последовательны (единственное или множественное число — выберите и придерживайтесь).
|
||||
- Первичный ключ: как правило `id` типа `BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY`.
|
||||
- Внешние ключи: `<referenced_table>_id`, тот же тип, что и PK ссылочной таблицы.
|
||||
- Метки времени: `created_at`, `updated_at` типа `TIMESTAMPTZ`; задавайте `DEFAULT now()` и `NOT NULL`.
|
||||
- Уникальные ограничения: `uq_<table>__<col>[_<col2>]`.
|
||||
- Первичный ключ: `pk_<table>` (имя создаётся автоматически, но можно переопределить).
|
||||
- Внешние ключи: `fk_<table>__<ref_table>`.
|
||||
- Индексы: `idx_<table>__<col>[_<col2>]`.
|
||||
|
||||
Пример (рекомендуемая версия таблиц):
|
||||
```sql
|
||||
CREATE TABLE contacts (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
full_name TEXT NOT NULL,
|
||||
email TEXT,
|
||||
department_id BIGINT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
CONSTRAINT uq_contacts__email UNIQUE (email)
|
||||
);
|
||||
|
||||
CREATE TABLE departments (
|
||||
department_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
CONSTRAINT uq_departments__name UNIQUE (name)
|
||||
);
|
||||
|
||||
ALTER TABLE contacts
|
||||
ADD CONSTRAINT fk_contacts__departments
|
||||
FOREIGN KEY (department_id)
|
||||
REFERENCES departments(department_id)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE SET NULL;
|
||||
|
||||
-- Индексы
|
||||
CREATE INDEX idx_contacts__department_id ON contacts(department_id);
|
||||
CREATE INDEX idx_contacts__full_name ON contacts(full_name);
|
||||
```
|
||||
|
||||
## Создание таблицы (с первичным ключом)
|
||||
|
||||
```sql
|
||||
CREATE TABLE contacts (
|
||||
id SERIAL PRIMARY KEY,
|
||||
full_name TEXT NOT NULL,
|
||||
email TEXT UNIQUE,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
```
|
||||
|
||||
## Операции CRUD
|
||||
|
||||
```sql
|
||||
-- Создать запись
|
||||
INSERT INTO contacts (full_name, email)
|
||||
VALUES ('Alice Johnson', 'alice@example.com');
|
||||
|
||||
-- Прочитать записи
|
||||
SELECT id, full_name, email, created_at
|
||||
FROM contacts
|
||||
ORDER BY id
|
||||
LIMIT 10;
|
||||
|
||||
-- Обновить запись
|
||||
UPDATE contacts
|
||||
SET email = 'alice@newmail.com'
|
||||
WHERE id = 1;
|
||||
|
||||
-- Удалить запись
|
||||
DELETE FROM contacts
|
||||
WHERE id = 1;
|
||||
```
|
||||
|
||||
### Работа с NULL
|
||||
|
||||
```sql
|
||||
-- Вставить запись без email (NULL)
|
||||
INSERT INTO contacts (full_name, email) VALUES ('No Email User', NULL);
|
||||
|
||||
-- Найти записи с отсутствующим email
|
||||
SELECT id, full_name, email FROM contacts WHERE email IS NULL;
|
||||
|
||||
-- Найти записи, где email указан
|
||||
SELECT id, full_name, email FROM contacts WHERE email IS NOT NULL;
|
||||
|
||||
-- Подставить значение по умолчанию, если email NULL
|
||||
SELECT id, full_name, COALESCE(email, 'no-email@example.com') AS safe_email
|
||||
FROM contacts;
|
||||
|
||||
```
|
||||
|
||||
## Основные команды ALTER TABLE
|
||||
|
||||
```sql
|
||||
-- Добавить столбец
|
||||
ALTER TABLE contacts ADD COLUMN phone TEXT;
|
||||
|
||||
-- Переименовать столбец
|
||||
ALTER TABLE contacts RENAME COLUMN phone TO phone_number;
|
||||
|
||||
-- Удалить столбец
|
||||
ALTER TABLE contacts DROP COLUMN phone_number;
|
||||
|
||||
-- Изменить тип столбца (пример: TEXT -> VARCHAR)
|
||||
ALTER TABLE contacts ALTER COLUMN full_name TYPE VARCHAR(200);
|
||||
|
||||
-- Добавить первичный ключ в существующую таблицу (если отсутствует)
|
||||
ALTER TABLE contacts ADD COLUMN id SERIAL;
|
||||
ALTER TABLE contacts ADD PRIMARY KEY (id);
|
||||
|
||||
-- Удалить первичный ключ
|
||||
ALTER TABLE contacts DROP CONSTRAINT contacts_pkey;
|
||||
|
||||
-- Переименовать таблицу
|
||||
ALTER TABLE contacts RENAME TO people;
|
||||
```
|
||||
|
||||
## Работа с несколькими таблицами (две)
|
||||
|
||||
Добавим таблицу `departments` и внешний ключ из `contacts` на `departments`.
|
||||
|
||||
```sql
|
||||
-- Создать таблицу отделов
|
||||
CREATE TABLE departments (
|
||||
department_id SERIAL PRIMARY KEY,
|
||||
name TEXT NOT NULL UNIQUE
|
||||
);
|
||||
|
||||
-- Вернуть имя таблицы people обратно, если переименовывали ранее
|
||||
ALTER TABLE IF EXISTS people RENAME TO contacts;
|
||||
|
||||
-- Добавить внешний ключ на departments
|
||||
ALTER TABLE contacts ADD COLUMN department_id INT;
|
||||
ALTER TABLE contacts
|
||||
ADD CONSTRAINT contacts_department_fk
|
||||
FOREIGN KEY (department_id)
|
||||
REFERENCES departments(department_id)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE SET NULL;
|
||||
```
|
||||
|
||||
Пример данных:
|
||||
```sql
|
||||
INSERT INTO departments (name) VALUES ('Sales'), ('Engineering'), ('HR');
|
||||
|
||||
UPDATE contacts SET department_id = 1 WHERE id = 1; -- Alice -> Sales
|
||||
-- При необходимости добавьте больше контактов аналогично
|
||||
```
|
||||
|
||||
### Примеры JOIN
|
||||
|
||||
```sql
|
||||
-- INNER JOIN: только совпадающие записи
|
||||
SELECT c.id, c.full_name, d.name AS department
|
||||
FROM contacts c
|
||||
JOIN departments d ON d.department_id = c.department_id;
|
||||
|
||||
-- LEFT JOIN: все контакты, даже без отдела
|
||||
SELECT c.id, c.full_name, d.name AS department
|
||||
FROM contacts c
|
||||
LEFT JOIN departments d ON d.department_id = c.department_id;
|
||||
|
||||
-- RIGHT JOIN: все отделы, даже без контактов
|
||||
SELECT c.id, c.full_name, d.name AS department
|
||||
FROM contacts c
|
||||
RIGHT JOIN departments d ON d.department_id = c.department_id;
|
||||
|
||||
-- FULL OUTER JOIN: объединение LEFT и RIGHT
|
||||
SELECT c.id, c.full_name, d.name AS department
|
||||
FROM contacts c
|
||||
FULL JOIN departments d ON d.department_id = c.department_id;
|
||||
```
|
||||
|
||||
### UNION и INTERSECT
|
||||
|
||||
```sql
|
||||
-- UNION: объединить результаты (уникальные строки)
|
||||
SELECT full_name AS item FROM contacts
|
||||
UNION
|
||||
SELECT name AS item FROM departments;
|
||||
|
||||
-- INTERSECT: пересечение множеств
|
||||
-- (искусственный пример: найдём такие строки, где имя контакта совпадает с названием отдела)
|
||||
SELECT full_name FROM contacts
|
||||
INTERSECT
|
||||
SELECT name FROM departments;
|
||||
```
|
||||
|
||||
### Оконные функции (window functions) на примере компаний нефти и газа
|
||||
|
||||
Создадим отдельную таблицу `companies` с повторяющимися данными для примеров.
|
||||
|
||||
```sql
|
||||
CREATE TABLE companies (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
company_name TEXT NOT NULL,
|
||||
sector TEXT NOT NULL, -- 'Oil' | 'Gas'
|
||||
country TEXT NOT NULL, -- страна регистрации
|
||||
revenue_usd NUMERIC(14,2) NOT NULL, -- выручка
|
||||
employees INT NOT NULL, -- число сотрудников
|
||||
founded_year INT, -- год основания (может повторяться)
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
INSERT INTO companies (company_name, sector, country, revenue_usd, employees, founded_year) VALUES
|
||||
('PetroOne', 'Oil', 'USA', 1200000.00, 5000, 1980),
|
||||
('GasPrime', 'Gas', 'USA', 800000.00, 3200, 1990),
|
||||
('NordOil', 'Oil', 'Norway',950000.00, 2100, 1975),
|
||||
('EuroGas', 'Gas', 'Norway',400000.00, 1500, 2001),
|
||||
('OilAsia', 'Oil', 'UAE', 2200000.00, 9000, 1970),
|
||||
('GasEast', 'Gas', 'UAE', 1300000.00, 4800, 1988),
|
||||
('LatOil', 'Oil', 'Brazil', 500000.00, 1200, 2005),
|
||||
('SouthGas', 'Gas', 'Brazil', 350000.00, 900, 2005),
|
||||
('OilAsia-2', 'Oil', 'UAE', 1600000.00, 6000, 1970); -- повторяющиеся страна/год/sector
|
||||
```
|
||||
|
||||
Группировки, фильтрация (HAVING), сортировка и LIMIT:
|
||||
|
||||
```sql
|
||||
-- Выручка и среднее число сотрудников по сектору
|
||||
SELECT sector,
|
||||
SUM(revenue_usd) AS total_revenue,
|
||||
AVG(employees)::INT AS avg_employees
|
||||
FROM companies
|
||||
GROUP BY sector
|
||||
HAVING SUM(revenue_usd) > 1000000 -- оставить только сектора с суммарной выручкой > 1 млн
|
||||
ORDER BY total_revenue DESC
|
||||
LIMIT 10;
|
||||
|
||||
-- По стране и сектору
|
||||
SELECT country, sector,
|
||||
COUNT(*) AS num_companies,
|
||||
SUM(revenue_usd) AS total_revenue
|
||||
FROM companies
|
||||
GROUP BY country, sector
|
||||
ORDER BY total_revenue DESC, country;
|
||||
```
|
||||
|
||||
Примеры оконных функций:
|
||||
|
||||
```sql
|
||||
-- Нумерация компаний внутри сектора по выручке (от большей к меньшей)
|
||||
SELECT company_name, sector, revenue_usd,
|
||||
ROW_NUMBER() OVER (PARTITION BY sector ORDER BY revenue_usd DESC) AS rn_in_sector
|
||||
FROM companies
|
||||
ORDER BY sector, rn_in_sector;
|
||||
|
||||
-- Ранги: RANK (с пропусками), DENSE_RANK (без пропусков) внутри сектора
|
||||
SELECT company_name, sector, revenue_usd,
|
||||
RANK() OVER (PARTITION BY sector ORDER BY revenue_usd DESC) AS rnk,
|
||||
DENSE_RANK() OVER (PARTITION BY sector ORDER BY revenue_usd DESC) AS drnk
|
||||
FROM companies
|
||||
ORDER BY sector, rnk;
|
||||
|
||||
-- Сумма и среднее по стране (окно PARTITION BY)
|
||||
SELECT company_name, country, revenue_usd,
|
||||
SUM(revenue_usd) OVER (PARTITION BY country) AS country_revenue_total,
|
||||
AVG(revenue_usd) OVER (PARTITION BY country) AS country_revenue_avg
|
||||
FROM companies
|
||||
ORDER BY country, revenue_usd DESC;
|
||||
|
||||
-- Скользящее среднее по выручке внутри сектора (окно 1 предыдущая, текущая, 1 следующая)
|
||||
SELECT company_name, sector, revenue_usd,
|
||||
AVG(revenue_usd) OVER (
|
||||
PARTITION BY sector
|
||||
ORDER BY revenue_usd
|
||||
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
|
||||
) AS moving_avg_in_sector
|
||||
FROM companies
|
||||
ORDER BY sector, revenue_usd;
|
||||
|
||||
-- Процентильные ранги и квартиль (NTILE)
|
||||
SELECT company_name, sector, revenue_usd,
|
||||
PERCENT_RANK() OVER (PARTITION BY sector ORDER BY revenue_usd) AS percent_rank_in_sector,
|
||||
CUME_DIST() OVER (PARTITION BY sector ORDER BY revenue_usd) AS cume_dist_in_sector,
|
||||
NTILE(4) OVER (PARTITION BY sector ORDER BY revenue_usd) AS quartile_in_sector
|
||||
FROM companies
|
||||
ORDER BY sector, revenue_usd;
|
||||
|
||||
-- LAG/LEAD: сравнение с соседями по выручке внутри сектора
|
||||
SELECT company_name, sector, revenue_usd,
|
||||
LAG(revenue_usd) OVER (PARTITION BY sector ORDER BY revenue_usd) AS prev_revenue,
|
||||
LEAD(revenue_usd) OVER (PARTITION BY sector ORDER BY revenue_usd) AS next_revenue
|
||||
FROM companies
|
||||
ORDER BY sector, revenue_usd;
|
||||
```
|
||||
|
||||
|
||||
173
redis.md
Normal file
173
redis.md
Normal file
@ -0,0 +1,173 @@
|
||||
# Redis в Docker: установка и базовые команды
|
||||
|
||||
Краткая инструкция по запуску Redis в Docker и использованию `redis-cli`.
|
||||
|
||||
## Установка/запуск Redis в Docker
|
||||
|
||||
- Запустить Redis (порт 6379):
|
||||
```bash
|
||||
docker run -d --name redis -p 6379:6379 redis:7
|
||||
```
|
||||
|
||||
- Перезапуск/остановка/удаление:
|
||||
```bash
|
||||
docker restart redis
|
||||
```
|
||||
```bash
|
||||
docker stop redis
|
||||
```
|
||||
```bash
|
||||
docker rm -f redis
|
||||
```
|
||||
|
||||
## Подключение к Redis
|
||||
|
||||
- Из контейнера (встроенный `redis-cli`):
|
||||
```bash
|
||||
docker exec -it redis redis-cli
|
||||
```
|
||||
|
||||
- С хоста (если установлен `redis-cli`):
|
||||
```bash
|
||||
redis-cli -h 127.0.0.1 -p 6379
|
||||
```
|
||||
|
||||
- Проверка доступности:
|
||||
```bash
|
||||
redis-cli -h 127.0.0.1 -p 6379 PING
|
||||
# Ответ: PONG
|
||||
```
|
||||
|
||||
## Базовые команды (ключ-значение)
|
||||
|
||||
```redis
|
||||
# Имена скважин
|
||||
SET well:1001:name "Well-1001"
|
||||
GET well:1001:name
|
||||
|
||||
# Счетчики добычи (баррели нефти)
|
||||
SETNX counters:production:well:1001:bbl 0
|
||||
INCR counters:production:well:1001:bbl
|
||||
INCRBY counters:production:well:1001:bbl 250
|
||||
DECR counters:production:well:1001:bbl
|
||||
|
||||
# Массовая запись/чтение параметров месторождения
|
||||
MSET field:permian:name Permian field:permian:country USA field:permian:type oil
|
||||
MGET field:permian:name field:permian:country field:permian:type
|
||||
|
||||
# Удаление и проверка существования
|
||||
DEL field:permian:type
|
||||
EXISTS well:1001:name
|
||||
TTL counters:production:well:1001:bbl
|
||||
```
|
||||
|
||||
## Время жизни/истечение
|
||||
|
||||
```redis
|
||||
# Кэш телеметрии датчика давления (истекает через 5 минут)
|
||||
SET sensor:well:1001:pressure:psi "2850" EX 300
|
||||
|
||||
# Продлить TTL еще на 60 секунд
|
||||
EXPIRE sensor:well:1001:pressure:psi 60
|
||||
|
||||
# Сделать запись постоянной
|
||||
PERSIST sensor:well:1001:pressure:psi
|
||||
```
|
||||
|
||||
## Поиск ключей и очистка
|
||||
|
||||
```redis
|
||||
KEYS well:*
|
||||
```
|
||||
|
||||
## Структуризация команд
|
||||
|
||||
### 1) Простые типы: строки и числа
|
||||
|
||||
```redis
|
||||
# Строки состояния
|
||||
SET well:1001:status "online"
|
||||
GET well:1001:status
|
||||
|
||||
# Множественная запись паспортных данных скважины
|
||||
MSET well:1001:field Permian well:1001:type oil well:1001:depth_m 3200
|
||||
MGET well:1001:field well:1001:type well:1001:depth_m
|
||||
|
||||
# Только если ключ не существует (инициализация счетчика газа, тыс. куб. футов)
|
||||
SETNX counters:gas:well:1001:mcf 0
|
||||
|
||||
# Инкременты/декременты
|
||||
INCR counters:gas:well:1001:mcf
|
||||
INCRBY counters:gas:well:1001:mcf 500
|
||||
DECR counters:gas:well:1001:mcf
|
||||
|
||||
# Полезное: журнал операций
|
||||
APPEND ops:log "start_pump;"
|
||||
STRLEN ops:log
|
||||
GETSET last:ops:timestamp "2025-10-28T10:00:00Z"
|
||||
DEL ops:log well:1001:status
|
||||
EXISTS counters:gas:well:1001:mcf
|
||||
```
|
||||
|
||||
### 2) Списки (queues/стэки)
|
||||
|
||||
```redis
|
||||
# Очередь работ по обслуживанию
|
||||
LPUSH jobs:maintenance well:1001:inspect well:1002:replace_valve
|
||||
RPUSH jobs:maintenance well:1003:calibrate_sensor
|
||||
|
||||
# Изъятие задач
|
||||
LPOP jobs:maintenance
|
||||
RPOP jobs:maintenance
|
||||
|
||||
# Диапазон и метаданные
|
||||
LRANGE jobs:maintenance 0 -1
|
||||
LLEN jobs:maintenance
|
||||
LINDEX jobs:maintenance 0
|
||||
|
||||
# Блокирующие операции (ожидание новой задачи)
|
||||
BLPOP jobs:maintenance 5
|
||||
BRPOP jobs:maintenance 5
|
||||
|
||||
# Удаление конкретной задачи
|
||||
LREM jobs:maintenance 0 well:1002:replace_valve
|
||||
```
|
||||
|
||||
### 3) Хэши (похожие на объекты)
|
||||
|
||||
```redis
|
||||
# Паспорт скважины
|
||||
HSET well:1001 name "Well-1001" field "Permian" status "online" depth_m 3200
|
||||
HGET well:1001 name
|
||||
HMGET well:1001 field status depth_m
|
||||
HGETALL well:1001
|
||||
|
||||
# Управление полями
|
||||
HDEL well:1001 status
|
||||
HEXISTS well:1001 field
|
||||
HLEN well:1001
|
||||
|
||||
# Счетчики в хэше (например, количество запусков насоса)
|
||||
HINCRBY well:1001 metrics:pump_starts 1
|
||||
```
|
||||
|
||||
### 4) Множества (уникальные элементы, без порядка)
|
||||
|
||||
```redis
|
||||
# Скважины по месторождениям
|
||||
SADD field:permian:wells 1001 1002
|
||||
SADD field:west_siberia:wells 1002 1003
|
||||
SMEMBERS field:permian:wells
|
||||
SCARD field:west_siberia:wells
|
||||
|
||||
# Операции множеств (пересечения/объединения между полями)
|
||||
SUNION field:permian:wells field:west_siberia:wells # 1001 1002 1003
|
||||
SINTER field:permian:wells field:west_siberia:wells # 1002
|
||||
SDIFF field:permian:wells field:west_siberia:wells # 1001
|
||||
|
||||
# Теги оборудования на скважине
|
||||
SADD well:1001:tags oil onshore artificial_lift
|
||||
SISMEMBER well:1001:tags oil
|
||||
```
|
||||
|
||||
> Примечание: отсортированные множества (ZSET) и другие структуры (Streams, Bitmaps, HyperLogLog) можно добавить позже по мере необходимости.
|
||||
Loading…
Reference in New Issue
Block a user