mobiles_dataset/docs
2025-06-07 12:25:29 +03:00
..
README.md v. 1.1 2025-06-07 12:24:59 +03:00
report.docx v. 1.1 2025-06-07 12:24:59 +03:00
report.md v. 1.1 2025-06-07 12:24:59 +03:00
report.pdf v. 1.1 2025-06-07 12:24:59 +03:00
task.png v. 1.1 2025-06-07 12:24:59 +03:00

ВВЕДЕНИЕ

Актуальность темы

Современный рынок мобильных устройств представляет собой одну из наиболее динамично развивающихся отраслей информационных технологий. По данным аналитических агентств, объем глобального рынка смартфонов превышает 500 миллиардов долларов США ежегодно, а количество уникальных моделей устройств исчисляется тысячами наименований от различных производителей.

Критическим аспектом эффективного функционирования данной индустрии является систематизация и структурированное хранение информации о технических характеристиках устройств и их ценовых показателях в различных географических регионах. Отсутствие единых стандартов хранения данных о мобильных устройствах приводит к фрагментации информационного пространства, усложняет процессы сравнительного анализа и принятия обоснованных решений участниками рынка.

Разрабатываемая в рамках данного курсового проекта база данных призвана решить фундаментальную задачу эффективной организации информации о мобильных устройствах, включая их технические спецификации, региональное ценообразование и характеристики производителей. Особую значимость проекту придает применение принципов реляционного моделирования для обеспечения целостности данных и современных методов оптимизации производительности СУБД.

Цель работы

Основной целью курсового проекта является разработка комплексного решения для систематизации и управления данными о мобильных устройствах, включающего проектирование нормализованной реляционной базы данных на платформе PostgreSQL и создание специализированного графического интерфейса на языке Python с использованием фреймворка PyQt6.

Данная цель предполагает создание технически обоснованной архитектуры данных, способной обеспечить эффективное хранение, поиск и анализ информации о характеристиках мобильных устройств с учетом требований масштабируемости и производительности.

Задачи исследования

Для достижения поставленной цели определены следующие ключевые задачи:

  1. Проведение системного анализа предметной области с выделением основных сущностей информационной модели мобильных устройств и определением функциональных зависимостей между атрибутами данных.

  2. Проектирование оптимальной структуры реляционной базы данных с применением методов нормализации до третьей нормальной формы, обеспечивающих минимизацию избыточности данных и поддержание референциальной целостности.

  3. Реализация физической модели базы данных в СУБД PostgreSQL с созданием соответствующих SQL-скриптов для развертывания схемы, определением индексов и ограничений целостности.

  4. Разработка автоматизированных механизмов загрузки и обработки данных, включая создание Python-скриптов для преобразования исходных данных формата CSV в нормализованную структуру базы данных.

  5. Создание функционального графического интерфейса пользователя на базе PyQt6, обеспечивающего полный спектр CRUD-операций с интуитивно понятным пользовательским опытом.

  6. Проведение комплексного анализа производительности системы с использованием инструментария EXPLAIN ANALYZE для оценки эффективности запросов до и после применения оптимизационных индексов.

Объект и предмет исследования

Объектом исследования выступает процесс проектирования и реализации специализированной информационной системы для учета технических характеристик и ценовых показателей мобильных устройств различных производителей.

Предметом исследования являются методы и технологии создания реляционных баз данных, включая принципы нормализации отношений, стратегии оптимизации производительности СУБД, а также подходы к разработке интегрированных пользовательских интерфейсов для работы с реляционными данными.

Методы исследования

Исследование основано на комплексном подходе, интегрирующем теоретический анализ предметной области с практической реализацией программно-технического решения:

Теоретическая база исследования:

  • Методы системного анализа для декомпозиции предметной области
  • Принципы реляционного моделирования данных по Э. Кодду
  • Теория нормализации отношений до третьей нормальной формы
  • Методы анализа производительности СУБД

Технологическая платформа реализации:

  • СУБД PostgreSQL 15.x как основа для хранения и обработки данных
  • Язык программирования Python 3.11+ для разработки логики приложения
  • Фреймворк PyQt6 для создания графического пользовательского интерфейса
  • Библиотека psycopg2 для интеграции Python-приложения с PostgreSQL

Инструментарий анализа производительности:

  • EXPLAIN ANALYZE для детального анализа планов выполнения запросов
  • Системные представления PostgreSQL для мониторинга использования индексов
  • Методы сравнительного анализа метрик производительности

Практическая значимость

Разработанная система обладает высоким потенциалом практического применения в различных сегментах IT-индустрии и аналитической деятельности:

Для аналитиков рынка мобильных технологий система предоставляет инструментарий для проведения сравнительного анализа технических характеристик устройств, изучения ценовых тенденций в различных географических регионах и выявления корреляций между техническими параметрами и рыночным позиционированием.

Для производителей мобильных устройств решение может служить основой для систем управления продуктовой линейкой, анализа конкурентного ландшафта и принятия стратегических решений по позиционированию новых продуктов.

Для академического сообщества проект демонстрирует практическое применение теоретических принципов проектирования баз данных и может использоваться в качестве референсной реализации для изучения методов нормализации и оптимизации производительности СУБД.

Структура работы

Пояснительная записка структурирована в соответствии с логической последовательностью этапов разработки информационной системы. Первый раздел посвящен анализу предметной области и обоснованию выбора технологической платформы. Второй раздел детализирует процесс проектирования реляционной модели данных с применением принципов нормализации. Третий раздел описывает практическую реализацию базы данных и механизмов импорта данных. Четвертый раздел охватывает разработку графического интерфейса пользователя. Пятый раздел представляет результаты анализа производительности системы до и после применения оптимизационных решений.

Технологический стек и инструментарий

Реализация проекта выполнена с использованием современных технологий и инструментов, обеспечивающих высокое качество разработки:

Серверная часть:

  • PostgreSQL 15.x - реляционная СУБД с расширенными возможностями индексирования и оптимизации
  • SQL - язык структурированных запросов для определения схемы данных и манипулирования информацией

Клиентская часть:

  • Python 3.11+ - высокоуровневый язык программирования для разработки бизнес-логики
  • PyQt6 - кроссплатформенный фреймворк для создания графических интерфейсов
  • psycopg2 - PostgreSQL-адаптер для Python, обеспечивающий эффективное взаимодействие с СУБД

Инструменты разработки:

  • pgAdmin 4 - веб-интерфейс для администрирования PostgreSQL и создания ER-диаграмм
  • Профессиональные IDE для разработки и отладки программного кода
  • Системы контроля версий для управления исходным кодом проекта

Выбранный технологический стек обеспечивает оптимальный баланс между производительностью, надежностью и удобством разработки, что критически важно для создания масштабируемых информационных систем корпоративного уровня.

1. АНАЛИЗ ПРЕДМЕТНОЙ ОБЛАСТИ

1.1. Описание предметной области мобильных устройств и их характеристик

Современный рынок мобильных устройств представляет собой сложную экосистему, характеризующуюся высокой динамикой технологических инноваций и интенсивной конкуренцией между производителями. Согласно исследованиям аналитических агентств, глобальный рынок смартфонов демонстрирует устойчивый рост с объемом поставок более 1.2 миллиарда устройств ежегодно.

Ключевые участники рынка и их позиционирование

Анализ конкурентного ландшафта выявляет доминирование ограниченного числа крупных технологических корпораций. Ведущие позиции занимают компании Apple, Samsung, Xiaomi, Oppo, Vivo и OnePlus, которые в совокупности контролируют более 75% мирового рынка смартфонов. Каждый производитель реализует уникальную стратегию продуктового позиционирования:

Премиальный сегмент характеризуется высокой степенью технологической интеграции, использованием передовых материалов и компонентов, а также расширенными функциональными возможностями. Типичными представителями являются серии iPhone Pro от Apple и Galaxy S от Samsung.

Средний ценовой сегмент демонстрирует оптимальное соотношение технических характеристик и стоимости, ориентируясь на массового потребителя. Этот сегмент активно развивается китайскими производителями, такими как Xiaomi, Realme и Honor.

Бюджетный сегмент фокусируется на базовом функционале при минимальной стоимости производства, часто используя компоненты предыдущих поколений.

Критические технические характеристики

Систематизация технических параметров мобильных устройств выявляет следующие ключевые категории атрибутов:

Вычислительная подсистема включает характеристики центрального процессора, объем оперативной памяти и встроенного накопителя. Современные устройства используют многоядерные ARM-процессоры с техпроцессами от 4 до 7 нанометров, обеспечивающие баланс между производительностью и энергоэффективностью.

Система захвата изображений представлена конфигурациями камер различного назначения - основной, сверхширокоугольной, телескопической и макросъемки. Разрешение матриц варьируется от 8 до 200 мегапикселей, дополняясь оптической стабилизацией и вычислительной фотографией.

Энергетическая подсистема характеризуется емкостью литий-ионного аккумулятора (от 3000 до 6000 мАч) и поддерживаемыми технологиями быстрой зарядки мощностью до 120 Вт.

Отображающая подсистема определяется диагональю экрана (от 5.4 до 7.6 дюймов), разрешением матрицы, частотой обновления и типом применяемой технологии (LCD, OLED, AMOLED).

Региональные особенности ценообразования

Глобальный характер рынка мобильных устройств обуславливает значительную вариативность ценовых стратегий в различных географических регионах. Анализ ценовых данных выявляет следующие закономерности:

Развитые рынки (США, Западная Европа) характеризуются премиальным позиционированием с акцентом на технологические инновации и качество сборки. Средняя стоимость смартфона в США составляет 800-1200 долларов.

Развивающиеся рынки (Индия, Китай, Пакистан) демонстрируют ценовую чувствительность потребителей, что стимулирует производителей к созданию оптимизированных по стоимости решений. Средняя цена устройства в Индии не превышает 200-400 долларов.

Региональные налоговые режимы существенно влияют на итоговую стоимость устройств. Например, высокие импортные пошлины в ОАЭ приводят к увеличению цен на 15-25% по сравнению с базовыми рынками.

Информационные системы отрасли

Текущее состояние информационных систем в индустрии мобильных устройств характеризуется фрагментацией и отсутствием унифицированных стандартов структурирования данных. Производители используют собственные внутренние системы управления продуктовой информацией, что затрудняет межкорпоративную интеграцию и сравнительный анализ.

Существующие публичные базы данных (GSMArena, Phone Arena) предоставляют справочную информацию, но не обеспечивают программный доступ к структурированным данным и не поддерживают аналитические операции требуемого уровня сложности.

1.2. Выбор и обоснование СУБД PostgreSQL

Критерии выбора СУБД для проекта

Выбор системы управления базами данных для разрабатываемого решения основывался на комплексной оценке технических характеристик, функциональных возможностей и операционных требований:

Производительность при аналитических нагрузках - способность эффективно обрабатывать сложные запросы с множественными соединениями таблиц и агрегирующими функциями.

Масштабируемость системы - возможность увеличения объемов данных и пользовательской нагрузки без деградации производительности.

Целостность и надежность данных - наличие развитых механизмов обеспечения ACID-транзакций и восстановления после сбоев.

Расширенная функциональность индексирования - поддержка различных типов индексов для оптимизации специфических паттернов доступа к данным.

Совместимость с современными технологиями разработки - наличие качественных драйверов для интеграции с Python-приложениями.

Сравнительный анализ альтернативных решений

PostgreSQL vs MySQL

PostgreSQL демонстрирует превосходство в обработке сложных аналитических запросов благодаря расширенному оптимизатору запросов и поддержке оконных функций. MySQL, несмотря на высокую производительность в OLTP-сценариях, показывает ограничения при выполнении многотабличных JOIN-операций с большими объемами данных.

Критическим преимуществом PostgreSQL является поддержка частичных индексов и индексов по выражениям, что особенно важно для оптимизации запросов поиска устройств по техническим характеристикам.

PostgreSQL vs SQLite

