mirror of
https://github.com/Dannecron/netology-devops.git
synced 2025-12-25 15:22:37 +03:00
add homework 6.4: tasks 1-3
This commit is contained in:
@@ -27,3 +27,4 @@
|
||||
* [6.1. Типы и структура СУБД](/src/homework/06-database/6.1)
|
||||
* [6.2. SQL](/src/homework/06-database/6.2)
|
||||
* [6.3. MySQL](/src/homework/06-database/6.3)
|
||||
* [6.4. PostgreSQL](/src/homework/06-database/6.4)
|
||||
|
||||
@@ -46,7 +46,7 @@ docker-compose exec postgres sh
|
||||
createdb --username=admin some_db
|
||||
```
|
||||
|
||||
Далее создадим пользователей. Для начала подключимся к БД с помощью утилиты psql:
|
||||
Далее создадим пользователей. Для начала подключимся к БД с помощью утилиты `psql`:
|
||||
```shell
|
||||
docker-compose exec postgres psql --username=admin --dbname=test_db
|
||||
```
|
||||
|
||||
19
src/homework/06-database/6.4/docker-compose.yml
Normal file
19
src/homework/06-database/6.4/docker-compose.yml
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:13.5-alpine
|
||||
environment:
|
||||
POSTGRES_USER: admin
|
||||
POSTGRES_PASSWORD: 123
|
||||
POSTGRES_DB: test_database
|
||||
PGDATA: /var/lib/postgresql/data/pgdata
|
||||
ports:
|
||||
- "25432:5432"
|
||||
volumes:
|
||||
- netology_pgdata:/var/lib/postgresql/data/pgdata
|
||||
- ./dump:/opt/dump
|
||||
|
||||
volumes:
|
||||
netology_pgdata:
|
||||
99
src/homework/06-database/6.4/dump/test_dump.sql
Normal file
99
src/homework/06-database/6.4/dump/test_dump.sql
Normal file
@@ -0,0 +1,99 @@
|
||||
--
|
||||
-- PostgreSQL database dump
|
||||
--
|
||||
|
||||
-- Dumped from database version 13.0 (Debian 13.0-1.pgdg100+1)
|
||||
-- Dumped by pg_dump version 13.0 (Debian 13.0-1.pgdg100+1)
|
||||
|
||||
SET statement_timeout = 0;
|
||||
SET lock_timeout = 0;
|
||||
SET idle_in_transaction_session_timeout = 0;
|
||||
SET client_encoding = 'UTF8';
|
||||
SET standard_conforming_strings = on;
|
||||
SELECT pg_catalog.set_config('search_path', '', false);
|
||||
SET check_function_bodies = false;
|
||||
SET xmloption = content;
|
||||
SET client_min_messages = warning;
|
||||
SET row_security = off;
|
||||
|
||||
SET default_tablespace = '';
|
||||
|
||||
SET default_table_access_method = heap;
|
||||
|
||||
--
|
||||
-- Name: orders; Type: TABLE; Schema: public; Owner: postgres
|
||||
--
|
||||
|
||||
CREATE TABLE public.orders (
|
||||
id integer NOT NULL,
|
||||
title character varying(80) NOT NULL,
|
||||
price integer DEFAULT 0
|
||||
);
|
||||
|
||||
|
||||
ALTER TABLE public.orders OWNER TO postgres;
|
||||
|
||||
--
|
||||
-- Name: orders_id_seq; Type: SEQUENCE; Schema: public; Owner: postgres
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.orders_id_seq
|
||||
AS integer
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
ALTER TABLE public.orders_id_seq OWNER TO postgres;
|
||||
|
||||
--
|
||||
-- Name: orders_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.orders_id_seq OWNED BY public.orders.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: orders id; Type: DEFAULT; Schema: public; Owner: postgres
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.orders ALTER COLUMN id SET DEFAULT nextval('public.orders_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Data for Name: orders; Type: TABLE DATA; Schema: public; Owner: postgres
|
||||
--
|
||||
|
||||
COPY public.orders (id, title, price) FROM stdin;
|
||||
1 War and peace 100
|
||||
2 My little database 500
|
||||
3 Adventure psql time 300
|
||||
4 Server gravity falls 300
|
||||
5 Log gossips 123
|
||||
6 WAL never lies 900
|
||||
7 Me and my bash-pet 499
|
||||
8 Dbiezdmin 501
|
||||
\.
|
||||
|
||||
|
||||
--
|
||||
-- Name: orders_id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres
|
||||
--
|
||||
|
||||
SELECT pg_catalog.setval('public.orders_id_seq', 8, true);
|
||||
|
||||
|
||||
--
|
||||
-- Name: orders orders_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.orders
|
||||
ADD CONSTRAINT orders_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- PostgreSQL database dump complete
|
||||
--
|
||||
|
||||
205
src/homework/06-database/6.4/readme.md
Normal file
205
src/homework/06-database/6.4/readme.md
Normal file
@@ -0,0 +1,205 @@
|
||||
Выполнение [домашнего задания](https://github.com/netology-code/virt-homeworks/blob/master/06-db-04-postgresql/README.md)
|
||||
по теме "6.4. PostgreSQL".
|
||||
|
||||
## Q/A
|
||||
|
||||
### Задача 1
|
||||
|
||||
> Используя docker поднимите инстанс PostgreSQL (версию 13). Данные БД сохраните в volume.
|
||||
>
|
||||
> Подключитесь к БД PostgreSQL используя `psql`.
|
||||
>
|
||||
> Воспользуйтесь командой `\?` для вывода подсказки по имеющимся в `psql` управляющим командам.
|
||||
>
|
||||
> **Найдите и приведите** управляющие команды для:
|
||||
> - вывода списка БД
|
||||
> - подключения к БД
|
||||
> - вывода списка таблиц
|
||||
> - вывода описания содержимого таблиц
|
||||
> - выхода из psql
|
||||
|
||||
Запуск postgresql в docker-контейнере производится с использованием конфигурации [docker-compose.yml](./docker-compose.yml).
|
||||
|
||||
Для подключения к БД с использованием `psql` нужно выполнить следующую команду:
|
||||
|
||||
```shell
|
||||
docker-compose exec postgres psql --username=admin --dbname=test_db
|
||||
```
|
||||
|
||||
Команды работы с БД:
|
||||
|
||||
```shell
|
||||
# вывод списка БД
|
||||
\l
|
||||
List of databases
|
||||
Name | Owner | Encoding | Collate | Ctype | Access privileges
|
||||
-----------+-------+----------+------------+------------+-------------------
|
||||
postgres | admin | UTF8 | en_US.utf8 | en_US.utf8 |
|
||||
template0 | admin | UTF8 | en_US.utf8 | en_US.utf8 | =c/admin +
|
||||
| | | | | admin=CTc/admin
|
||||
template1 | admin | UTF8 | en_US.utf8 | en_US.utf8 | =c/admin +
|
||||
| | | | | admin=CTc/admin
|
||||
test_db | admin | UTF8 | en_US.utf8 | en_US.utf8 |
|
||||
|
||||
# подключение к БД
|
||||
\c postgres
|
||||
You are now connected to database "postgres" as user "admin".
|
||||
|
||||
# вывод списка таблиц
|
||||
\dt
|
||||
List of relations
|
||||
Schema | Name | Type | Owner
|
||||
--------+---------+-------+-------
|
||||
public | clients | table | admin
|
||||
public | orders | table | admin
|
||||
|
||||
# вывод описания содержимого таблиц
|
||||
\d orders
|
||||
Table "public.orders"
|
||||
Column | Type | Collation | Nullable | Default
|
||||
--------+------------------------+-----------+----------+------------------------------------
|
||||
id | integer | | not null | nextval('orders_id_seq'::regclass)
|
||||
name | character varying(255) | | |
|
||||
price | integer | | |
|
||||
Indexes:
|
||||
"orders_pkey" PRIMARY KEY, btree (id)
|
||||
Referenced by:
|
||||
TABLE "clients" CONSTRAINT "client_order_fk" FOREIGN KEY (order_id) REFERENCES orders(id) ON DELETE CASCADE
|
||||
|
||||
# выход из psql
|
||||
\q
|
||||
```
|
||||
|
||||
### Задача 2
|
||||
|
||||
> Используя `psql` создайте БД `test_database`.
|
||||
>
|
||||
> Изучите [бэкап БД](./dump/test_dump.sql).
|
||||
>
|
||||
> Восстановите бэкап БД в `test_database`.
|
||||
>
|
||||
> Перейдите в управляющую консоль `psql` внутри контейнера.
|
||||
>
|
||||
> Подключитесь к восстановленной БД и проведите операцию ANALYZE для сбора статистики по таблице.
|
||||
>
|
||||
> Используя таблицу [pg_stats](https://postgrespro.ru/docs/postgresql/13/view-pg-stats), найдите столбец таблицы `orders`
|
||||
> с наибольшим средним значением размера элементов в байтах.
|
||||
>
|
||||
> **Приведите в ответе** команду, которую вы использовали для вычисления и полученный результат.
|
||||
|
||||
Для восстановления дампа нужно выполнить следующую последовательность команд:
|
||||
|
||||
```shell
|
||||
docker-compose exec postgres sh
|
||||
cd /opt/dump/
|
||||
psql -Uadmin -dtest_database < test_dump.sql
|
||||
psql -Uadmin -dtest_database
|
||||
\dt
|
||||
List of relations
|
||||
Schema | Name | Type | Owner
|
||||
--------+--------+-------+-------
|
||||
public | orders | table | admin
|
||||
(1 row)
|
||||
```
|
||||
|
||||
Для сбора статистики по таблице, нужно выполнить следующий запрос:
|
||||
|
||||
```sql
|
||||
analyze verbose orders;
|
||||
-- INFO: analyzing "public.orders"
|
||||
-- INFO: "orders": scanned 1 of 1 pages, containing 8 live rows and 0 dead rows; 8 rows in sample, 8 estimated total rows
|
||||
-- ANALYZE
|
||||
```
|
||||
|
||||
Вывод информации по таблице:
|
||||
|
||||
```sql
|
||||
select tablename, attname, avg_width from pg_stats where tablename like 'orders';
|
||||
-- tablename | attname | avg_width
|
||||
-- -----------+---------+-----------
|
||||
-- orders | id | 4
|
||||
-- orders | title | 16
|
||||
-- orders | price | 4
|
||||
-- (3 rows)
|
||||
```
|
||||
|
||||
Таким образом, наибольшее среднее значение размера элементов у столбца `title` с размером 16 байт.
|
||||
|
||||
### Задача 3
|
||||
|
||||
> Архитектор и администратор БД выяснили, что ваша таблица orders разрослась до невиданных размеров и
|
||||
> поиск по ней занимает долгое время. Вам, как успешному выпускнику курсов DevOps в нетологии предложили
|
||||
> провести разбиение таблицы на 2 (шардировать на orders_1 - price>499 и orders_2 - price<=499).
|
||||
>
|
||||
> Предложите SQL-транзакцию для проведения данной операции.
|
||||
>
|
||||
> Можно ли было изначально исключить "ручное" разбиение при проектировании таблицы orders?
|
||||
|
||||
Для партицирования существующей таблицы (шардирование таблицы в рамках текущего инстанса БД)
|
||||
необходимо использовать функционал наследования и создать две таблицы, которые наследуют базовую.
|
||||
|
||||
```sql
|
||||
create table orders_1 (
|
||||
constraint pk_orders_1 primary key (id),
|
||||
constraint ck_orders_1 check ( price > 499)
|
||||
) inherits (orders);
|
||||
|
||||
create table orders_2 (
|
||||
constraint pk_orders_2 primary key (id),
|
||||
constraint ck_orders_2 check ( price <= 499)
|
||||
) inherits (orders);
|
||||
```
|
||||
|
||||
При этом, запись в основную таблицу не переведёт данные в дочерние таблицы. Для этого необходимо написать триггер,
|
||||
который будет все новые данные записывать в дочерние таблицы:
|
||||
|
||||
```sql
|
||||
CREATE OR REPLACE FUNCTION insert_new_order()
|
||||
RETURNS TRIGGER AS $$
|
||||
begin
|
||||
if (NEW.price > 499) then
|
||||
insert into orders_1 values (NEW.*);
|
||||
else
|
||||
insert into orders_2 values (NEW.*);
|
||||
end if;
|
||||
|
||||
return null;
|
||||
end;
|
||||
$$
|
||||
LANGUAGE plpgsql;
|
||||
|
||||
create trigger insert_new_orders_trigger
|
||||
before insert on orders
|
||||
for each row execute function insert_new_order();
|
||||
```
|
||||
|
||||
Теперь новые данные, которые будут записываться в таблицу `orders` будут физически попадать в одну из таблиц `orders_1` или `orders_2`,
|
||||
но при этом при запросе к родительской таблице эти данные будут видны.
|
||||
|
||||
На этапе проектирования структуры БД необходимо выделять таблицы, которые будут иметь очень большой размер.
|
||||
В этом случае можно использовать нативный функционал партицирования, который может быть активирован только при создании таблицы.
|
||||
|
||||
Таким образом, создание таблицы `orders` в самом начале создания схемы выглядело бы следующим образом:
|
||||
|
||||
```sql
|
||||
CREATE TABLE orders (
|
||||
id serial4 NOT NULL,
|
||||
title varchar(80) NOT NULL,
|
||||
price int4 NULL DEFAULT 0,
|
||||
CONSTRAINT orders_pkey PRIMARY KEY (id)
|
||||
) PARTITION BY RANGE (price);
|
||||
|
||||
CREATE TABLE orders_1 PARTITION OF orders
|
||||
FOR VALUES FROM (500) TO (maxvalue);
|
||||
|
||||
CREATE TABLE orders_2 PARTITION OF orders
|
||||
FOR VALUES FROM (minvalue) to (500);
|
||||
```
|
||||
|
||||
### Задача 4
|
||||
|
||||
> Используя утилиту `pg_dump` создайте бекап БД `test_database`.
|
||||
>
|
||||
> Как бы вы доработали бэкап-файл, чтобы добавить уникальность значения столбца `title` для таблиц `test_database`?
|
||||
|
||||
// todo
|
||||
Reference in New Issue
Block a user