###### tags: `netology` `security`
# Домашнее задание к занятию "6.4. PostgreSQL"
## Задача 1
```bash=
docker run -d --name pg_docker \
-e POSTGRES_PASSWORD=postgres \
-p 5432:5432 \
-v $HOME/docker/volumes/postgres/data:/var/lib/postgresql/data \
-v $HOME/docker/volumes/postgres/bckp:/var/lib/postgresql/bckp \
postgres:13
```
### Найдите и приведите управляющие команды для:
- вывода списка БД - `\l`
- подключения к БД - `\c <db_name>`
- вывода списка таблиц - `\dt`
- вывода описания содержимого таблиц - `\d+ <table_name>`
- выхода из psql = `\q`
## Задача 2
### Используя таблицу pg_stats, найдите столбец таблицы orders с наибольшим средним значением размера элементов в байтах.
```sql=
SELECT attname, avg_width FROM pg_stats WHERE tablename = 'orders';
```
```sql=
attname | avg_width
---------+-----------
id | 4
title | 16
price | 4
(3 rows)
```
Ответ: столбец `title`
## Задача 3
### Предложите SQL-транзакцию для проведения операции разбиения таблицы на 2 (шардировать на orders_1 - price>499 и orders_2 - price<=499).
```sql=
BEGIN;
CREATE TABLE orders_new(id SERIAL, title VARCHAR(80) NOT NULL, price integer DEFAULT 0) PARTITION BY RANGE (price);
CREATE TABLE orders_price_gt_499 PARTITION OF orders_new FOR VALUES FROM (500) TO (2147483647);
CREATE TABLE orders_price_lte_499 PARTITION OF orders_new FOR VALUES FROM (0) TO (500);
INSERT INTO orders_new SELECT * FROM orders;
DROP TABLE orders;
ALTER TABLE orders_new RENAME TO orders;
COMMIT;
```
### Можно ли было изначально исключить "ручное" разбиение при проектировании таблицы orders?
Можно, если изначально известное распределение по какому-то из полей, что бывает крайне редко.
Если мы заранее знаем, что кол-во записей в БД будет равномерно распредлено по какому-то полю, то шардировать можно при проектировании. Иначе можем получить ситуацию когда на одном шарде 99% записей, на другом 1%
## Задача 4
### Используя утилиту pg_dump создайте бекап БД test_database.
```bash=
pg_dump -U postgres test_database > /var/lib/postgresql/bckp/my_dump.sql
```
### Как бы вы доработали бэкап-файл, чтобы добавить уникальность значения столбца title для таблиц test_database?
Можно прямо в создание partitions добавить директиву UNIQUE напротив объявления полей таблицы:
```sql=
CREATE TABLE public.orders_price_lte_499 (
id integer DEFAULT nextval('public.orders_new_id_seq'::regclass) NOT NULL,
title character varying(80) NOT NULL UNIQUE,
price integer DEFAULT 0
);
CREATE TABLE public.orders_price_gt_499 (
id integer DEFAULT nextval('public.orders_new_id_seq'::regclass) NOT NULL,
title character varying(80) NOT NULL UNIQUE,
price integer DEFAULT 0
);
```
При разворацивании такого дампа title станет уникальным полем. Проверено.