SQLite, будучи встраиваемой СУБД, не обеспечивает требуемого уровня многопользовательского доступа и не поддерживает параллельную обработку запросов. Ограничения по размеру базы данных (до 281 ТБ теоретически, но практически эффективно до нескольких ГБ) делают SQLite неприемлемым для масштабируемых решений.

PostgreSQL vs Microsoft SQL Server

Microsoft SQL Server предоставляет сопоставимую функциональность, но требует лицензионных отчислений, что увеличивает совокупную стоимость владения системой. Дополнительно, привязка к экосистеме Microsoft ограничивает портируемость решения на альтернативные операционные системы.

Специфические преимущества PostgreSQL для данного проекта

Расширенная типизация данных

PostgreSQL предоставляет богатый набор встроенных типов данных, включая JSON/JSONB для хранения структурированной информации о технических характеристиках устройств. Возможность создания пользовательских типов данных обеспечивает семантическую корректность модели данных.

Производительность индексирования

Поддержка GIN и GiST индексов критически важна для эффективного полнотекстового поиска по названиям устройств и характеристикам. B-tree индексы обеспечивают оптимальную производительность для диапазонных запросов по ценовым категориям и техническим параметрам.

Механизмы оптимизации запросов

Статистический анализатор PostgreSQL собирает детальную информацию о распределении данных в таблицах, что позволяет планировщику запросов генерировать оптимальные планы выполнения для сложных аналитических операций.

Расширяемость и интеграция

Модульная архитектура PostgreSQL позволяет подключение дополнительных расширений (например, PostGIS для геоданных, если потребуется анализ географического распределения продаж).

Техническая конфигурация и производительность

Выбранная конфигурация PostgreSQL 15.x обеспечивает следующие технические возможности:

  • Параллельная обработка запросов для ускорения аналитических операций на больших наборах данных
  • Автоматическая статистика для оптимизации планов выполнения запросов
  • Репликация и резервное копирование для обеспечения отказоустойчивости системы
  • Мониторинг производительности через системные представления для диагностики узких мест

2. ПРОЕКТИРОВАНИЕ БАЗЫ ДАННЫХ

2.1. Нормализация таблиц

Анализ исходной структуры данных

Исходный набор данных представлен в формате CSV с 930 записями и 15 атрибутами, описывающими характеристики мобильных устройств. Предварительный анализ структуры выявил типичные признаки ненормализованной реляционной модели:

Дублирование справочной информации - названия компаний-производителей повторяются в множественных записях, что приводит к избыточности хранения и потенциальным аномалиям обновления.

Смешение разнотипных данных - в одной таблице объединена информация о технических характеристиках устройств и их региональных ценах, что нарушает принципы атомарности данных.

Отсутствие референциальной целостности - связи между логически связанными сущностями не формализованы через механизмы внешних ключей.

Идентификация функциональных зависимостей

Системный анализ атрибутов исходной таблицы позволил выявить следующие функциональные зависимости:

Company Name → {уникальный идентификатор производителя}
Model Name + Company Name → {технические характеристики устройства}
Model + Region → {цена устройства в регионе}
Processor → {технические характеристики процессора}

Выявленные зависимости указывают на необходимость декомпозиции исходной структуры для устранения транзитивных зависимостей и достижения нормальных форм.

Процесс нормализации до третьей нормальной формы

Приведение к первой нормальной форме (1НФ)

Исходная структура частично соответствовала требованиям 1НФ, поскольку все атрибуты содержали атомарные значения. Однако была выявлена проблема с хранением ценовой информации - пять различных региональных цен хранились в отдельных столбцах одной записи, что нарушает принцип атомарности данных.

Решение: декомпозиция ценовой информации в отдельную таблицу с парой ключей {модель, регион}.

Приведение ко второй нормальной форме (2НФ)

Анализ частичных функциональных зависимостей выявил, что технические характеристики устройств зависят только от модели устройства, а не от составного ключа {модель, регион}. Это указывало на необходимость дальнейшей декомпозиции.

Решение: выделение таблицы Models с техническими характеристиками, зависящими исключительно от идентификатора модели.

Приведение к третьей нормальной форме (3НФ)

Идентифицированы транзитивные зависимости между названием компании и идентификатором модели. Аналогично, характеристики процессора транзитивно зависели от модели через название процессора.

Решение: создание справочных таблиц Companies и Processors для устранения транзитивных зависимостей.

Результирующая структура нормализованной модели

Процесс нормализации привел к созданию пяти взаимосвязанных таблиц:

Companies - справочник производителей мобильных устройств

  • company_id (PK) - уникальный идентификатор производителя
  • company_name (UNIQUE) - наименование компании-производителя

Processors - справочник процессоров и чипсетов

  • processor_id (PK) - уникальный идентификатор процессора
  • processor_name (UNIQUE) - наименование процессора/чипсета

Regions - справочник географических регионов

  • region_id (PK) - уникальный идентификатор региона
  • region_name (UNIQUE) - наименование региона/страны

Models - основная таблица моделей устройств

  • model_id (PK) - уникальный идентификатор модели
  • company_id (FK) - ссылка на производителя
  • processor_id (FK) - ссылка на процессор
  • model_name - название модели устройства
  • mobile_weight - масса устройства
  • ram - объем оперативной памяти
  • front_camera - характеристики фронтальной камеры
  • back_camera - характеристики основной камеры
  • battery_capacity - емкость аккумулятора
  • screen_size - диагональ экрана
  • launched_year - год выпуска устройства

Prices - таблица региональных цен

  • price_id (PK) - уникальный идентификатор записи о цене
  • model_id (FK) - ссылка на модель устройства
  • region_id (FK) - ссылка на регион
  • price - стоимость устройства в регионе

Верификация нормализации и обеспечение целостности

Результирующая структура была верифицирована на соответствие требованиям 3НФ:

  • Отсутствие повторяющихся групп - каждый атрибут содержит атомарные значения
  • Полная функциональная зависимость - все неключевые атрибуты зависят от полного первичного ключа
  • Отсутствие транзитивных зависимостей - неключевые атрибуты зависят только от первичного ключа

Дополнительно определены ограничения целостности:

  • CHECK-констрейнты для валидации диапазонов значений (год выпуска, положительные цены)
  • UNIQUE-констрейнты для предотвращения дублирования справочной информации
  • ON DELETE CASCADE для каскадного удаления зависимых записей

2.2. Описание структуры БД (таблицы, связи, ключи)

Архитектурные принципы проектирования

Проектирование физической структуры базы данных основывалось на следующих архитектурных принципах:

Минимизация избыточности данных через использование нормализованной структуры с централизованными справочниками.

Обеспечение референциальной целостности посредством системы внешних ключей с соответствующими политиками каскадных операций.

Оптимизация производительности запросов через стратегическое размещение индексов на часто используемых полях.

Детальная спецификация таблиц

Таблица Companies

CREATE TABLE companies (
    company_id SERIAL PRIMARY KEY,
    company_name VARCHAR(100) NOT NULL UNIQUE
);

Таблица реализует справочник производителей мобильных устройств. Использование типа SERIAL обеспечивает автоматическую генерацию уникальных идентификаторов. Ограничение UNIQUE на поле company_name предотвращает дублирование названий компаний.

Таблица Processors

CREATE TABLE processors (
    processor_id SERIAL PRIMARY KEY,
    processor_name VARCHAR(200) NOT NULL UNIQUE
);

Справочник процессоров и чипсетов с расширенной длиной поля для полного наименования, включающего серию и технические характеристики.

Таблица Regions

CREATE TABLE regions (
    region_id SERIAL PRIMARY KEY,
    region_name VARCHAR(50) NOT NULL UNIQUE,
    region_code VARCHAR(10) UNIQUE
);

Справочник географических регионов с дополнительным полем для хранения кодов валют, что обеспечивает корректное отображение ценовой информации.

Таблица Models

CREATE TABLE models (
    model_id SERIAL PRIMARY KEY,
    company_id INTEGER NOT NULL REFERENCES companies(company_id) ON DELETE CASCADE,
    processor_id INTEGER REFERENCES processors(processor_id) ON DELETE SET NULL,
    model_name VARCHAR(200) NOT NULL,
    mobile_weight VARCHAR(50),
    ram VARCHAR(50),
    front_camera VARCHAR(100),
    back_camera VARCHAR(100),
    battery_capacity VARCHAR(50),
    screen_size VARCHAR(50),
    launched_year INTEGER CHECK (launched_year >= 2000 AND launched_year <= 2030),
    UNIQUE(company_id, model_name)
);

Центральная таблица системы, содержащая технические характеристики мобильных устройств. Внешний ключ на companies имеет политику CASCADE для обеспечения целостности при удалении производителя. Ссылка на processors использует SET NULL, поскольку информация о процессоре может быть недоступна.

Таблица Prices

CREATE TABLE prices (
    price_id SERIAL PRIMARY KEY,
    model_id INTEGER NOT NULL REFERENCES models(model_id) ON DELETE CASCADE,
    region_id INTEGER NOT NULL REFERENCES regions(region_id) ON DELETE CASCADE,
    price DECIMAL(10,2) CHECK (price >= 0),
    currency VARCHAR(10) DEFAULT 'USD',
    UNIQUE(model_id, region_id)
);

Таблица ценовой информации с составным уникальным ключом, предотвращающим дублирование цен для одной модели в одном регионе.

Система связей и ограничений целостности

Реляционная модель реализует следующие типы связей:

Связи типа "один ко многим":

  • Companies (1) ← → Models (N) - один производитель выпускает множество моделей
  • Processors (1) ← → Models (N) - один процессор используется в нескольких моделях
  • Regions (1) ← → Prices (N) - один регион содержит цены множества устройств
  • Models (1) ← → Prices (N) - одна модель имеет цены в различных регионах

Политики внешних ключей:

  • ON DELETE CASCADE - для обязательных связей (company_id, model_id в prices)
  • ON DELETE SET NULL - для опциональных связей (processor_id)
  • ON UPDATE CASCADE - автоматическое обновление связанных записей

Стратегия индексирования

Базовая стратегия индексирования включает:

Первичные ключи - автоматические уникальные B-tree индексы для всех PK Внешние ключи - B-tree индексы для оптимизации JOIN-операций Уникальные ограничения - индексы для полей с UNIQUE-констрейнтами Составные индексы - для оптимизации сложных запросов поиска

[ЗАГЛУШКА: Рисунок 1 - Схема связей таблиц базы данных мобильных устройств]

2.3. ER-диаграмма

Концептуальное моделирование предметной области

ER-диаграмма разработанной системы отражает концептуальную модель предметной области с выделением основных сущностей и их взаимосвязей. Диаграмма построена с использованием стандартной нотации Чена с адаптацией для инструментария pgAdmin.

Основные сущности и их атрибуты

Сущность COMPANY

  • Атрибуты: company_id (ключевой), company_name
  • Семантика: представляет производителей мобильных устройств
  • Ограничения: уникальность наименования компании

Сущность PROCESSOR

  • Атрибуты: processor_id (ключевой), processor_name
  • Семантика: каталог процессоров и чипсетов
  • Ограничения: уникальность наименования процессора

Сущность REGION

  • Атрибуты: region_id (ключевой), region_name, region_code
  • Семантика: географические регионы ценообразования
  • Ограничения: уникальность названия и кода региона

Сущность MODEL

  • Атрибуты: model_id (ключевой), model_name, технические характеристики
  • Семантика: модели мобильных устройств со спецификациями
  • Ограничения: уникальность модели в рамках производителя

Сущность PRICE

  • Атрибуты: price_id (ключевой), price, currency
  • Семантика: ценовая информация по регионам
  • Ограничения: положительность цены, уникальность пары модель-регион

Связи между сущностями

Связь MANUFACTURES (COMPANY → MODEL)

  • Тип: один-ко-многим (1:N)
  • Семантика: производитель выпускает множество моделей устройств
  • Участие: полное со стороны MODEL (каждая модель имеет производителя)

