#set text(size: 1.3em) #show link: underline #set page(footer: context { if counter(page).get().first() > 1 [ #align(center)[ #counter(page).display("1") ] ] }) #show raw.where(block: false): box.with( fill: luma(240), inset: (x: 3pt, y: 0pt), outset: (y: 3pt), radius: 2pt, ) #show raw.where(block: true): block.with( fill: luma(240), inset: 10pt, radius: 4pt, ) // title #align(center)[Санкт-Петербургский национальный исследовательский университет информационных технологий, механики и оптики] \ \ \ #align(center)[Факультет инфокоммуникационных технологий] #align(center)[Направление подготовки 11.03.02] \ \ #align(center)[Практическая работа №1] //#align(center)[Установка и первоначальная настройка субд postgresql.] \ \ \ \ //#align(center)[Вариант 19] \ \ \ \ \ \ \ #align(right)[Выполнил:] #align(right)[Дощенников Никита Андреевич] #align(right)[Группа: К3221] #align(right)[Проверила:] #align(right)[Татьяна Евгеньевна Войтюк] \ \ #align(center)[Санкт-Петербург] #align(center)[2025] #pagebreak() === Цель работы: Освоить базовые приёмы установки и настройки субд "postgresql", научиться использовать pgadmin для администрирования, развернуть учебную базу данных "demo" и ознакомиться с её структурой, а также закрепить навыки создания баз данных и схем на примере учебной бд "hr". Изучение принципов проектирования и администрирования реляционных баз данных в среде postgresql с использованием графического интерфейса pgadmin и языка sql. Освоение создания, изменения и связи таблиц, настройки ограничений целостности, индексов и построения ER-диаграмм. Формирование практических навыков работы с объектами базы данных, добавления и проверки данных, а также документирования структуры базы данных. === Задачи, решаемые при выполнении работы. - Установить и настроить субд postgresql и клиент pgadmin. - Проверить правильность работы сервера с помощью выполнения тестового запроса. - Развернуть учебную базу demo и убедиться в доступности её объектов. - Ознакомиться со структурой базы demo и проанализировать основные сущности. - Создать учебную базу данных двумя способами: через графический интерфейс и с помощью `CREATE DATABASE`. - Создать в базе данных hr схемы для группировки объектов. - Освоить создание таблиц в базе данных с использованием графического интерфейса pgadmin и sql запросов. - Научиться задавать ключевые параметры таблиц: первичные ключи, автоинкрементные поля, значения по умолчанию и ограничения `NOT NULL`. - Изучить применение команды `ALTER TABLE` для изменения структуры таблицы без потери данных. - Создать связи между таблицами (внешние ключи) как через интерфейс pgadmin, так и с помощью sql кода. - Научиться создавать индексы для оптимизации поиска и сортировки данных. - Освоить построение и редактирование er диаграмм для визуализации структуры базы данных. - Научиться добавлять, изменять и проверять данные в таблицах с помощью интерфейса pgadmin и dml запросов. - Изучить назначение и реализацию ограничений целостности. - Научиться очищать таблицы с помощью команды `TRUNCATE` и выполнять внешние sql скрипты для заполнения и модификации базы. - Сформировать целостное представление о создании и сопровождении базы данных на примере модели hr. === Исходные данные. - Сервер с установленными docker и контейнерами: - postgres:16 — сервер субд postgresql, - dpage/pgadmin4 — веб-интерфейс для администрирования. - Учебная база данных demo. - субд postgresql и графическая оболочка pgadmin. - бд hr, содержащая схемы и объекты для работы. - схема employeesDepartments, созданная на предыдущем этапе. - sql-скрипты, предоставленные в методических материалах: - набор заданий, предполагающих создание таблиц employees, departments, locations и других таблиц базы данных hr. - примерные структуры таблиц и параметры столбцов. - методические указания по выполнению лабораторных работ и пошаговые инструкции с примерами sql команд и интерфейсных действий. === Выполнение работы. ==== Часть 1. ===== Задание 1. Установка необходимого ПО. Для выполнения работы была установлена субд postgresql и приложение pgadmin. Установка производилась в среде docker. На сервере был установлен docker и запущены контейнеры: `postgres:16`, `dpage/pgadmin4`. На рис. 1 показан вывод команды `docker ps`, который показывает запущенные контейнеры `pgadmin` и `postgres`. #align(center)[ #figure( image("part1/assets/18.png"), caption: [Результат команды `docker ps`.], supplement: [Рис] ) ] Контейнеры были объединены в общую сеть docker, чтобы pgadmin мог напрямую подключаться к postgres. На рис. 2 показаны настройки сети `dbnet`. #align(center)[ #figure( image("part1/assets/19.png"), caption: [Настройки сети `dbnet`.], supplement: [Рис] ) ] pgadmin стал доступен по адресу #link("https://db.fymio.us")[db.fymio.us] На рис. 3 показан фрагмент `Caddyfile`, ответственный за #link("https://db.fymio.us")[db.fymio.us]. #align(center)[ #figure( image("part1/assets/20.png"), caption: [Часть вывода команды `cat /etc/caddy/Caddyfile`.], supplement: [Рис] ) ] В pgadmin был зарегистрирован новый сервер. В настройках подключения были указаны следующие параметры. На рис. 4, 5 показаны соответствующие настройки. #align(center)[ #figure( image("part1/assets/16.png"), caption: [Настройки General сервера Web PostgreSQL.], supplement: [Рис] ) ] #align(center)[ #figure( image("part1/assets/17.png"), caption: [Настройки Connection сервера Web PostgreSQL.], supplement: [Рис] ) ] В "Object Explorer" слева я раскрыл узел "Databases" (Рис. 6): #align(center)[ #figure( image("part1/assets/1.png"), caption: [Object Explorer -> Databases.], supplement: [Рис] ) ] Затем я нажал ПКМ по базе "postgres" и выбрал инструмент "Query Tool" (Рис. 7): #align(center)[ #figure( image("part1/assets/2.png"), caption: [Открытие Query Tool.], supplement: [Рис] ) ] В открывшемся окне написал запрос проверки версии сервера `SELECT version();`. После этого нажал кнопку "Execute script" (Рис. 8). #align(center)[ #figure( image("part1/assets/3.png"), caption: [Выполнение скрипта проверки версии.], supplement: [Рис] ) ] В поле "Data Output" я увидел версию `PostgreSQL 16.10`. ===== Задание 2. Подключение учебной базы данных. После выполнения следующих команд на сервере учебная база данных появилась в "Object Explorer". ```bash wget https://edu.postgrespro.ru/demo-medium.zip unzip demo-medium.zip docker exec -i postgres psql -U postgres -d postgres < demo-medium-20170815.sql ``` После появления базы данных "demo", в "Query Tool" я выполнил следующий скрипт (Рис. 9): ```sql SELECT * FROM bookings.aircrafts_data; ``` #align(center)[ #figure( image("part1/assets/4.png"), caption: [Выполнение скрипта `SELECT * FROM bookings.aircrafts_data`.], supplement: [Рис] ) ] ===== Задание 3. Ознакомление с учебной БД. Я ознакомился с описанием БД на сайте #link("https://postgrespro.ru/education/demodb")[postgrespro.ru/education/demodb] ===== Задание 4. Создание учебной базы данных HR средствами pgAdmin. Я нажал ПКМ на узле "Databases" и выбрал меню "Create" затем "Database..." (Рис. 10). #align(center)[ #figure( image("part1/assets/5.png"), caption: [Создание новой базы данных.], supplement: [Рис] ) ] Затем в октрывшемся окне я выставил следующие настройки (Рис. 10, 11). #align(center)[ #figure( image("part1/assets/6.png"), caption: [Настройки новой базы. Вкладка General.], supplement: [Рис] ) ] #align(center)[ #figure( image("part1/assets/7.png"), caption: [Настройки новой базы. Вкладка Definition.], supplement: [Рис] ) ] Затем я сохранил настройки. В "Object Explorer" появилась созданная база (Рис. 12). #align(center)[ #figure( image("part1/assets/8.png"), caption: [База `HR` в Object Explorer.], supplement: [Рис] ) ] После этого я удалил базу через ПКМ (Рис. 14). #align(center)[ #figure( image("part1/assets/9.png"), caption: [Удаление базы `HR`.], supplement: [Рис] ) ] ===== Задание 5. Создание учебной базы данных HR средствами PL/pgSQL Я открыл "Query Tool" базы данных `postgres`. И прописал следующий скрипт (Рис. 15). ```sql CREATE DATABASE hr WITH ENCODING 'UTF8' LC_COLLATE 'C' LC_CTYPE 'C' TEMPLATE template0 CONNECTION LIMIT 1; ``` #align(center)[ #figure( image("part1/assets/10.png"), caption: [Создание базы `hr` при помощи скрипта.], supplement: [Рис] ) ] После этого в списке баз появилась созданная (Рис. 16). #align(center)[ #figure( image("part1/assets/11.png"), caption: [Новая база в Object Explorer.], supplement: [Рис] ) ] ===== Задание 6. Создание схем. Я развернул вкладку для создания схем. Рис. 17 показывает меню создание схем. #align(center)[ #figure( image("part1/assets/12.png"), caption: [Создание схемы.], supplement: [Рис] ) ] И создал схему "EmployeesDepartments". В "Object Explorer" видно что схема создана (Рис. 18). #align(center)[ #figure( image("part1/assets/13.png"), caption: [Новая схема появилась.], supplement: [Рис] ) ] Чтобы создать вторую схему, я открыл "Query Tool" к базе `hr`. И прописал следующие запросы (Рис. 19): ```cs CREATE SCHEMA IF NOT EXISTS "countries" AUTHORIZATION postgres; ``` #align(center)[ #figure( image("part1/assets/14.png"), caption: [Исполнение скрипта по созданию схемы.], supplement: [Рис] ) ] В "Object Explorer" видна добавленная схема (Рис. 20): #align(center)[ #figure( image("part1/assets/15.png"), caption: [Появление новой схемы.], supplement: [Рис] ) ] ==== Часть 2. ===== Задание 1. Создание таблицы в графической среде pgadmin. Я раскрыл базу hr до узла tables и выбрал опцию create (Рис. 21): #align(center)[ #figure( image("part2/assets/1.png"), caption: [Меню создания новой таблицы.], supplement: [Рис] ) ] И создал таблицу `EMPLOYEES` (Рис. 22): #align(center)[ #figure( image("part2/assets/2.png"), caption: [Настройки таблицы EMPLOYEES.], supplement: [Рис] ) ] Затем я заполнил вкладку `columns` как показано на рисунке в условии (Рис. 23): #align(center)[ #figure( image("part2/assets/3.png"), caption: [Столбцы таблицы EMPLOYEES.], supplement: [Рис] ) ] Для поля `employee_id`, я выставил следующие параметры (Рис. 24): #align(center)[ #figure( image("part2/assets/4.png"), caption: [Настройки столбца `EMPLOYEE_ID` -> Constraints.], supplement: [Рис] ) ] Для столбца `hire_date` я поставил значение по умолчанию `current_date` (Рис. 25). #align(center)[ #figure( image("part2/assets/5.png"), caption: [Обновленное значение по умолчанию для столбца `HIRE_DATE`.], supplement: [Рис] ) ] После этого, я сохранил таблицу. ===== Задание 2. Создание таблицы в Query Editor. Я открыл query tool для hr и вписал туда следующий скрипт (Рис. 26): ```sql CREATE TABLE "EmployeesDepartments"."DEPARTMENTS" ( DEPARTMENT_ID integer GENERATED ALWAYS AS IDENTITY (INCREMENT 1 START 1) PRIMARY KEY NOT NULL, DEPARTMENT_NAME character varying(30)[] NOT NULL, MANAGER_ID bigint NULL, LOCATION_ID integer NULL ); ``` #align(center)[ #figure( image("part2/assets/6.png"), caption: [Исполнение скрипта по созданию таблицы.], supplement: [Рис] ) ] Таблица появилась в object explorer (Рис. 27): #align(center)[ #figure( image("part2/assets/7.png"), caption: [Новая таблица в Object Explorer.], supplement: [Рис] ) ] Затем я создал еще одну таблицу скриптом (Рис. 28): ```sql CREATE TABLE "EmployeesDepartments"."LOCATIONS" (LOCATION_ID smallint GENERATED ALWAYS AS IDENTITY NOT NULL, STREET_ADDRESS character varying(40), POSTAL_CODE character varying(12), CITY character varying(30), COUNTRY_ID CHAR(2) ); ``` #align(center)[ #figure( image("part2/assets/9.png"), caption: [Исполнение скрипта по созданию таблицы.], supplement: [Рис] ) ] Как можно видеть, таблица была создана (Рис. 29): #align(center)[ #figure( image("part2/assets/10.png"), caption: [Новая таблица в Object Explorer.], supplement: [Рис] ) ] ===== Задание 3. Изменение таблицы. В query tool я ввел следующее (Рис. 30): ```sql ALTER TABLE "EmployeesDepartments"."LOCATIONS" ADD STATE_PROVINCE character varying(25) NULL; ``` #align(center)[ #figure( image("part2/assets/11.png"), caption: [Исполнение скрипта в query tool.], supplement: [Рис] ) ] Изменил столбец CITY следующим кодом (Рис. 31): ```sql ALTER TABLE "EmployeesDepartments"."LOCATIONS" ADD CONSTRAINT "PK_LokationId" PRIMARY KEY (LOCATION_ID); ``` #align(center)[ #figure( image("part2/assets/12.png"), caption: [Исполнение скрипта query tool.], supplement: [Рис] ) ] Таблица locations (Рис. 32): #align(center)[ #figure( image("part2/assets/13.png"), caption: [Таблица locations.], supplement: [Рис] ) ] Затем я прописал текст скрипта `script1_create.sql` (Рис. 33, 34): #align(center)[ #figure( image("part2/assets/14.png"), caption: [Скрипт `script1_create.sql` в query tool.], supplement: [Рис] ) ] #align(center)[ #figure( image("part2/assets/15.png"), caption: [Новые таблицы в Object Explorer.], supplement: [Рис] ) ] ===== Задание 4. Создание отношения графическим интерфейсом pgadmin. Я нажал ПКМ по таблице EmployeesDepartments.LOCATIONS и выбрал меню создания внешнего ключа (Рис. 35): #align(center)[ #figure( image("part2/assets/16.png"), caption: [Меню создания внешнего ключа.], supplement: [Рис] ) ] Затем я ввел задание название отношения (Рис. 36): #align(center)[ #figure( image("part2/assets/17.png"), caption: [Настройки создания Foreign Key.], supplement: [Рис] ) ] После, я добавил столбец кнопкой add (Рис. 37): #align(center)[ #figure( image("part2/assets/18.png"), caption: [Настройки создания Foreign Key.], supplement: [Рис] ) ] Вкладка sql (Рис. 38): #align(center)[ #figure( image("part2/assets/19.png"), caption: [SQL код создания Foreign Key.], supplement: [Рис] ) ] Ограничения locations (Рис. 39): #align(center)[ #figure( image("part2/assets/20.png"), caption: [Ограничения LOCATIONS.], supplement: [Рис] ) ] Затем я создал отношение с помощью ddl оператора alter table (Рис. 40): ```sql ALTER TABLE "Countries"."COUNTRIES" ADD CONSTRAINT "COUNTR_REG_ID_FK1" FOREIGN KEY ("REGION_ID") REFERENCES "Countries"."REGIONS" ("REGION_ID"); ``` #align(center)[ #figure( image("part1/assets/21.png"), caption: [Выполнение скрипта в query tool.], supplement: [Рис] ) ] ===== Задание 5. Создания индекса с помощью графического интерфейса pgadmin. В таблице EmployeesDepartments.LOCATIONS, я выбрал раздел меню для создания индекса: #align(center)[#image("part2/assets/22.png")] Я в диалоге создания индекса я передал следующие параметры: #align(center)[#image("part2/assets/23.png")] #align(center)[#image("part2/assets/24.png")] #align(center)[#image("part2/assets/25.png")] sql: #align(center)[#image("part2/assets/26.png")] ===== Задание 6. Построение диаграмм базы данных. Для создания диаграммы я нажал ПКМ на узел базы данных и выбрал параметр "ERD For Database": #align(center)[#image("part2/assets/27.png")] Затем я скорректировал вид своей диаграммы в соответствии с условием: #align(center)[#image("part2/assets/28.png")] Я экспортировал снимок диаграммы, нажав на соответствующую кнопку. Результат: #align(center)[#image("part2/assets/29.png")] Сохранил проект диаграммы: #align(center)[#image("part2/assets/30.png")] ===== Задание 7. Добавление данных в таблицу. Я раскрыл меню для генерирования скрипта по вставке данных в таблицу Countries.CURRENCIES: #align(center)[#image("part2/assets/31.png")] Затем я добавил следующий код в скрипт: ```sql INSERT INTO "Countries"."CURRENCIES"("COMMENTS", "CURRENCY_NAME", "CURRENCY_CODE") VALUES('EuroZone', 'Euro', 'EUR'); ``` #align(center)[#image("part2/assets/32.png")] После запуска скрипта проверил при помощи: ```sql select * from "Countries"."CURRENCIES"; ``` #align(center)[#image("part2/assets/33.png")] В столбце EMPLOYEE_ID я заменил identity с always на by default. #align(center)[#image("part2/assets/34.png")] Затем при помощи графического интерфейса pgadmin, я добавил запись в таблицу "EmployeesDepartments"."EMPLOYEES": #align(center)[#image("part2/assets/35.png")] #align(center)[#image("part2/assets/36.png")] Затем я добавил строку и сохранил данные: #align(center)[#image("part2/assets/37.png")] #align(center)[#image("part2/assets/38.png")] #align(center)[#image("part2/assets/39.png")] Затем, в query tool я ввел следующий код: ```sql INSERT INTO "EmployeesDepartments"."EMPLOYEES"("FIRST_NAME", "LAST_NAME", "EMAIL", "PHONE_NUMBER", "JOB_ID", "SALARY", "COMMISSION_PCT", "MANAGER_ID", "DEPARTMENT_ID") VALUES(2, 'Steven', 'King', 'SKING', '515.123.4567', 'AD_PRES', 24000, null, null, 90); ``` #align(center)[#image("part2/assets/40.png")] Проверим: ```sql SELECT * FROM "EmployeesDepartments"."EMPLOYEES"; ``` #align(center)[#image("part2/assets/41.png")] ===== Задание 8. Ограничения для столбцов. Я добавил ограничения к таблицам "Countries"."SPOKEN_LANGUAGES" и "EmployeesDepartments"."EMPLOYEES" при помощи следующего кода: ```sql ALTER TABLE "Countries"."SPOKEN_LANGUAGES" ADD CONSTRAINT "CTRY_NUM_FK1" FOREIGN KEY ("COUNTRY_ID") REFERENCES "Countries"."COUNTRIES" ("COUNTRY_ID"); ``` #align(center)[#image("part2/assets/42.png")] #align(center)[#image("part2/assets/43.png")] и ```sql ALTER TABLE "EmployeesDepartments"."EMPLOYEES" ADD CONSTRAINT "EMP_SALARY_MIN" CHECK ("SALARY" > 0); ``` #align(center)[#image("part2/assets/44.png")] #align(center)[#image("part2/assets/45.png")] Затем я добавил еще одно ограничение для таблицы JOB_HISTORY. Для этого в свойствах таблицы в разделе constraints добавил check c условием, что "END_DATE" > "START_DATE": #align(center)[#image("part2/assets/46.png")] #align(center)[#image("part2/assets/47.png")] Я включил это ограничение выключив соответствующую опцию: #align(center)[#image("part2/assets/48.png")] #align(center)[#image("part2/assets/49.png")] Также я проверил работоспособность ограничения: ```sql INSERT INTO "EmployeesDepartments"."JOB_HISTORY" ("EMPLOYEE_ID", "START_DATE", "END_DATE", "JOB_ID", "DEPARTMENT_ID") VALUES(200, '06-17-1993', '09-17-1987', 'AD_ASST', 90); ``` #align(center)[#image("part2/assets/50.png")] и ```sql INSERT INTO "EmployeesDepartments"."JOB_HISTORY" ("EMPLOYEE_ID", "START_DATE", "END_DATE", "JOB_ID", "DEPARTMENT_ID") VALUES(200, '06-17-1981', '06-17-1993', 'AD_ASST', 90); ``` #align(center)[#image("part2/assets/51.png")] ===== Задание 9. Очистка таблиц и завершение создания БД HR. Я произвел очистку таблицы EMPLOYEES с помощью DDL команды `TRUNCATE`: ```sql TRUNCATE "EmployeesDepartments"."EMPLOYEES"; ``` #align(center)[#image("part2/assets/52.png")] Также я очистил JOB_HISTORY и CURRENCIES: ```sql TRUNCATE "EmployeesDepartments"."JOB_HISTORY"; ``` #align(center)[#image("part2/assets/53.png")] и ```sql TRUNCATE "Countries"."CURRENCIES"; ``` #align(center)[#image("part2/assets/54.png")] После очистки я выполнил код из файла `script2_alter.sql`: #align(center)[#image("part2/assets/55.png")] И для добавления данных, я выполнил скрипт `script3_insert.sql`: #align(center)[#image("part2/assets/56.png")] Результат: #align(center)[#image("part2/assets/57.png")] === Выводы. В ходе выполнения практической работы я подробно изучил процесс установки и первоначальной настройки системы управления базами данных postgresql, а также освоил работу с графическим интерфейсом pgadmin. При помощи контейнерной среды docker я развернул сервер postgresql и клиентское приложение pgadmin, обеспечив их взаимодействие через общую сеть и корректное подключение по заданным параметрам. В процессе работы я научился: - создавать и удалять базы данных как через интерфейс pgadmin, так и с помощью sql-команд `CREATE DATABASE` и `DROP DATABASE`; - использовать параметры локализации (`LC_COLLATE`, `LC_CTYPE`) и шаблоны (`TEMPLATE template0`) при создании баз данных; - создавать схемы для логического объединения объектов базы данных и разграничения их по смысловым группам; - разрабатывать таблицы с использованием как графического интерфейса, так и SQL-скриптов, задавая типы данных, значения по умолчанию, первичные ключи, автоинкрементные поля и ограничения `NOT NULL`; - изменять структуру таблиц с помощью команды `ALTER TABLE`, добавлять новые столбцы, первичные и внешние ключи, а также ограничения целостности и проверки (`CHECK`); - создавать связи между таблицами и обеспечивать целостность данных за счёт использования внешних ключей (`FOREIGN KEY`); - добавлять индексы для ускорения поиска и сортировки данных; - использовать команды dml (`INSERT`, `SELECT`, `UPDATE`, `DELETE`) для добавления, изменения и проверки данных в таблицах; - очищать таблицы при помощи команды `TRUNCATE` и выполнять внешние sql-скрипты для массового изменения и заполнения данных; - визуализировать структуру базы данных при помощи er-диаграмм, редактировать и экспортировать их. Кроме того, в процессе работы я разобрался с типовыми ошибками, возникающими при создании баз данных с различными локалями и при несогласованности ключей, и научился устранять их корректной настройкой параметров и порядка выполнения операций. В результате выполнения лабораторной работы я сформировал целостное представление о процессе проектирования, создания и сопровождения реляционных баз данных в postgresql, закрепил навыки администрирования, построения структуры данных, задания связей и ограничений, а также использования инструментов визуального моделирования. Полученные знания и навыки позволяют уверенно работать с субд postgresql и применять её как для учебных, так и для практических проектов.