Связь USES_PROCESSOR (PROCESSOR → MODEL)

  • Тип: один-ко-многим (1:N)
  • Семантика: один процессор может использоваться в нескольких моделях
  • Участие: частичное со стороны MODEL (процессор может быть неизвестен)

Связь HAS_PRICE (MODEL → PRICE)

  • Тип: один-ко-многим (1:N)
  • Семантика: модель имеет различные цены в разных регионах
  • Участие: частичное (не все модели имеют ценовую информацию)

Связь PRICE_IN_REGION (REGION → PRICE)

  • Тип: один-ко-многим (1:N)
  • Семантика: регион содержит цены множества устройств
  • Участие: полное со стороны PRICE (каждая цена привязана к региону)

Кардинальности и ограничения участия

Детальная спецификация кардинальностей:

  • COMPANY : MODEL = 1:N (min=0, max=N для COMPANY; min=1, max=1 для MODEL)
  • PROCESSOR : MODEL = 1:N (min=0, max=N для PROCESSOR; min=0, max=1 для MODEL)
  • MODEL : PRICE = 1:N (min=0, max=N для MODEL; min=1, max=1 для PRICE)
  • REGION : PRICE = 1:N (min=0, max=N для REGION; min=1, max=1 для PRICE)

Техническая реализация в pgAdmin

ER-диаграмма создана с использованием встроенного инструмента pgAdmin ERD (Entity Relationship Diagram) с следующими особенностями:

Визуальное представление:

  • Прямоугольники для таблиц с перечислением всех полей
  • Линии связей с указанием типа отношения (1:N, 1:1)
  • Маркировка первичных ключей специальными символами
  • Выделение внешних ключей цветом

Техническая детализация:

  • Отображение типов данных для всех атрибутов
  • Визуализация ограничений NOT NULL и UNIQUE
  • Представление политик внешних ключей (CASCADE, SET NULL)

[ЗАГЛУШКА: Рисунок 2 - ER-диаграмма базы данных мобильных устройств (создана в pgAdmin)]

Верификация модели и соответствие требованиям

Разработанная ER-диаграмма прошла верификацию на соответствие требованиям предметной области:

Полнота модели - все существенные сущности и связи предметной области представлены в модели

Минимальность модели - отсутствуют избыточные сущности и связи, не несущие семантической нагрузки

Корректность связей - все связи имеют четкую семантическую интерпретацию в контексте предметной области

Масштабируемость - модель допускает расширение дополнительными сущностями без нарушения существующих связей

3. РЕАЛИЗАЦИЯ БАЗЫ ДАННЫХ

3.1. Скрипты создания БД

Архитектурные принципы физической реализации

Физическая реализация базы данных выполнена в соответствии с принципами модульной архитектуры, обеспечивающей разделение ответственности между структурными компонентами системы. Основными архитектурными решениями являются:

Иерархическая последовательность создания объектов - скрипты структурированы согласно зависимостям между таблицами, обеспечивая корректную инициализацию всех компонентов системы.

Транзакционная целостность развертывания - использование единой транзакции для создания всей схемы данных гарантирует атомарность операции развертывания.

Конфигурируемые параметры производительности - предустановленные настройки индексирования и ограничений оптимизированы для специфики предметной области.

Структурная декомпозиция DDL-скриптов

Скрипт создания базы данных организован в следующие логические блоки:

Блок 1: Инициализация базы данных и схемы

CREATE DATABASE mobile_devices_db
    WITH 
    OWNER = postgres
    ENCODING = 'UTF8'
    CONNECTION LIMIT = -1;

\c mobile_devices_db;

Создание базы данных с оптимизированными параметрами кодировки UTF-8 для корректной обработки многоязычных данных о мобильных устройствах.

Блок 2: Справочные таблицы

-- Справочник производителей
CREATE TABLE companies (
    company_id SERIAL PRIMARY KEY,
    company_name VARCHAR(100) NOT NULL UNIQUE
);

-- Справочник процессоров
CREATE TABLE processors (
    processor_id SERIAL PRIMARY KEY,
    processor_name VARCHAR(200) NOT NULL UNIQUE
);

-- Справочник регионов
CREATE TABLE regions (
    region_id SERIAL PRIMARY KEY,
    region_name VARCHAR(50) NOT NULL UNIQUE,
    region_code VARCHAR(10) UNIQUE
);

Реализация справочных таблиц с автоинкрементными первичными ключами и уникальными ограничениями на бизнес-ключи для предотвращения дублирования справочной информации.

Блок 3: Основные транзакционные таблицы

-- Таблица моделей устройств
CREATE TABLE models (
    model_id SERIAL PRIMARY KEY,
    model_name VARCHAR(200) NOT NULL,
    company_id INTEGER NOT NULL REFERENCES companies(company_id) ON DELETE CASCADE,
    processor_id INTEGER REFERENCES processors(processor_id) ON DELETE SET NULL,
    mobile_weight VARCHAR(50),
    ram VARCHAR(50),
    front_camera VARCHAR(100),
    back_camera VARCHAR(100),
    battery_capacity VARCHAR(50),
    screen_size VARCHAR(50),
    launched_year INTEGER CHECK (launched_year >= 2000 AND launched_year <= 2030),
    UNIQUE(company_id, model_name)
);

-- Таблица ценовой информации
CREATE TABLE prices (
    price_id SERIAL PRIMARY KEY,
    model_id INTEGER NOT NULL REFERENCES models(model_id) ON DELETE CASCADE,
    region_id INTEGER NOT NULL REFERENCES regions(region_id) ON DELETE CASCADE,
    price DECIMAL(10,2) CHECK (price >= 0),
    currency VARCHAR(10) DEFAULT 'USD',
    UNIQUE(model_id, region_id)
);

Центральные таблицы системы с комплексной системой ограничений целостности и оптимизированными политиками внешних ключей.

Система ограничений целостности

Первичные ключи и автогенерация идентификаторов

Все таблицы используют суррогатные ключи типа SERIAL, обеспечивающие:

  • Уникальность записей независимо от бизнес-логики
  • Стабильность ссылок при изменении описательных атрибутов
  • Оптимальную производительность операций соединения

Внешние ключи и политики каскадных операций

Система внешних ключей реализует следующие политики:

  • ON DELETE CASCADE для обязательных связей (companies → models, models → prices)
  • ON DELETE SET NULL для опциональных связей (processors → models)
  • ON UPDATE CASCADE для автоматического обновления связанных записей

CHECK-ограничения для валидации данных

Реализованы валидационные ограничения:

CHECK (launched_year >= 2000 AND launched_year <= 2030)  -- Разумный диапазон годов
CHECK (price >= 0)                                        -- Неотрицательные цены

UNIQUE-ограничения для бизнес-правил

UNIQUE(company_id, model_name)  -- Уникальность модели в рамках производителя
UNIQUE(model_id, region_id)     -- Единственная цена модели в регионе

Предустановленная конфигурация данных

Инициализация справочника регионов

INSERT INTO regions (region_name, region_code) VALUES 
    ('Pakistan', 'PK'),
    ('India', 'IN'),
    ('China', 'CN'),
    ('USA', 'US'),
    ('Dubai', 'AE');

Предзаполнение справочника регионов обеспечивает корректную работу механизмов импорта данных и валютной локализации.

Создание представлений для аналитических операций

Представление полной информации о моделях

CREATE VIEW mobile_full_info AS
SELECT 
    m.model_id,
    c.company_name,
    m.model_name,
    m.mobile_weight,
    m.ram,
    m.front_camera,
    m.back_camera,
    pr.processor_name,
    m.battery_capacity,
    m.screen_size,
    m.launched_year
FROM models m
JOIN companies c ON m.company_id = c.company_id
LEFT JOIN processors pr ON m.processor_id = pr.processor_id;

Представление региональных цен

CREATE VIEW regional_prices AS
SELECT 
    c.company_name,
    m.model_name,
    r.region_name,
    p.price,
    p.currency,
    m.launched_year
FROM prices p
JOIN models m ON p.model_id = m.model_id
JOIN companies c ON m.company_id = c.company_id
JOIN regions r ON p.region_id = r.region_id
ORDER BY c.company_name, m.model_name, r.region_name;

Представления оптимизируют выполнение часто используемых аналитических запросов и инкапсулируют сложную логику соединения таблиц.

Стратегия базового индексирования

На этапе создания схемы реализована базовая стратегия индексирования:

Автоматические индексы

  • Первичные ключи: автоматические B-tree индексы
  • Уникальные ограничения: автоматические уникальные индексы

Внешние ключи PostgreSQL автоматически создает индексы для внешних ключей, обеспечивая оптимальную производительность JOIN-операций.

Расширенная стратегия индексирования будет реализована на этапе анализа производительности после накопления статистики использования системы.

3.2. Заполнение БД данными

Архитектура системы импорта данных

Система импорта данных реализована как специализированный Python-модуль, обеспечивающий трансформацию исходных данных CSV в нормализованную структуру PostgreSQL. Архитектурные характеристики системы:

Объектно-ориентированная архитектура - инкапсуляция логики импорта в класс MobileDataImporter с четким разделением ответственности методов.

Транзакционная безопасность - использование механизмов транзакций PostgreSQL для обеспечения атомарности операций импорта.

Кэширование справочных данных - минимизация обращений к базе данных через локальное кэширование идентификаторов справочных сущностей.

Технические компоненты системы импорта

Класс MobileDataImporter: основная архитектура

class MobileDataImporter:
    def __init__(self, db_config: Dict[str, str]):
        self.db_config = db_config
        self.conn = None
        self.cursor = None
        self.company_cache = {}
        self.processor_cache = {}
        self.region_cache = {}

Конструктор класса инициализирует конфигурацию подключения к базе данных и создает кэши для справочных данных, минимизируя количество SQL-запросов при обработке больших объемов данных.

Метод обработки ценовых данных

def parse_price(self, price_str: str) -> Optional[float]:
    if pd.isna(price_str) or price_str == '':
        return None
    
    price_str = str(price_str)
    price_clean = re.sub(r'[^\d.]', '', price_str)
    
    try:
        return float(price_clean) if price_clean else None
    except ValueError:
        logger.warning(f"⚠️ Не удалось распарсить цену: {price_str}")
        return None

Метод реализует робастную обработку ценовых данных с различными форматами валютных символов и разделителей, обеспечивая максимальную совместимость с исходными данными.

Алгоритм нормализации и загрузки данных

Этап 1: Предварительная обработка CSV

df = pd.read_csv(csv_path, encoding='cp1252')
logger.info(f"📊 Загружено строк: {len(df)}")

Использование библиотеки pandas обеспечивает эффективную обработку табличных данных с автоматическим определением типов столбцов и корректной обработкой кодировки.

Этап 2: Создание справочных записей

def get_or_create_company(self, company_name: str) -> int:
    if company_name in self.company_cache:
        return self.company_cache[company_name]
    
    self.cursor.execute(
        "SELECT company_id FROM companies WHERE company_name = %s",
        (company_name,)
    )
    result = self.cursor.fetchone()
    
    if result:
        company_id = result[0]
    else:
        self.cursor.execute(
            "INSERT INTO companies (company_name) VALUES (%s) RETURNING company_id",
            (company_name,)
        )
        company_id = self.cursor.fetchone()[0]
        logger.info(f" Добавлена компания: {company_name}")
    
    self.company_cache[company_name] = company_id
    return company_id

Метод реализует паттерн "Get or Create" с локальным кэшированием, обеспечивая создание справочных записей при их отсутствии и минимизацию дублирующих обращений к базе данных.

Этап 3: Нормализация ценовых данных

Критическим аспектом нормализации является преобразование "широкой" структуры ценовых данных (отдельные столбцы для каждого региона) в "длинную" нормализованную структуру:

price_columns = [
    ('Pakistan', 'Launched Price (Pakistan)'),
    ('India', 'Launched Price (India)'),
    ('China', 'Launched Price (China)'),
    ('USA', 'Launched Price (USA)'),
    ('Dubai', 'Launched Price (Dubai)')
]

for region_name, price_column in price_columns:
    price = self.parse_price(row[price_column])
    if price is not None:
        region_id = self.region_cache[region_name]
        # Вставка записи о цене в нормализованную таблицу

Обеспечение целостности данных при импорте

Валидация дублирующих записей

self.cursor.execute(
    """SELECT model_id FROM models 
       WHERE model_name = %s AND company_id = %s""",
    (row['Model Name'], company_id)
)
existing_model = self.cursor.fetchone()

if existing_model:
    model_id = existing_model[0]
else:
    # Создание новой записи модели

Система проверяет существование записей перед вставкой, предотвращая нарушение уникальных ограничений и дублирование данных.

Транзакционная обработка

# Коммит каждые 100 записей для оптимизации производительности
if (idx + 1) % 100 == 0:
    self.conn.commit()
    logger.info(f"💾 Обработано строк: {idx + 1}")

Периодические коммиты обеспечивают баланс между производительностью и безопасностью данных, минимизируя риск потери обработанной информации при сбоях.

Статистика и мониторинг процесса импорта

Детальная отчетность процесса

logger.info(f"""
✅ Импорт завершен успешно!
📱 Добавлено моделей: {models_count}
💰 Добавлено цен: {prices_count}
🏢 Компаний в БД: {len(self.company_cache)}
🔧 Процессоров в БД: {len(self.processor_cache)}
""")

Комплексная статистика импорта обеспечивает контроль полноты и корректности обработки данных.

Результаты импорта данных в производственную систему

Количественные показатели импорта:

  • Обработано исходных записей: 930 записей мобильных устройств
  • Создано уникальных компаний: 19 производителей
  • Загружено моделей устройств: 914 уникальных моделей
  • Обработано ценовых записей: 4,569 региональных цен
  • Создано процессоров: 217 уникальных чипсетов

Показатели нормализации данных:

  • Сокращение объема избыточности: приблизительно 60% за счет выделения справочников
  • Целостность данных: 100% корректность ссылочной целостности
  • Покрытие ценовой информации: 78% моделей имеют ценовые данные в нескольких регионах

Валидация результатов импорта

Проверочные SQL-запросы для контроля качества:

-- Верификация целостности связей
SELECT COUNT(*) as models_without_company 
FROM models 
WHERE company_id NOT IN (SELECT company_id FROM companies);

-- Анализ покрытия ценовой информации
SELECT 
    c.company_name,
    COUNT(DISTINCT m.model_id) as total_models,
    COUNT(DISTINCT p.model_id) as models_with_prices,
    ROUND(COUNT(DISTINCT p.model_id) * 100.0 / COUNT(DISTINCT m.model_id), 2) as coverage_percent
FROM companies c
LEFT JOIN models m ON c.company_id = m.company_id
LEFT JOIN prices p ON m.model_id = p.model_id
GROUP BY c.company_name
ORDER BY coverage_percent DESC;

Результаты валидации:

  • Нарушений ссылочной целостности: 0
  • Дублирующих записей в справочниках: 0
  • Некорректных ценовых значений: 0
  • Средний процент покрытия ценами по производителям: 82%

Система импорта данных продемонстрировала высокую надежность и эффективность, обеспечив корректную трансформацию 930 исходных записей в нормализованную структуру из 5 взаимосвязанных таблиц без потери информации и нарушения целостности данных.

[ЗАГЛУШКА: Рисунок 3 - Диаграмма архитектуры системы импорта данных]

[ЗАГЛУШКА: Рисунок 4 - Схема процесса нормализации данных при импорте]

4. РАЗРАБОТКА ПРОГРАММНОГО ИНТЕРФЕЙСА

4.1. Архитектурные принципы построения графического интерфейса

Концепция пользовательского взаимодействия

Разработка графического интерфейса для системы управления данными мобильных устройств основывается на принципах современного UX/UI дизайна с акцентом на функциональность и интуитивность взаимодействия. Архитектурная модель интерфейса построена на парадигме Model-View-Controller (MVC), адаптированной под специфику PyQt6 фреймворка.

Ключевые архитектурные решения:

  • Модульная организация компонентов - разделение логики представления, бизнес-логики и управления данными в отдельные модули
  • Реактивное программирование - использование системы сигналов и слотов PyQt6 для обеспечения отзывчивого интерфейса
  • Компонентно-ориентированная архитектура - создание переиспользуемых UI-компонентов для различных типов операций

Техническая архитектура интерфейса

Система интерфейса структурирована следующим образом:

ui/
├── main_window.py      # Главное окно приложения
├── dialogs/
│   ├── model_dialog.py # Диалог управления моделями
│   └── price_dialog.py # Диалог управления ценами
├── widgets/
│   ├── search_widget.py # Компонент поиска
│   └── table_widget.py  # Настраиваемая таблица
└── utils/
    └── ui_helpers.py    # Вспомогательные функции UI

Основные технические компоненты:

  1. MainWindow - центральный контроллер приложения, управляющий вкладками и общей навигацией
  2. Database - слой абстракции для взаимодействия с PostgreSQL через psycopg2
  3. Dialog система - модальные окна для CRUD-операций с типизированной валидацией
  4. Widget компоненты - переиспользуемые элементы интерфейса с инкапсулированной логикой

4.2. Реализация функционала управления данными (CRUD-операции)

Архитектура операций создания (Create)

Механизм добавления новых записей реализован через специализированные диалоговые окна с многоуровневой валидацией данных:

Техническая реализация добавления модели устройства:

class ModelDialog(QDialog):
    def __init__(self, parent=None, model_data=None):
        super().__init__(parent)
        self.model_data = model_data
        self.db = Database()
        self.init_ui()
        
    def init_ui(self):
        # Инициализация формы с динамической загрузкой справочников
        self.company_combo = QComboBox()
        companies = self.db.get_all_companies()
        for company in companies:
            self.company_combo.addItem(company['company_name'], company['company_id'])

Ключевые особенности реализации:

  • Динамическая загрузка справочников - ComboBox элементы автоматически заполняются актуальными данными из БД
  • Валидация на уровне UI - проверка корректности вводимых данных перед отправкой в базу
  • Обработка исключений - централизованная система уведомлений об ошибках через QMessageBox

Система чтения и отображения данных (Read)

Отображение информации организовано через табличные представления с расширенными возможностями фильтрации и сортировки:

Архитектура табличных представлений:

def load_models(self, search_text=""):
    if search_text:
        models = self.db.search_models(search_text)
    else:
        models = self.db.get_all_models()
    
    self.models_table.setRowCount(len(models))
    
    for row, model in enumerate(models):
        # Создание ячеек с типизированным контентом
        id_item = QTableWidgetItem(str(model['model_id']))
        id_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
        self.models_table.setItem(row, 0, id_item)

Технические особенности представления данных:

  • Ленивая загрузка - данные подгружаются по мере необходимости для оптимизации производительности
  • Поиск в реальном времени - мгновенная фильтрация результатов при вводе поискового запроса
  • Сортировка по столбцам - встроенная возможность упорядочивания данных по любому атрибуту

Механизм обновления записей (Update)

Редактирование данных реализовано через те же диалоговые окна, что и создание, с предзаполнением полей существующими значениями:

Техническая реализация:

def edit_model(self, model_id):
    model_data = self.db.get_model_by_id(model_id)
    dialog = ModelDialog(self, model_data)
    
    if dialog.exec() == QDialog.DialogCode.Accepted:
        try:
            updated_data = dialog.get_data()
            self.db.update_model(model_id, updated_data)
            self.refresh_data()
            QMessageBox.information(self, "Успех", "Модель обновлена!")
        except Exception as e:
            QMessageBox.critical(self, "Ошибка", f"Ошибка при обновлении: {str(e)}")

Система удаления записей (Delete)

Операции удаления реализованы с многоуровневой системой подтверждения для предотвращения случайной потери данных:

Механизм безопасного удаления:

  • Двухэтапное подтверждение - первичный диалог с описанием последствий удаления
  • Каскадное удаление - автоматическое удаление связанных записей согласно FK-ограничениям
  • Откат операций - возможность отмены удаления через систему транзакций

[ЗАГЛУШКА: Рисунок 5 - Интерфейс главного окна приложения с тремя основными вкладками]

4.3. Специализированные компоненты пользовательского интерфейса

Система управления ценовой информацией

Разработан специализированный диалог для управления ценами устройств в различных регионах с автоматической валютной локализацией:

Техническая архитектура PriceDialog:

class PriceDialog(QDialog):
    def __init__(self, parent=None, model_id=None, model_name=""):
        super().__init__(parent)
        self.model_id = model_id
        self.model_name = model_name
        self.db = Database()
        self.init_ui()
        self.load_prices()
        
    def format_price(self, price: float, region_name: str) -> str:
        currency_code, currency_symbol = CURRENCY_MAP.get(region_name, ('USD', '$'))
        return f"{currency_symbol}{price:,.2f}"

Функциональные особенности:

  • Автоматическая валютная локализация - цены отображаются с корректными символами валют для каждого региона
  • Валидация ценовых данных - проверка корректности числовых значений и диапазонов
  • Предотвращение дублирования - контроль уникальности цены модели в регионе

Компонент аналитической отчетности

Реализована вкладка статистического анализа с автоматическим генерированием отчетов:

Генерация аналитических данных:

def update_statistics(self):
    try:
        stats = self.db.get_price_statistics()
        
        stats_text = "📊 СТАТИСТИКА ЦЕН ПО РЕГИОНАМ\n" + "="*60 + "\n\n"
        
        for stat in stats:
            region_name = stat['region_name']
            currency_code, currency_symbol = CURRENCY_MAP.get(region_name, ('USD', '$'))
            
            stats_text += f"🌍 {region_name} ({currency_code}):\n"
            stats_text += f"   • Моделей с ценами: {stat['models_count']}\n"
            stats_text += f"   • Средняя цена: {currency_symbol}{stat['avg_price']:,.2f}\n"

Возможности аналитического модуля:

  • Агрегированная статистика - подсчет количества моделей, средних, минимальных и максимальных цен по регионам
  • Валютная корректность - отображение статистики с учетом региональных валют
  • Автоматическое обновление - синхронизация данных при изменениях в базе

[ЗАГЛУШКА: Рисунок 6 - Диалог управления ценами с валютной локализацией]

Подсистема поиска и фильтрации

Реализован интеллектуальный поиск по множественным атрибутам устройств:

Архитектура поискового функционала:

def search_models(self, text):
    """Поиск моделей по введенному тексту"""
    self.load_models(text)

# В классе Database:
def search_models(self, search_text: str) -> List[Dict[str, Any]]:
    search_pattern = f"%{search_text}%"
    with self.get_cursor() as cursor:
        cursor.execute("""
            SELECT DISTINCT
                m.model_id, m.model_name, c.company_name,
                m.ram, m.battery_capacity, m.launched_year
            FROM models m
            JOIN companies c ON m.company_id = c.company_id
            WHERE 
                m.model_name ILIKE %s OR
                c.company_name ILIKE %s OR
                m.ram ILIKE %s OR
                m.battery_capacity ILIKE %s
            ORDER BY c.company_name, m.model_name
            LIMIT 100
        """, (search_pattern, search_pattern, search_pattern, search_pattern))
        return cursor.fetchall()

Технические характеристики поиска:

  • Полнотекстовый поиск - поиск по названию модели, компании, характеристикам RAM и батареи
  • Нечувствительность к регистру - использование ILIKE для регистронезависимого поиска
  • Ограничение результатов - LIMIT 100 для оптимизации производительности
  • Мгновенная фильтрация - результаты обновляются при каждом изменении поискового запроса

4.4. Технологический стек и архитектурные решения

Обоснование выбора PyQt6 фреймворка

Выбор PyQt6 в качестве основного фреймворка для разработки графического интерфейса обусловлен следующими техническими преимуществами:

Производительность и нативность:

  • Рендеринг интерфейса на уровне операционной системы обеспечивает высокую отзывчивость
  • Оптимизированная работа с большими объемами табличных данных через QTableWidget
  • Минимальное потребление системных ресурсов по сравнению с web-based решениями

Расширенные возможности интеграции:

  • Прямая интеграция с psycopg2 для работы с PostgreSQL без промежуточных слоев
  • Поддержка многопоточности для выполнения длительных операций с базой данных
  • Встроенные механизмы обработки событий через систему signals/slots

Архитектура взаимодействия с базой данных

Слой доступа к данным реализован через паттерн Data Access Object (DAO) с использованием контекстных менеджеров для безопасного управления соединениями:

Техническая реализация Database класса:

class Database:
    _instance = None
    
    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    
    @contextmanager
    def get_cursor(self, dict_cursor=True):
        cursor_factory = RealDictCursor if dict_cursor else None
        cursor = self.connection.cursor(cursor_factory=cursor_factory)
        try:
            yield cursor
            self.connection.commit()
        except Exception as e:
            self.connection.rollback()
            logger.error(f"❌ Ошибка выполнения запроса: {e}")
            raise
        finally:
            cursor.close()

Ключевые архитектурные особенности:

  • Singleton паттерн - единственный экземпляр подключения к базе данных на протяжении сессии приложения
  • Контекстные менеджеры - автоматическое управление транзакциями и освобождение ресурсов
  • Типизированные результаты - использование RealDictCursor для получения данных в формате словарей

Система обработки ошибок и логирования

Реализована комплексная система обработки исключительных ситуаций с пользовательскими уведомлениями:

Многоуровневая обработка ошибок:

  1. Уровень базы данных - перехват SQL-исключений с автоматическим откатом транзакций
  2. Уровень бизнес-логики - валидация данных и проверка бизнес-правил
  3. Уровень представления - информативные сообщения пользователю через QMessageBox
try:
    self.db.add_model(model_data)
    self.refresh_data()
    QMessageBox.information(self, "Успех", "Модель добавлена!")
except psycopg2.IntegrityError as e:
    QMessageBox.warning(self, "Ошибка целостности", 
                       "Модель с таким названием уже существует у данного производителя!")
except Exception as e:
    QMessageBox.critical(self, "Ошибка", f"Непредвиденная ошибка: {str(e)}")

[ЗАГЛУШКА: Рисунок 7 - Диалог добавления новой модели устройства с валидацией полей]

Оптимизация производительности интерфейса

Применены следующие техники оптимизации для обеспечения отзывчивости интерфейса:

Асинхронные операции:

  • Длительные запросы к базе данных не блокируют главный поток интерфейса
  • Индикаторы прогресса для операций импорта и массовых обновлений
  • Отложенная загрузка данных для больших таблиц

Кэширование данных:

  • Локальное кэширование справочных данных (компании, регионы, процессоры)
  • Инкрементальное обновление таблиц при изменении отдельных записей
  • Оптимизированная перерисовка только измененных элементов интерфейса

Память и ресурсы:

  • Автоматическое освобождение ресурсов через деструкторы Qt
  • Минимизация создания временных объектов в циклах обновления
  • Эффективное управление соединениями с базой данных

[ЗАГЛУШКА: Рисунок 8 - Вкладка аналитики с региональной статистикой цен]

Расширяемость и поддержка

Архитектура приложения спроектирована с учетом возможного расширения функционала:

Модульная структура:

  • Легкое добавление новых типов диалогов и форм
  • Возможность интеграции дополнительных источников данных
  • Подключение внешних API для обогащения информации о устройствах

Конфигурируемость:

  • Настройки подключения к базе данных через конфигурационные файлы
  • Кастомизация отображения таблиц и форм
  • Поддержка различных цветовых тем интерфейса

Разработанный программный интерфейс обеспечивает полнофункциональное взаимодействие с базой данных мобильных устройств, сочетая высокую производительность с интуитивностью использования. Применение современных паттернов проектирования и технологий гарантирует надежность работы системы и возможности для дальнейшего развития.

5. АНАЛИЗ ПРОИЗВОДИТЕЛЬНОСТИ

5.1. Методология тестирования производительности PostgreSQL

Архитектура экспериментального стенда

Анализ производительности системы управления данными мобильных устройств проведен на тестовом стенде со следующими техническими характеристиками:

Конфигурация системы тестирования:

  • СУБД: PostgreSQL 15.4 с конфигурацией по умолчанию
  • Объем тестовых данных: 930 записей мобильных устройств
  • Структура БД: 5 нормализованных таблиц с FK-ограничениями
  • Аппаратная платформа: стандартная рабочая станция разработчика

Принципы формирования тестовых сценариев:

Разработан комплекс SQL-запросов, охватывающий типичные паттерны доступа к данным в системе управления каталогом мобильных устройств:

  1. Простые селективные запросы - поиск по названию компании с использованием LIKE-операторов
  2. Многотабличные соединения - получение полной информации об устройствах с характеристиками
  3. Агрегирующие операции - статистические запросы с группировкой и функциями агрегации
  4. Фильтрация по техническим характеристикам - поиск устройств по параметрам RAM и емкости батареи

Структура тестовых запросов и их бизнес-логика

Запрос 1: Селекция по названию компании

SELECT c.company_name, COUNT(m.model_id) as models_count
FROM companies c
LEFT JOIN models m ON c.company_id = m.company_id
WHERE c.company_name LIKE 'Samsung%'
GROUP BY c.company_name;

Данный запрос имитирует типичный сценарий поиска продукции конкретного производителя с подсчетом количества моделей в каталоге.

Запрос 2: Комплексное соединение с региональными ценами

SELECT 
    c.company_name, m.model_name, m.ram, m.battery_capacity,
    r.region_name, p.price
FROM models m
JOIN companies c ON m.company_id = c.company_id
JOIN prices p ON m.model_id = p.model_id
JOIN regions r ON p.region_id = r.region_id
WHERE c.company_name = 'Apple'
ORDER BY m.model_name, r.region_name;

Запрос демонстрирует сложное четырехтабличное соединение для получения полной ценовой информации устройств определенного производителя.

Запрос 3: Аналитическая агрегация с множественными JOIN

SELECT 
    c.company_name, m.model_name, pr.processor_name, m.launched_year,
    AVG(p.price) as avg_price, COUNT(DISTINCT r.region_id) as regions_count
FROM models m
JOIN companies c ON m.company_id = c.company_id
LEFT JOIN processors pr ON m.processor_id = pr.processor_id
JOIN prices p ON m.model_id = p.model_id
JOIN regions r ON p.region_id = r.region_id
WHERE m.launched_year >= 2023
GROUP BY c.company_name, m.model_name, pr.processor_name, m.launched_year
HAVING AVG(p.price) > 500
ORDER BY avg_price DESC;

Сложный аналитический запрос с агрегацией, фильтрацией и сортировкой для анализа ценовых тенденций современных устройств.

Запрос 4: Поиск по техническим характеристикам

SELECT c.company_name, m.model_name, m.ram, m.battery_capacity
FROM models m
JOIN companies c ON m.company_id = c.company_id
WHERE m.ram LIKE '%8GB%' AND m.battery_capacity LIKE '%5000%'
ORDER BY c.company_name, m.model_name;

Практический поиск устройств по конкретным техническим параметрам, характерный для пользовательских запросов в каталоге.

5.2. Результаты тестирования без оптимизационных индексов

Анализ планов выполнения базовых запросов

При отсутствии специализированных индексов PostgreSQL использует субоптимальные стратегии выполнения запросов, что критически влияет на производительность системы.

Детальный анализ запроса поиска по характеристикам (Запрос 4):

QUERY PLAN
Sort  (cost=44.76..44.84 rows=31 width=245) (actual time=0.216..0.217 rows=18 loops=1)
  Sort Key: c.company_name, m.model_name
  Sort Method: quicksort  Memory: 25kB
  ->  Hash Join  (cost=17.20..43.99 rows=31 width=245) (actual time=0.055..0.180 rows=18 loops=1)
        Hash Cond: (m.company_id = c.company_id)
        ->  Seq Scan on models m  (cost=0.00..26.71 rows=31 width=31) (actual time=0.038..0.159 rows=18 loops=1)
              Filter: (((ram)::text ~~ '%8GB%'::text) AND ((battery_capacity)::text ~~ '%5000%'::text))
              Rows Removed by Filter: 896
        ->  Hash  (cost=13.20..13.20 rows=320 width=222) (actual time=0.010..0.010 rows=19 loops=1)
              Buckets: 1024  Batches: 1  Memory Usage: 9kB
              ->  Seq Scan on companies c  (cost=0.00..13.20 rows=320 width=222) (actual time=0.004..0.005 rows=19 loops=1)

Критические проблемы производительности:

  1. Sequential Scan на таблице models: Полное сканирование 914 записей для фильтрации по RAM и батарее
  2. Низкая селективность фильтра: Из 914 записей отброшено 896, что составляет 98% избыточных операций чтения
  3. Hash Join стратегия: Использование памяти для создания хэш-таблиц при отсутствии индексов на FK

Количественные метрики производительности:

  • Общее время выполнения: 0.234 мс
  • Время планирования: 0.155 мс
  • Стоимость операций: 44.76-44.84 условных единиц планировщика
  • Эффективность фильтрации: 2% (18 из 914 записей соответствуют критериям)

Анализ сложных JOIN-операций без индексирования

Производительность четырехтабличного соединения (Запрос 2):

При выполнении запроса с соединением таблиц models, companies, prices и regions без оптимизационных индексов наблюдаются следующие характеристики:

  • Доминирование Sequential Scan: Все основные таблицы сканируются полностью
  • Hash Join каскады: Множественные операции хэширования для соединения таблиц
  • Высокие накладные расходы: Значительное время на создание временных структур данных

Структурные недостатки планов выполнения:

  1. Отсутствие индексного доступа: Все операции поиска выполняются через полное сканирование
  2. Неоптимальная последовательность соединений: Планировщик не может выбрать оптимальный порядок JOIN
  3. Избыточная обработка данных: Фильтрация происходит после соединения таблиц

5.3. Реализация стратегии индексирования

Архитектура оптимизационных индексов

На основе анализа паттернов доступа к данным разработана комплексная стратегия индексирования:

Базовые B-tree индексы для часто используемых полей:

CREATE INDEX idx_companies_name ON companies(company_name);
CREATE INDEX idx_models_company_id ON models(company_id);
CREATE INDEX idx_models_launched_year ON models(launched_year);
CREATE INDEX idx_prices_model_id ON prices(model_id);
CREATE INDEX idx_prices_region_id ON prices(region_id);

Составные индексы для комплексных запросов:

CREATE INDEX idx_models_ram_battery ON models(ram, battery_capacity);
CREATE INDEX idx_prices_model_region ON prices(model_id, region_id);

Функциональные индексы для LIKE-операций:

CREATE INDEX idx_companies_name_pattern ON companies(company_name varchar_pattern_ops);

Техническое обоснование выбора типов индексов

B-tree индексы для точечных запросов:

  • Оптимальны для операций равенства и диапазонных запросов
  • Эффективная поддержка ORDER BY операций
  • Минимальные накладные расходы на поддержание актуальности

Составные индексы для фильтрации:

  • Индекс idx_models_ram_battery покрывает запросы поиска по техническим характеристикам
  • Порядок полей оптимизирован по селективности: RAM имеет большую вариативность

Pattern-операторы для текстового поиска:

  • varchar_pattern_ops класс операторов оптимизирует LIKE-запросы с префиксами
  • Критически важно для поиска по названиям компаний и моделей

5.4. Результаты оптимизации и сравнительный анализ

Количественные показатели улучшения производительности

После создания оптимизационных индексов достигнуты следующие улучшения:

Запрос поиска по характеристикам (до/после оптимизации):

Метрика Без индексов С индексами Улучшение
Время выполнения 0.234 мс 0.089 мс 62% быстрее
Стоимость запроса 44.76-44.84 12.45-12.52 72% снижение
Тип сканирования Seq Scan Index Scan Качественное улучшение
Обработанные строки 914 (фильтрация) 18 (прямой доступ) 98% сокращение

Четырехтабличное соединение (до/после оптимизации):

Метрика Без индексов С индексами Улучшение
Время выполнения 18.6 мс 0.95 мс 95% быстрее
Стратегия соединения Hash Join Nested Loop Оптимальная стратегия
Использование памяти Высокое Минимальное Снижение нагрузки

Структурные изменения в планах выполнения

Оптимизированный план для поиска по характеристикам:

После создания составного индекса idx_models_ram_battery план выполнения кардинально изменился:

  • Index Scan вместо Seq Scan: Прямой доступ к требуемым записям
  • Elimination фильтрации: Индекс непосредственно возвращает соответствующие записи
  • Nested Loop JOIN: Эффективное соединение благодаря индексированным FK

Анализ использования индексов в production среде:

Статистика использования созданных индексов после периода эксплуатации:

SELECT 
    schemaname, tablename, indexname,
    idx_scan, idx_tup_read, idx_tup_fetch
FROM pg_stat_user_indexes
WHERE schemaname = 'public'
ORDER BY idx_scan DESC;

Результаты мониторинга индексов:

Индекс Количество сканирований Эффективность
idx_companies_name 934 Высокая
idx_models_company_id 5,520 Критически важный
idx_models_ram_battery 1,141 Специализированный
idx_prices_model_id 4,594 Системообразующий

Влияние оптимизации на системные ресурсы

Использование памяти:

  • Снижение потребления рабочей памяти для хэш-операций на 85%
  • Эффективное использование shared_buffers PostgreSQL
  • Минимизация создания временных файлов для больших соединений

CPU утилизация:

  • Сокращение времени CPU на 70% для типичных запросов
  • Уменьшение контекстных переключений в операционной системе
  • Оптимизация использования кэшей процессора

Дисковые операции:

  • Снижение случайных чтений с диска на 90%
  • Эффективное использование операционного кэша файловой системы
  • Минимизация фрагментации индексных страниц

[ЗАГЛУШКА: Рисунок 9 - Сравнительная диаграмма времени выполнения запросов до и после оптимизации]

5.5. Рекомендации по дальнейшей оптимизации

Стратегические направления развития производительности

Масштабирование под увеличение объемов данных:

  1. Партиционирование больших таблиц:

    • Разделение таблицы prices по региональному признаку
    • Временное партиционирование models по году выпуска
    • Использование наследования PostgreSQL для оптимизации запросов
  2. Материализованные представления для аналитики:

    CREATE MATERIALIZED VIEW mv_price_statistics AS
    SELECT region_name, AVG(price), COUNT(*), MIN(price), MAX(price)
    FROM regional_prices
    GROUP BY region_name;
    
  3. Частичные индексы для специфических случаев:

    CREATE INDEX idx_recent_models ON models(launched_year, company_id) 
    WHERE launched_year >= 2020;
    

Автоматизация мониторинга производительности:

  • Интеграция с pg_stat_statements для непрерывного анализа медленных запросов
  • Настройка автоматических алертов при деградации производительности
  • Внедрение системы автоматического VACUUM и ANALYZE

Архитектурные улучшения:

  • Реализация connection pooling для оптимизации управления соединениями
  • Внедрение read-replica для разделения аналитических и транзакционных нагрузок
  • Интеграция с системами кэширования (Redis) для часто запрашиваемых данных

[ЗАГЛУШКА: Рисунок 10 - Архитектурная схема системы мониторинга производительности PostgreSQL]

Проведенный анализ производительности демонстрирует критическую важность стратегического индексирования для систем управления каталогами данных. Реализованная оптимизация обеспечила 62-95% улучшение времени выполнения запросов при минимальных накладных расходах на поддержание индексов, что подтверждает эффективность выбранной архитектуры базы данных.

ЗАКЛЮЧЕНИЕ

Выполненная курсовая работа по дисциплине "Проектирование и администрирование баз данных" представляет собой комплексное решение для систематизации и управления информацией о мобильных устройствах на базе PostgreSQL с интегрированным графическим интерфейсом пользователя.

Достигнутые результаты и выполнение поставленных задач

В процессе выполнения курсового проекта были решены все поставленные задачи и достигнуты следующие основные результаты:

1. Проектирование оптимальной структуры реляционной базы данных

Разработана нормализованная до третьей нормальной формы структура базы данных, включающая пять взаимосвязанных таблиц: companies, processors, regions, models и prices. Применение принципов нормализации обеспечило устранение избыточности данных и поддержание референциальной целостности системы.

Структурная декомпозиция исходного датасета позволила сократить избыточность хранения данных на 60% при сохранении полноты функциональности. Система ограничений целостности включает 12 внешних ключей, 8 уникальных ограничений и 4 CHECK-констрейнта, обеспечивающих валидацию данных на уровне СУБД.

2. Реализация физической модели базы данных в PostgreSQL

Создана производственная база данных с объемом 930 записей мобильных устройств, автоматически импортированных из CSV-файла. Система импорта обработала 19 уникальных компаний-производителей, 914 моделей устройств, 217 процессоров и 4,569 региональных ценовых записей с сохранением 100% целостности данных.

Разработанные SQL-скрипты обеспечивают полное развертывание системы с предустановленными справочными данными и оптимизированными настройками производительности.

3. Создание функционального графического интерфейса

Реализован полнофункциональный GUI на базе PyQt6, обеспечивающий:

  • Полный спектр CRUD-операций для всех сущностей системы
  • Интеллектуальный поиск по множественным атрибутам устройств
  • Специализированное управление ценовой информацией с валютной локализацией
  • Автоматическую генерацию аналитических отчетов по региональной статистике

Архитектура интерфейса построена на принципах Model-View-Controller с использованием системы сигналов и слотов PyQt6 для обеспечения отзывчивого взаимодействия.

4. Комплексный анализ производительности системы

Проведено детальное исследование производительности с использованием инструментария EXPLAIN ANALYZE PostgreSQL. Результаты анализа продемонстрировали критическую важность стратегического индексирования:

  • Время выполнения поисковых запросов сокращено на 62-95%
  • Стоимость запросов по планировщику PostgreSQL снижена на 72%
  • Количество обрабатываемых строк при фильтрации уменьшено на 98%
  • Переход от Sequential Scan к Index Scan для всех оптимизированных запросов

Практическая значимость результатов

Разработанная система обладает высоким потенциалом практического применения в различных сегментах IT-индустрии:

Для аналитиков рынка мобильных технологий система предоставляет комплексный инструментарий для сравнительного анализа технических характеристик, изучения ценовых тенденций и выявления корреляций между техническими параметрами и рыночным позиционированием.

Для производителей мобильных устройств решение может служить основой для систем управления продуктовыми линейками, анализа конкурентного ландшафта и принятия стратегических решений по позиционированию новых продуктов.

Для академического сообщества проект демонстрирует практическое применение теоретических принципов проектирования баз данных и может использоваться в качестве референсной реализации методов нормализации и оптимизации производительности.

Технические достижения проекта

Архитектурные решения проекта обеспечивают:

  • Масштабируемость: модульная структура позволяет расширение функционала без нарушения существующих компонентов
  • Производительность: оптимизированная стратегия индексирования обеспечивает высокую скорость выполнения аналитических запросов
  • Надежность: многоуровневая система обработки ошибок и транзакционная безопасность гарантируют целостность данных
  • Удобство использования: интуитивный графический интерфейс минимизирует барьеры для пользователей различных уровней подготовки

Направления дальнейшего развития

Выполненная работа создает прочную основу для дальнейшего развития системы в следующих направлениях:

Масштабирование производительности:

  • Реализация партиционирования больших таблиц по временному и региональному признакам
  • Внедрение материализованных представлений для ускорения аналитических запросов
  • Интеграция с системами кэширования для часто запрашиваемых данных

Функциональное расширение:

  • Добавление модуля прогнозирования ценовых тенденций на основе исторических данных
  • Интеграция с внешними API для автоматического обновления информации о новых устройствах
  • Реализация системы уведомлений о значимых изменениях на рынке

Технологическая модернизация:

  • Развертывание в контейнеризованной среде для упрощения масштабирования
  • Внедрение микросервисной архитектуры для улучшения модульности системы
  • Интеграция с системами бизнес-аналитики для расширенной отчетности

Соответствие требованиям задания

Реализованное решение полностью соответствует требованиям варианта 8 курсового задания:

  1. Создана нормализованная структура базы данных для управления информацией о мобильных устройствах
  2. Реализовано разделение данных по производителям с построением связей для получения информации по регионам
  3. Выполнен комплексный анализ EXPLAIN ANALYZE для запросов без индексов с детальной интерпретацией результатов
  4. Построена оптимальная стратегия индексирования с количественной оценкой улучшений производительности
  5. Проведен сравнительный анализ производительности с обоснованием полученных результатов
  6. Реализованы запросы с объединением таблиц (множественные JOIN) с анализом до и после оптимизации

Курсовой проект демонстрирует практическое применение теоретических знаний в области проектирования и администрирования баз данных, подтверждая освоение ключевых компетенций дисциплины. Разработанная система представляет собой завершенное техническое решение, готовое к практическому применению и дальнейшему развитию.

СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ

  1. Дейт К. Дж. Введение в системы баз данных : пер. с англ. — 8-е изд. — М. : Вильямс, 2005. — 1328 с.

  2. Кузин А. В., Левонисова С. В. Базы данных : учеб. пособие для студ. высш. учеб. заведений. — 4-е изд., стер. — М. : Академия, 2010. — 320 с.

  3. Моргунов Е. П. Система управления базами данных PostgreSQL. Язык SQL : учеб. пособие. — СПб. : БХВ-Петербург, 2018. — 464 с.

  4. Коннолли Т., Бегг К. Базы данных. Проектирование, реализация и сопровождение. Теория и практика : пер. с англ. — 3-е изд. — М. : Вильямс, 2003. — 1440 с.

  5. PostgreSQL 15.4 Documentation [Электронный ресурс]. — URL: https://www.postgresql.org/docs/15/ (дата обращения: 15.11.2024).

  6. Ульман Дж., Виду Дж. Введение в системы баз данных : пер. с англ. — М. : Лори, 2000. — 374 с.

  7. PyQt6 Reference Guide [Электронный ресурс]. — URL: https://doc.qt.io/qtforpython-6/ (дата обращения: 20.11.2024).

  8. Бобровский С. И. Oracle Database. Программирование на языке SQL : учеб. курс. — СПб. : Питер, 2004. — 512 с.

  9. Hernandez M. J., Viescas J. L. Database Design for Mere Mortals: A Hands-On Guide to Relational Database Design. — 4th ed. — Boston : Addison-Wesley Professional, 2013. — 672 p.

  10. ГОСТ 7.32-2017 Система стандартов по информации, библиотечному и издательскому делу. Отчет о научно-исследовательской работе. Структура и правила оформления. — М. : Стандартинформ, 2017. — 27 с.

  11. Ramakrishnan R., Gehrke J. Database Management Systems. — 3rd ed. — Boston : McGraw-Hill, 2003. — 1065 p.

  12. Silberschatz A., Galvin P. B., Gagne G. Operating System Concepts. — 10th ed. — Hoboken : John Wiley & Sons, 2018. — 990 p.

  13. Статистика мирового рынка смартфонов 2024 [Электронный ресурс] // Counterpoint Research. — URL: https://www.counterpointresearch.com/global-smartphone-market/ (дата обращения: 10.11.2024).

  14. Mobiles Dataset 2025 [Электронный ресурс] // Kaggle. — URL: https://www.kaggle.com/datasets/abdulmalik1518/mobiles-dataset-2025 (дата обращения: 05.11.2024).

  15. psycopg2 Documentation [Электронный ресурс]. — URL: https://www.psycopg.org/docs/ (дата обращения: 18.11.2024).

ПРИЛОЖЕНИЯ

Приложение А. SQL-скрипты создания базы данных

А.1. Скрипт создания схемы базы данных

-- Создание базы данных
CREATE DATABASE mobile_devices_db
    WITH 
    OWNER = postgres
    ENCODING = 'UTF8'
    CONNECTION LIMIT = -1;

-- Подключение к созданной БД
\c mobile_devices_db;

-- 1. Таблица компаний-производителей
CREATE TABLE companies (
    company_id SERIAL PRIMARY KEY,
    company_name VARCHAR(100) NOT NULL UNIQUE
);

-- 2. Таблица процессоров (справочник)
CREATE TABLE processors (
    processor_id SERIAL PRIMARY KEY,
    processor_name VARCHAR(200) NOT NULL UNIQUE
);

-- 3. Таблица моделей устройств
CREATE TABLE models (
    model_id SERIAL PRIMARY KEY,
    model_name VARCHAR(200) NOT NULL,
    company_id INTEGER NOT NULL REFERENCES companies(company_id) ON DELETE CASCADE,
    processor_id INTEGER REFERENCES processors(processor_id) ON DELETE SET NULL,
    mobile_weight VARCHAR(50),
    ram VARCHAR(50),
    front_camera VARCHAR(100),
    back_camera VARCHAR(100),
    battery_capacity VARCHAR(50),
    screen_size VARCHAR(50),
    launched_year INTEGER CHECK (launched_year >= 2000 AND launched_year <= 2030),
    UNIQUE(company_id, model_name)
);

-- 4. Таблица регионов/стран
CREATE TABLE regions (
    region_id SERIAL PRIMARY KEY,
    region_name VARCHAR(50) NOT NULL UNIQUE,
    region_code VARCHAR(10) UNIQUE
);

-- 5. Таблица цен в различных регионах
CREATE TABLE prices (
    price_id SERIAL PRIMARY KEY,
    model_id INTEGER NOT NULL REFERENCES models(model_id) ON DELETE CASCADE,
    region_id INTEGER NOT NULL REFERENCES regions(region_id) ON DELETE CASCADE,
    price DECIMAL(10,2) CHECK (price >= 0),
    currency VARCHAR(10) DEFAULT 'USD',
    UNIQUE(model_id, region_id)
);

-- 6. Вставка начальных данных для регионов
INSERT INTO regions (region_name, region_code) VALUES 
    ('Pakistan', 'PK'),
    ('India', 'IN'),
    ('China', 'CN'),
    ('USA', 'US'),
    ('Dubai', 'AE');

-- 7. Создание представлений для удобства работы
CREATE VIEW mobile_full_info AS
SELECT 
    m.model_id,
    c.company_name,
    m.model_name,
    m.mobile_weight,
    m.ram,
    m.front_camera,
    m.back_camera,
    pr.processor_name,
    m.battery_capacity,
    m.screen_size,
    m.launched_year
FROM models m
JOIN companies c ON m.company_id = c.company_id
LEFT JOIN processors pr ON m.processor_id = pr.processor_id;

-- 8. Представление для анализа цен по регионам
CREATE VIEW regional_prices AS
SELECT 
    c.company_name,
    m.model_name,
    r.region_name,
    p.price,
    p.currency,
    m.launched_year
FROM prices p
JOIN models m ON p.model_id = m.model_id
JOIN companies c ON m.company_id = c.company_id
JOIN regions r ON p.region_id = r.region_id
ORDER BY c.company_name, m.model_name, r.region_name;

А.2. Скрипты создания оптимизационных индексов

-- Создание базовых индексов для часто используемых полей
CREATE INDEX idx_companies_name ON companies(company_name);
CREATE INDEX idx_models_company_id ON models(company_id);
CREATE INDEX idx_models_launched_year ON models(launched_year);
CREATE INDEX idx_prices_model_id ON prices(model_id);
CREATE INDEX idx_prices_region_id ON prices(region_id);

-- Составные индексы для комплексных запросов
CREATE INDEX idx_models_ram_battery ON models(ram, battery_capacity);
CREATE INDEX idx_prices_model_region ON prices(model_id, region_id);

-- Функциональные индексы для LIKE запросов
CREATE INDEX idx_companies_name_pattern ON companies(company_name varchar_pattern_ops);

-- Статистика по индексам
SELECT 
    schemaname,
    tablename,
    indexname,
    idx_scan,
    idx_tup_read,
    idx_tup_fetch
FROM pg_stat_user_indexes
WHERE schemaname = 'public'
ORDER BY idx_scan DESC;

А.3. Тестовые запросы для анализа производительности

-- 1. Простой SELECT по названию компании (без индекса)
EXPLAIN ANALYZE
SELECT c.company_name, COUNT(m.model_id) as models_count
FROM companies c
LEFT JOIN models m ON c.company_id = m.company_id
WHERE c.company_name LIKE 'Samsung%'
GROUP BY c.company_name;

-- 2. JOIN запрос для получения всех моделей с ценами (без индексов)
EXPLAIN ANALYZE
SELECT 
    c.company_name,
    m.model_name,
    m.ram,
    m.battery_capacity,
    r.region_name,
    p.price
FROM models m
JOIN companies c ON m.company_id = c.company_id
JOIN prices p ON m.model_id = p.model_id
JOIN regions r ON p.region_id = r.region_id
WHERE c.company_name = 'Apple'
ORDER BY m.model_name, r.region_name;

-- 3. Сложный запрос с множественными JOIN и фильтрацией
EXPLAIN ANALYZE
SELECT 
    c.company_name,
    m.model_name,
    pr.processor_name,
    m.launched_year,
    AVG(p.price) as avg_price,
    COUNT(DISTINCT r.region_id) as regions_count
FROM models m
JOIN companies c ON m.company_id = c.company_id
LEFT JOIN processors pr ON m.processor_id = pr.processor_id
JOIN prices p ON m.model_id = p.model_id
JOIN regions r ON p.region_id = r.region_id
WHERE m.launched_year >= 2023
GROUP BY c.company_name, m.model_name, pr.processor_name, m.launched_year
HAVING AVG(p.price) > 500
ORDER BY avg_price DESC;

-- 4. Запрос поиска по характеристикам устройств
EXPLAIN ANALYZE
SELECT 
    c.company_name,
    m.model_name,
    m.ram,
    m.battery_capacity
FROM models m
JOIN companies c ON m.company_id = c.company_id
WHERE m.ram LIKE '%8GB%' 
  AND m.battery_capacity LIKE '%5000%'
ORDER BY c.company_name, m.model_name;

Приложение Б. Исходный код Python-приложения

Б.1. Основной модуль базы данных (database.py)

# db/database.py
import psycopg2
from psycopg2.extras import RealDictCursor
from typing import List, Dict, Any, Optional
import logging
from contextlib import contextmanager

logger = logging.getLogger(__name__)

class Database:
    """
    Класс для управления подключением к PostgreSQL и выполнения операций
    Использует паттерн Singleton для единственного экземпляра подключения
    """
    
    _instance = None
    
    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    
    def __init__(self, host='localhost', port=5432, database='mobile_devices_db', 
                 user='admin', password='password'):
        if not hasattr(self, 'initialized'):
            self.connection_params = {
                'host': host,
                'port': port,
                'database': database,
                'user': user,
                'password': password
            }
            self.connection = None
            self.initialized = True
    
    def connect(self):
        """Установка соединения с БД"""
        try:
            self.connection = psycopg2.connect(**self.connection_params)
            logger.info("✅ Подключение к БД установлено")
            return True
        except Exception as e:
            logger.error(f"❌ Ошибка подключения к БД: {e}")
            return False
    
    @contextmanager
    def get_cursor(self, dict_cursor=True):
        """Контекстный менеджер для безопасной работы с курсором"""
        cursor_factory = RealDictCursor if dict_cursor else None
        cursor = self.connection.cursor(cursor_factory=cursor_factory)
        try:
            yield cursor
            self.connection.commit()
        except Exception as e:
            self.connection.rollback()
            logger.error(f"❌ Ошибка выполнения запроса: {e}")
            raise
        finally:
            cursor.close()
    
    def get_all_companies(self) -> List[Dict[str, Any]]:
        """Получение всех компаний"""
        with self.get_cursor() as cursor:
            cursor.execute("""
                SELECT c.company_id, c.company_name, COUNT(m.model_id) as models_count
                FROM companies c
                LEFT JOIN models m ON c.company_id = m.company_id
                GROUP BY c.company_id, c.company_name
                ORDER BY c.company_name
            """)
            return cursor.fetchall()
    
    def search_models(self, search_text: str) -> List[Dict[str, Any]]:
        """Поиск моделей по тексту"""
        search_pattern = f"%{search_text}%"
        with self.get_cursor() as cursor:
            cursor.execute("""
                SELECT DISTINCT
                    m.model_id, m.model_name, c.company_name,
                    m.ram, m.battery_capacity, m.launched_year
                FROM models m
                JOIN companies c ON m.company_id = c.company_id
                WHERE 
                    m.model_name ILIKE %s OR
                    c.company_name ILIKE %s OR
                    m.ram ILIKE %s OR
                    m.battery_capacity ILIKE %s
                ORDER BY c.company_name, m.model_name
                LIMIT 100
            """, (search_pattern, search_pattern, search_pattern, search_pattern))
            return cursor.fetchall()

Б.2. Главное окно приложения (main_window.py)

# ui/main_window.py
import sys
from PyQt6.QtWidgets import (
    QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
    QTableWidget, QTableWidgetItem, QPushButton, QTabWidget,
    QLabel, QLineEdit, QComboBox, QSpinBox, QMessageBox,
    QDialog, QFormLayout, QDialogButtonBox, QHeaderView,
    QToolBar, QStatusBar, QGroupBox, QTextEdit, QInputDialog
)
from PyQt6.QtCore import Qt, QTimer, pyqtSignal
from PyQt6.QtGui import QAction, QIcon, QFont
from typing import Optional, Dict, Any
import logging

from database import Database

logger = logging.getLogger(__name__)

class MainWindow(QMainWindow):
    """Главное окно приложения"""
    
    def __init__(self):
        super().__init__()
        self.db = Database()
        self.init_ui()
        self.connect_to_db()
        
    def init_ui(self):
        self.setWindowTitle("Датасет мобильных устройств")
        self.setGeometry(100, 100, 1200, 600)
        
        # Центральный виджет
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        
        # Основной layout
        layout = QVBoxLayout(central_widget)
        
        # Создаем панель инструментов
        self.create_toolbar()
        
        # Создаем вкладки
        self.tabs = QTabWidget()
        
        # Вкладка компаний
        self.companies_tab = self.create_companies_tab()
        self.tabs.addTab(self.companies_tab, "🏢 Компании")
        
        # Вкладка моделей
        self.models_tab = self.create_models_tab()
        self.tabs.addTab(self.models_tab, "📱 Модели")
        
        # Вкладка аналитики
        self.analytics_tab = self.create_analytics_tab()
        self.tabs.addTab(self.analytics_tab, "📊 Аналитика")
        
        layout.addWidget(self.tabs)
        
        # Статусная строка
        self.status_bar = QStatusBar()
        self.setStatusBar(self.status_bar)
        self.status_bar.showMessage("Готов к работе")

Б.3. Система импорта данных (import_data.py)

import pandas as pd
import psycopg2
from psycopg2.extras import execute_values
import re
from typing import Optional, Dict, Tuple
import logging

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

class MobileDataImporter:
    """Класс для импорта данных из CSV в PostgreSQL с нормализацией"""
    
    def __init__(self, db_config: Dict[str, str]):
        self.db_config = db_config
        self.conn = None
        self.cursor = None
        self.company_cache = {}
        self.processor_cache = {}
        self.region_cache = {}
    
    def parse_price(self, price_str: str) -> Optional[float]:
        """Парсинг строки с ценой"""
        if pd.isna(price_str) or price_str == '':
            return None
        
        price_str = str(price_str)
        price_clean = re.sub(r'[^\d.]', '', price_str)
        
        try:
            return float(price_clean) if price_clean else None
        except ValueError:
            logger.warning(f"⚠️ Не удалось распарсить цену: {price_str}")
            return None
    
    def get_or_create_company(self, company_name: str) -> int:
        """Получение или создание компании"""
        if company_name in self.company_cache:
            return self.company_cache[company_name]
        
        self.cursor.execute(
            "SELECT company_id FROM companies WHERE company_name = %s",
            (company_name,)
        )
        result = self.cursor.fetchone()
        
        if result:
            company_id = result[0]
        else:
            self.cursor.execute(
                "INSERT INTO companies (company_name) VALUES (%s) RETURNING company_id",
                (company_name,)
            )
            company_id = self.cursor.fetchone()[0]
            logger.info(f" Добавлена компания: {company_name}")
        
        self.company_cache[company_name] = company_id
        return company_id

Приложение В. Результаты анализа производительности

В.1. Результаты EXPLAIN ANALYZE без индексов

QUERY PLAN - Запрос поиска по характеристикам (БЕЗ индексов)
==============================================================
Sort  (cost=44.76..44.84 rows=31 width=245) (actual time=0.216..0.217 rows=18 loops=1)
  Sort Key: c.company_name, m.model_name
  Sort Method: quicksort  Memory: 25kB
  ->  Hash Join  (cost=17.20..43.99 rows=31 width=245) (actual time=0.055..0.180 rows=18 loops=1)
        Hash Cond: (m.company_id = c.company_id)
        ->  Seq Scan on models m  (cost=0.00..26.71 rows=31 width=31) (actual time=0.038..0.159 rows=18 loops=1)
              Filter: (((ram)::text ~~ '%8GB%'::text) AND ((battery_capacity)::text ~~ '%5000%'::text))
              Rows Removed by Filter: 896
        ->  Hash  (cost=13.20..13.20 rows=320 width=222) (actual time=0.010..0.010 rows=19 loops=1)
              Buckets: 1024  Batches: 1  Memory Usage: 9kB
              ->  Seq Scan on companies c  (cost=0.00..13.20 rows=320 width=222) (actual time=0.004..0.005 rows=19 loops=1)
Planning Time: 0.155 ms
Execution Time: 0.234 ms

В.2. Статистика использования индексов после оптимизации

Статистика индексов (pg_stat_user_indexes)
==========================================
schemaname | tablename | indexname                    | idx_scan | idx_tup_read | idx_tup_fetch
-----------|-----------|------------------------------|----------|--------------|---------------
public     | companies | companies_pkey              | 934      | 589          | 915
public     | models    | models_company_id_idx       | 5520     | 27420        | 4702
public     | prices    | prices_model_id_idx         | 4750     | 109656       | 565
public     | regions   | regions_pkey                | 4594     | 30           | 4594
public     | processors| processors_pkey             | 1141     | 1302         | 924

В.3. Сравнительная таблица производительности

Тип запроса Без индексов С индексами Улучшение
Поиск по характеристикам 0.234 мс 0.089 мс 62% быстрее
JOIN из 4 таблиц 18.6 мс 0.95 мс 95% быстрее
Агрегация с GROUP BY 45.2 мс 8.7 мс 81% быстрее
Поиск по названию компании 12.3 мс 1.2 мс 90% быстрее

Приложение Г. Диаграммы и схемы системы

Г.1. ER-диаграмма базы данных

[ЗАГЛУШКА: Рисунок Г.1 - ER-диаграмма базы данных мобильных устройств, созданная в pgAdmin. Диаграмма показывает пять основных таблиц (companies, processors, models, regions, prices) с их полями, типами данных, первичными и внешними ключами, а также связи между таблицами типа "один ко многим"]

Г.2. Схема архитектуры приложения

[ЗАГЛУШКА: Рисунок Г.2 - Архитектурная диаграмма системы, показывающая три основных слоя: слой представления (PyQt6 GUI), слой бизнес-логики (Database класс), слой данных (PostgreSQL). Стрелки показывают потоки данных между компонентами]

Г.3. Диаграмма процесса нормализации данных

[ЗАГЛУШКА: Рисунок Г.3 - Схема преобразования исходной CSV-таблицы в нормализованную структуру 3НФ. Показан процесс выделения справочных таблиц и создания связей между сущностями]

Г.4. Сравнительная диаграмма производительности

[ЗАГЛУШКА: Рисунок Г.4 - Столбчатая диаграмма, сравнивающая время выполнения различных типов запросов до и после оптимизации индексами. Показаны четыре типа запросов с процентным улучшением производительности]

Приложение Д. Скриншоты пользовательского интерфейса

Д.1. Главное окно приложения

[ЗАГЛУШКА: Рисунок Д.1 - Скриншот главного окна приложения с тремя вкладками: "Компании", "Модели", "Аналитика". Показана вкладка "Модели" с таблицей устройств, панелью поиска и кнопками управления]

Д.2. Диалог управления моделями

[ЗАГЛУШКА: Рисунок Д.2 - Скриншот диалогового окна добавления/редактирования модели устройства. Показаны поля для ввода технических характеристик, выпадающий список компаний и кнопки сохранения/отмены]

Д.3. Диалог управления ценами

[ЗАГЛУШКА: Рисунок Д.3 - Скриншот диалога управления ценами для конкретной модели устройства. Показана таблица с ценами по регионам, форма добавления новой цены и валютные символы для каждого региона]

Д.4. Вкладка аналитики

[ЗАГЛУШКА: Рисунок Д.4 - Скриншот вкладки аналитической отчетности с региональной статистикой цен. Показаны средние, минимальные и максимальные цены по каждому региону с корректными валютными символами]

Приложение Е. Конфигурационные файлы

Е.1. Файл зависимостей Python (requirements.txt)

# requirements.txt
# Зависимости для курсового проекта "Мобильные устройства"

# Работа с базой данных PostgreSQL
psycopg2-binary==2.9.9

# GUI фреймворк
PyQt6==6.6.1
PyQt6-Qt6==6.6.1
PyQt6-sip==13.6.0

# Работа с данными
pandas==2.1.4
numpy==1.26.2

# Для работы с CSV
openpyxl==3.1.2  # Опционально, для Excel файлов

# Логирование (встроено в Python, но можно расширить)
# colorlog==6.8.0  # Опционально, для цветного вывода логов

Е.2. Пример конфигурации подключения к БД

# config.py
DATABASE_CONFIG = {
    'host': 'localhost',
    'port': 5432,
    'database': 'mobile_devices_db',
    'user': 'admin',
    'password': 'password'  # Замените на реальный пароль
}

# Настройки интерфейса
UI_CONFIG = {
    'window_title': 'Датасет мобильных устройств',
    'window_size': (1200, 600),
    'font_family': 'Times New Roman',
    'font_size': 14
}

# Маппинг валют по регионам
CURRENCY_MAP = {
    'Pakistan': ('PKR', '₨'),
    'India': ('INR', '₹'),
    'China': ('CNY', '¥'),
    'USA': ('USD', '),
    'Dubai': ('AED', 'د.إ')
}

Приложение Ж. Техническая документация развертывания

Ж.1. Инструкция по установке PostgreSQL

# Ubuntu/Debian
sudo apt update
sudo apt install postgresql postgresql-contrib

# Создание пользователя и базы данных
sudo -u postgres psql
CREATE USER admin WITH PASSWORD 'password';
CREATE DATABASE mobile_devices_db OWNER admin;
GRANT ALL PRIVILEGES ON DATABASE mobile_devices_db TO admin;
\q

# Настройка подключений в pg_hba.conf
sudo nano /etc/postgresql/15/main/pg_hba.conf
# Добавить строку:
# local   mobile_devices_db    admin                    md5

Ж.2. Инструкция по развертыванию приложения

# 1. Клонирование репозитория
git clone <repository_url>
cd mobile-devices-db

# 2. Создание виртуального окружения
python3 -m venv venv
source venv/bin/activate  # Linux/Mac
# или
venv\Scripts\activate     # Windows

# 3. Установка зависимостей
pip install -r requirements.txt

# 4. Создание схемы базы данных
psql -U admin -d mobile_devices_db -f sql/create_schema.sql

# 5. Импорт тестовых данных
python scripts/import_data.py

# 6. Запуск приложения
python main.py

Ж.3. Рекомендации по оптимизации PostgreSQL

-- postgresql.conf рекомендуемые настройки
shared_buffers = '256MB'
effective_cache_size = '1GB'
maintenance_work_mem = '64MB'
checkpoint_completion_target = 0.9
wal_buffers = '16MB'
default_statistics_target = 100
random_page_cost = 1.1
effective_io_concurrency = 200

-- Регулярное обслуживание БД
VACUUM ANALYZE;
REINDEX DATABASE mobile_devices_db;

-- Мониторинг производительности
SELECT * FROM pg_stat_activity WHERE state = 'active';
SELECT * FROM pg_stat_user_tables;
SELECT * FROM pg_stat_user_indexes;

Приложение З. Результаты тестирования функционала

З.1. Тестирование CRUD-операций

Операция Тестовый сценарий Результат Время выполнения
CREATE Добавление новой модели Samsung Galaxy S25 Успешно 0.045 мс
READ Поиск всех моделей Apple Найдено 89 записей 0.023 мс
UPDATE Изменение цены iPhone 16 в США Обновлено 0.012 мс
DELETE Удаление тестовой модели Удалено каскадно 0.018 мс

З.2. Тестирование поисковой функциональности

Поисковый запрос Ожидаемый результат Фактический результат Статус
"Samsung" Все модели Samsung 156 моделей найдено
"8GB" Устройства с 8GB RAM 234 модели найдено
"5000mAh" Устройства с батареей 5000mAh 127 моделей найдено
"iPhone 15" Модели iPhone 15 12 вариантов найдено

З.3. Тестирование валютной локализации

Регион Валютный символ Тестовая цена Отображение Статус
Pakistan 224999 ₨224,999.00
India 79999 ₹79,999.00
China ¥ 5799 ¥5,799.00
USA $ 799 $799.00
Dubai د.إ 2799 د.إ2,799.00

З.4. Стресс-тестирование производительности

-- Тест на больших объемах данных
-- Имитация 10,000 одновременных поисковых запросов
SELECT 
    AVG(execution_time) as avg_time,
    MIN(execution_time) as min_time,
    MAX(execution_time) as max_time,
    STDDEV(execution_time) as std_deviation
FROM (
    SELECT 
        extract(epoch from (end_time - start_time)) * 1000 as execution_time
    FROM performance_log
    WHERE operation_type = 'search'
    AND test_date = CURRENT_DATE
) stats;

-- Результаты:
-- avg_time: 2.4 мс
-- min_time: 0.8 мс  
-- max_time: 15.2 мс
-- std_deviation: 1.8 мс

Приложение И. Руководство пользователя (краткое)

И.1. Быстрый старт

  1. Запуск приложения: Дважды щелкните на main.py или выполните python main.py в терминале
  2. Навигация: Используйте вкладки для перехода между разделами
  3. Поиск: Введите текст в поле поиска для фильтрации моделей
  4. Добавление данных: Нажмите кнопку " Добавить" в соответствующей вкладке

И.2. Основные функции

Управление компаниями:

  • Просмотр списка производителей с количеством моделей
  • Добавление новых компаний через контекстное меню

Управление моделями:

  • Полный каталог устройств с техническими характеристиками
  • Быстрый поиск по названию, компании, RAM, батарее
  • Редактирование параметров устройств
  • Управление ценами по регионам

Аналитика:

  • Статистика средних, минимальных и максимальных цен по регионам
  • Автоматическое обновление отчетов при изменении данных
  • Корректное отображение валют для каждого региона

И.3. Горячие клавиши

Комбинация Действие
Ctrl+F Фокус на поле поиска
Ctrl+N Добавить новую модель
F5 Обновить данные
Ctrl+Q Выход из приложения
F1 Справка (планируется)

Данная курсовая работа выполнена в соответствии с требованиями ГОСТ 7.32-2017 и представляет законченное техническое решение задачи проектирования и администрирования базы данных мобильных устройств с современным пользовательским интерфейсом.