В 1970 году британский ученый Эдгар Ф. Кодд опубликовал статью «A Relational Model of Data for Large Shared Data Banks», которая стала поворотным моментом в истории информационных технологий, заложив основы для всех современных реляционных баз данных. Эта работа не просто предложила новую архитектуру хранения информации, но и изменила подход к ее организации, сделав данные более структурированными, доступными и управляемыми. Сегодня, спустя более пятидесяти лет, принципы, сформулированные Коддом, остаются краеугольным камнем в проектировании информационных систем, от небольших приложений до гигантских корпоративных хранилищ.
Введение
В современном мире, где объемы информации растут экспоненциально, системы управления базами данных (СУБД) стали незаменимым инструментом для эффективного хранения, обработки и анализа данных. От финансовых учреждений до розничных сетей, от здравоохранения до сельского хозяйства – повсюду требуется точный и актуальный учет. В контексте аграрного сектора, например, эффективное управление данными о фруктовом саде может значительно повысить урожайность, оптимизировать затраты и улучшить качество продукции. Стоит отметить, что именно системный подход к управлению информацией позволяет превратить набор разрозненных данных в мощный аналитический инструмент, способный принимать стратегические решения.
Представленная контрольная работа ставит своей целью разработку структурированного плана для создания системы учета фруктового сада, демонстрируя глубокое понимание принципов проектирования реляционных баз данных и основ языка SQL. В рамках данного исследования будут рассмотрены ключевые концепции реляционной модели, поэтапный процесс проектирования базы данных, включая инфологическое и даталогическое моделирование, а также применение нормализации до продвинутых форм. Особое внимание будет уделено практическому применению SQL-запросов для манипуляции данными и методам обеспечения целостности и оптимизации производительности базы данных.
Структура работы разработана таким образом, чтобы читатель, будь то студент технического вуза или опытный IT-специалист, мог последовательно пройти путь от теоретических основ до практических аспектов создания и управления базой данных, способной эффективно решать реальные бизнес-задачи в условиях фруктового сада. Такой комплексный подход позволит не только глубоко изучить предмет, но и применить полученные знания для создания надежной и масштабируемой информационной системы.
Основы Реляционной Модели Данных
Реляционная модель данных (РМД) — это не просто способ хранения информации, это целая философия организации данных, опирающаяся на строгие математические принципы. Ее появление стало революцией, предложив стройную и логичную альтернативу более ранним, зачастую запутанным, иерархическим и сетевым моделям. Разве не удивительно, как математическая абстракция может так эффективно преобразовывать мир реальных данных?
История и эволюция реляционной модели данных
История реляционной модели данных тесно связана с именем Эдгара Ф. Кодда, выдающегося британского ученого-компьютерщика, работавшего в IBM. В 1970 году Кодд опубликовал знаковую статью «A Relational Model of Data for Large Shared Data Banks», в которой предложил новый подход к организации данных. До этого момента доминировали иерархические и сетевые модели, которые, несмотря на свою функциональность, часто страдали от жесткой структуры и сложности в управлении связями между данными.
Кодд, вдохновленный математической теорией множеств и логикой первого порядка, предложил представлять данные в виде двумерных таблиц, которые он назвал «отношениями». Эта идея, казавшаяся на первый взгляд простой, кардинально изменила ландшафт баз данных. Она позволила:
- Упростить структуру данных: Отказаться от сложных указателей и переходов, характерных для иерархических и сетевых моделей.
- Повысить гибкость: Изменять структуру данных без необходимости переписывать все приложения, работающие с базой.
- Улучшить запросы: Разработать мощные декларативные языки запросов, которые позволяли пользователям описывать, что они хотят получить, а не как это получить.
Работа Кодда не сразу получила широкое признание, но вскоре ее преимущества стали очевидны. К концу 1970-х и началу 1980-х годов начали появляться первые коммерческие реляционные СУБД, такие как System R (разработка IBM) и Ingres (разработка Калифорнийского университета в Беркли). Эти системы стали прототипами для современных гигантов, таких как Oracle, MySQL, PostgreSQL и Microsoft SQL Server. С тех пор реляционная модель данных остается доминирующей парадигмой в области баз данных, постоянно развиваясь и адаптируясь к новым вызовам.
Базовые понятия реляционной модели
Для понимания реляционной модели необходимо освоить ее основные термины, которые формируют фундамент для всей дальнейшей работы с базами данных.
- База данных (БД): Это не просто набор файлов, а структурированная информация, хранящаяся в связанных электронных таблицах. База данных — это организованная коллекция данных, которая позволяет эффективно хранить, извлекать и управлять информацией.
- Система управления базами данных (СУБД): Программное обеспечение, которое выступает в роли посредника между пользователем (или приложением) и базой данных. СУБД обеспечивает доступ, безопасность, целостность и согласованность данных. Примеры включают MySQL, PostgreSQL, Oracle, SQL Server.
- Отношение (Таблица): В реляционной модели все данные представлены в виде двумерных таблиц. Каждая таблица состоит из строк и столбцов. Например, таблица «Деревья» может содержать информацию о каждом дереве в саду.
- Кортеж (Строка): Это отдельная запись в таблице, представляющая собой единичное вхождение или запись об объекте реального мира. В таблице «Деревья» каждый кортеж будет описывать одно конкретное дерево.
- Атрибут (Столбец): Это столбец в таблице, который хранит определенный тип данных и описывает смысл и назначение элементов данных в соответствующих ячейках. Например, в таблице «Деревья» атрибутами могут быть «ИДДерева», «ДатаПосадки», «Квартал».
- Домен: Это совокупность всех допустимых значений для конкретного атрибута. Например, для атрибута «ДатаПосадки» домен будет включать все возможные календарные даты, а для атрибута «КоличествоКг» в таблице «Урожай» домен может быть множеством неотрицательных чисел. Домены обеспечивают целостность данных, ограничивая их возможные значения.
Эти базовые понятия формируют каркас, на котором строится вся логика реляционной базы данных, обеспечивая ее строгость и предсказуемость.
Ключи и связи в реляционных базах данных
Ключи и связи являются механизмом, который придает реляционной модели ее силу, позволяя эффективно структурировать данные и устанавливать между ними логические взаимоотношения. Без них таблицы были бы изолированными наборами информации.
- Первичный ключ (Primary Key): Это один или несколько атрибутов (столбцов) в таблице, которые однозначно идентифицируют каждую запись (кортеж) в этой таблице.
- Пример: В таблице
ДЕРЕВЬЯатрибутИД_Деревабудет первичным ключом, гарантируя, что каждое дерево имеет уникальный идентификатор. - Свойства:
- Уникальность: Значение первичного ключа должно быть уникальным для каждой строки.
- Неизменность (как правило): Желательно, чтобы значение первичного ключа не менялось со временем.
- Не-NULL: Первичный ключ не может содержать NULL-значения, так как он должен однозначно идентифицировать запись. Это свойство называется целостностью сущностей.
- Пример: В таблице
- Внешний ключ (Foreign Key): Это атрибут или набор атрибутов в одной таблице, который ссылается на первичный ключ другой таблицы. Внешние ключи создают логические связи между таблицами, позволяя объединять данные из разных источников.
- Пример: В таблице
УРОЖАЙатрибутИД_Дереваявляется внешним ключом, ссылающимся на первичный ключИД_Деревав таблицеДЕРЕВЬЯ. Это позволяет определить, с какого дерева был собран конкретный урожай. - Свойства:
- Ссылочная целостность: Значение внешнего ключа должно либо соответствовать значению первичного ключа в родительской таблице, на которую он ссылается, либо быть NULL (если это разрешено). Это предотвращает появление «висячих» ссылок, когда запись ссылается на несуществующий объект.
- Пример: В таблице
- Типы связей между таблицами:
- Один-к-одному (1:1): Каждая запись в одной таблице связана ровно с одной записью в другой таблице, и наоборот.
- Пример: Если каждое дерево имеет уникальный паспорт с детальной информацией, то таблица
ДЕРЕВЬЯи таблицаПАСПОРТА_ДЕРЕВЬЕВмогут быть связаны как 1:1, гдеИД_ДеревавПАСПОРТА_ДЕРЕВЬЕВбудет внешним ключом, ссылающимся наДЕРЕВЬЯ.
- Пример: Если каждое дерево имеет уникальный паспорт с детальной информацией, то таблица
- Один-ко-многим (1:М): Каждая запись в первой таблице может быть связана с несколькими записями во второй таблице, но каждая запись во второй таблице связана только с одной записью в первой.
- Пример: Один
СОРТфруктов (ИД_Сорта) может быть у многихДЕРЕВЬЕВ(ИД_СортавДЕРЕВЬЯ– внешний ключ кСОРТА).
- Пример: Один
- Многие-ко-многим (М:М): Каждая запись в первой таблице может быть связана с несколькими записями во второй таблице, и каждая запись во второй таблице также может быть связана с несколькими записями в первой.
- Пример: Одно
ДЕРЕВОможет болеть несколькимиБОЛЕЗНЯМИ, и однаБОЛЕЗНЬможет поражать несколькоДЕРЕВЬЕВ. Для реализации такой связи создается промежуточная таблица (ДЕРЕВЬЯ_БОЛЕЗНИ), содержащая внешние ключи обеих связанных таблиц (ИД_Дерева,ИД_Болезни).
- Пример: Одно
- Один-к-одному (1:1): Каждая запись в одной таблице связана ровно с одной записью в другой таблице, и наоборот.
Понимание этих концепций критически важно для построения эффективной, логичной и согласованной базы данных.
Проектирование Базы Данных «Фруктовый Сад»
Проектирование базы данных — это искусство и наука одновременно, требующие глубокого понимания предметной области и принципов организации данных. Это не просто создание таблиц, а разработка оптимальной структуры, способной эффективно хранить, извлекать и управлять информацией. Для системы «Фруктовый сад» этот процесс особенно важен, так как он закладывает основу для всего дальнейшего учета и анализа.
Этапы проектирования баз данных
Процесс проектирования баз данных традиционно делится на три основных этапа, каждый из которых имеет свои цели и инструментарий:
- Концептуальное (инфологическое) проектирование:
- Цель: Построение высокоуровневой, независимой от конкретной СУБД и модели данных, семантической модели предметной области. На этом этапе фокус делается на понимании информационных потребностей пользователей, выявлении ключевых сущностей и связей между ними.
- Инструментарий: Часто используются графические нотации, такие как ER-диаграммы (Entity-Relationship Diagram), которые описывают информационные объекты (сущности), их атрибуты и взаимосвязи. Результатом является ER-модель, которая представляет собой абстрактное, но полное описание информационной структуры предметной области.
- Пример для «Фруктового сада»: Определяем, что есть «Деревья», «Кварталы», «Сорта» и как они взаимодействуют.
- Логическое (даталогическое) проектирование:
- Цель: Преобразование концептуальной модели в схему, соответствующую выбранной модели данных (в нашем случае — реляционной), но еще без привязки к конкретной СУБД. На этом этапе ER-диаграмма трансформируется в набор реляционных таблиц, определяются первичные и внешние ключи, а также выполняется нормализация.
- Инструментарий: Схемы отношений, таблицы с указанием атрибутов, ключей и типов данных. Важным аспектом является применение правил нормализации.
- Пример для «Фруктового сада»: ER-диаграмма «Деревья» становится таблицей
ДЕРЕВЬЯс атрибутамиИД_Дерева,Дата_Посадки,ИД_Квартала,ИД_Сортаи т.д.
- Физическое проектирование:
- Цель: Создание схемы базы данных для конкретной СУБД, оптимизированной для производительности и эффективного использования ресурсов. На этом этапе принимаются решения о выборе типов данных, создании индексов, размещении данных на дисках, партиционировании таблиц и других специфичных для СУБД параметрах.
- Инструментарий: DDL-скрипты для создания таблиц, индексов, представлений; настройки СУБД; планы выполнения запросов.
- Пример для «Фруктового сада»: Выбираем PostgreSQL, определяем, что
ИД_Деревабудет иметь типSERIAL(автоинкрементное целое), создаем индексы наИД_Сортадля ускорения запросов по сортам.
Эти этапы обеспечивают системный подход к проектированию, позволяя последовательно детализировать модель данных от высокоуровневого представления до конкретной реализации, минимизируя риски и ошибки.
Концептуальное проектирование: Модель «Сущность-Связь» (ER-диаграмма)
Концептуальное проектирование является первым и, пожалуй, одним из наиболее важных этапов, поскольку на нем формируется высокоуровневое представление о предметной области. Модель «Сущность-Связь» (ER-диаграмма) — это мощный графический инструмент для визуализации этих представлений. Для системы учета «Фруктовый сад» мы выделим следующие ключевые сущности и их атрибуты:
- СУЩНОСТЬ: Кварталы (Участки сада)
- Атрибуты:
ИД_Квартала(первичный ключ, уникальный идентификатор квартала)Название_Квартала(например, «Северный», «Южный»)Площадь(в гектарах или квадратных метрах)
- Атрибуты:
- СУЩНОСТЬ: Сорта (Фруктов)
- Атрибуты:
ИД_Сорта(первичный ключ, уникальный идентификатор сорта)Название_Сорта(например, «Антоновка», «Гала»)Описание(дополнительная информация о сорте)Период_Созревания(например, «Ранний», «Средний», «Поздний»)
- Атрибуты:
- СУЩНОСТЬ: Деревья
- Атрибуты:
ИД_Дерева(первичный ключ, уникальный идентификатор дерева)Дата_ПосадкиСостояние_Здоровья(например, «Здорово», «Болеет», «Требует внимания»)ИД_Квартала(внешний ключ, ссылка наКварталы)ИД_Сорта(внешний ключ, ссылка наСорта)
- Атрибуты:
- СУЩНОСТЬ: Урожай
- Атрибуты:
ИД_Урожая(первичный ключ, уникальный идентификатор записи об урожае)Дата_СбораКоличество_КгКачество(например, «Премиум», «Первый сорт», «Технический»)ИД_Дерева(внешний ключ, ссылка наДеревья)
- Атрибуты:
- СУЩНОСТЬ: Склад
- Атрибуты:
ИД_Склада(первичный ключ, уникальный идентификатор склада)Название_СкладаАдрес
- Атрибуты:
- СУЩНОСТЬ: Партии_Хранения
- Атрибуты:
ИД_Партии(первичный ключ, уникальный идентификатор партии хранения)Дата_ПоступленияКоличество_Кг_ХранениеИД_Урожая(внешний ключ, ссылка наУрожай)ИД_Склада(внешний ключ, ссылка наСклад)
- Атрибуты:
- СУЩНОСТЬ: Покупатели
- Атрибуты:
ИД_Покупателя(первичный ключ, уникальный идентификатор покупателя)ИмяКонтактный_ТелефонАдрес
- Атрибуты:
- СУЩНОСТЬ: Продажи
- Атрибуты:
ИД_Продажи(первичный ключ, уникальный идентификатор продажи)Дата_ПродажиКоличество_Кг_ПроданоЦена_За_КгИД_Покупателя(внешний ключ, ссылка наПокупатели)ИД_Партии(внешний ключ, ссылка наПартии_Хранения)
- Атрибуты:
ER-диаграмма (текстовое представление):
+------------+ +----------+ +----------+ +-----------+
| КВАРТАЛЫ |<-------| ДЕРЕВЬЯ |------->| СОРТА | | ПОКУПАТЕЛИ|
+------------+ +----------+ +----------+ +-----------+
- ИД_Квартала (PK) - ИД_Дерева (PK) - ИД_Сорта (PK) - ИД_Покупателя (PK)
- Название_Квартала - Дата_Посадки - Название_Сорта - Имя
- Площадь - Состояние_Здоровья - Описание - Контактный_Телефон
- ИД_Квартала (FK) - Период_Созревания - Адрес
- ИД_Сорта (FK)
|
v
+---------+
| УРОЖАЙ |
+---------+
- ИД_Урожая (PK)
- Дата_Сбора
- Количество_Кг
- Качество
- ИД_Дерева (FK)
|
v
+------------------+ +----------+
| ПАРТИИ_ХРАНЕНИЯ |------->| СКЛАД |
+------------------+ +----------+
- ИД_Партии (PK) - ИД_Склада (PK)
- Дата_Поступле��ия - Название_Склада
- Количество_Кг_Хранение - Адрес
- ИД_Урожая (FK)
- ИД_Склада (FK)
|
v
+----------+
| ПРОДАЖИ |
+----------+
- ИД_Продажи (PK)
- Дата_Продажи
- Количество_Кг_Продано
- Цена_За_Кг
- ИД_Покупателя (FK)
- ИД_Партии (FK)
Описание связей:
- КВАРТАЛЫ (1) — (М) ДЕРЕВЬЯ: Один квартал может содержать много деревьев, но каждое дерево относится только к одному кварталу.
- СОРТА (1) — (М) ДЕРЕВЬЯ: Один сорт фруктов может быть у многих деревьев, но каждое дерево относится только к одному сорту.
- ДЕРЕВЬЯ (1) — (М) УРОЖАЙ: Одно дерево может давать много урожаев за свою жизнь, но каждый конкретный урожай собран с одного дерева.
- УРОЖАЙ (1) — (М) ПАРТИИ_ХРАНЕНИЯ: Одна запись об урожае может быть разделена на несколько партий для хранения (например, часть на одном складе, часть на другом, или в разное время), но каждая партия хранения относится к одному конкретному урожаю.
- СКЛАД (1) — (М) ПАРТИИ_ХРАНЕНИЯ: Один склад может хранить много партий, но каждая партия хранится на одном конкретном складе.
- ПАРТИИ_ХРАНЕНИЯ (1) — (М) ПРОДАЖИ: Одна партия хранения может быть продана в рамках нескольких сделок (покупателям), но каждая продажа относится к одной конкретной партии.
- ПОКУПАТЕЛИ (1) — (М) ПРОДАЖИ: Один покупатель может совершить много покупок, но каждая продажа совершена одним конкретным покупателем.
Логическое проектирование: Схема отношений
На этапе логического проектирования мы переводим концептуальную ER-диаграмму в конкретную схему реляционных таблиц, определяя все атрибуты, их типы данных, первичные и внешние ключи. Это формирует основу для дальнейшей реализации в СУБД.
Схема реляционных таблиц для системы «Фруктовый сад»:
- Таблица: Кварталы
ИД_КварталаINT PRIMARY KEY (Уникальный идентификатор квартала)Название_КварталаVARCHAR(100) NOT NULL (Название квартала, например, «Северный»)ПлощадьDECIMAL(10, 2) NOT NULL (Площадь квартала в га или м²)
- Таблица: Сорта
ИД_СортаINT PRIMARY KEY (Уникальный идентификатор сорта)Название_СортаVARCHAR(100) NOT NULL (Название сорта, например, «Антоновка»)ОписаниеTEXT (Описание сорта)Период_СозреванияVARCHAR(50) (Например, «Ранний», «Средний», «Поздний»)
- Таблица: Деревья
ИД_ДереваINT PRIMARY KEY (Уникальный идентификатор дерева)Дата_ПосадкиDATE NOT NULLСостояние_ЗдоровьяVARCHAR(50) DEFAULT ‘Здорово’ (Состояние здоровья дерева)ИД_КварталаINT NOT NULL, FOREIGN KEY (ИД_Квартала) REFERENCESКварталы(ИД_Квартала)ИД_СортаINT NOT NULL, FOREIGN KEY (ИД_Сорта) REFERENCESСорта(ИД_Сорта)
- Таблица: Урожай
ИД_УрожаяINT PRIMARY KEY (Уникальный идентификатор записи об урожае)Дата_СбораDATE NOT NULLКоличество_КгDECIMAL(10, 2) NOT NULLКачествоVARCHAR(50) (Например, «Премиум», «Первый сорт»)ИД_ДереваINT NOT NULL, FOREIGN KEY (ИД_Дерева) REFERENCESДеревья(ИД_Дерева)
- Таблица: Склад
ИД_СкладаINT PRIMARY KEY (Уникальный идентификатор склада)Название_СкладаVARCHAR(100) NOT NULLАдресVARCHAR(255)
- Таблица: Партии_Хранения
ИД_ПартииINT PRIMARY KEY (Уникальный идентификатор партии хранения)Дата_ПоступленияDATE NOT NULLКоличество_Кг_ХранениеDECIMAL(10, 2) NOT NULLИД_УрожаяINT NOT NULL, FOREIGN KEY (ИД_Урожая) REFERENCESУрожай(ИД_Урожая)ИД_СкладаINT NOT NULL, FOREIGN KEY (ИД_Склада) REFERENCESСклад(ИД_Склада)
- Таблица: Покупатели
ИД_ПокупателяINT PRIMARY KEY (Уникальный идентификатор покупателя)ИмяVARCHAR(100) NOT NULLКонтактный_ТелефонVARCHAR(20)АдресVARCHAR(255)
- Таблица: Продажи
ИД_ПродажиINT PRIMARY KEY (Уникальный идентификатор продажи)Дата_ПродажиDATE NOT NULLКоличество_Кг_ПроданоDECIMAL(10, 2) NOT NULLЦена_За_КгDECIMAL(10, 2) NOT NULLИД_ПокупателяINT NOT NULL, FOREIGN KEY (ИД_Покупателя) REFERENCESПокупатели(ИД_Покупателя)ИД_ПартииINT NOT NULL, FOREIGN KEY (ИД_Партии) REFERENCESПартии_Хранения(ИД_Партии)
Эта логическая схема отношений служит прямым руководством для создания физической базы данных в любой реляционной СУБД.
Нормализация базы данных до 3НФ
Нормализация — это краеугольный камень в проектировании реляционных баз данных, процесс, направленный на создание оптимальной структуры таблиц. Его основная цель — минимизировать избыточность данных и предотвратить аномалии, которые могут возникнуть при вставке, обновлении или удалении информации. Теория нормализации оперирует множеством нормальных форм, но на практике чаще всего достаточно достичь Третьей нормальной формы (3НФ) для большинства предметных областей.
Рассмотрим основные нормальные формы и их применение к нашей базе данных «Фруктовый сад».
1. Первая нормальная форма (1НФ)
Отношение находится в 1НФ, если:
- Каждый атрибут (столбец) является атомарным (неделимым). Это означает, что каждая ячейка таблицы должна содержать одно, неделимое значение.
- Нет повторяющихся групп столбцов.
- Каждая строка уникальна.
Пример нарушения 1НФ:
Представьте, что у нас есть таблица ДЕРЕВЬЯ_И_СОРТА, где в одном столбце Сорта_Фруктов хранится список сортов, даваемых деревом (например, «Антоновка, Мельба»).
| ИДДерева | Квартал | СортаФруктов |
|---|---|---|
| 1 | Север | Антоновка, Мельба |
| 2 | Юг | Гала |
Приведение к 1НФ:
Чтобы устранить это нарушение, мы выносим информацию о сортах в отдельную таблицу СОРТА и связываем ДЕРЕВЬЯ с СОРТА через внешний ключ (как мы уже сделали в нашей ER-модели). Атрибут ИД_Сорта в ДЕРЕВЬЯХ будет хранить только один, атомарный идентификатор сорта.
2. Вторая нормальная форма (2НФ)
Отношение находится во 2НФ, если оно находится в 1НФ, и каждый неключевой атрибут полностью функционально зависит от всего первичного ключа. Это важно, когда первичный ключ является составным (состоит из нескольких атрибутов). Отсутствие частичных зависимостей означает, что ни один неключевой атрибут не должен зависеть только от части составного первичного ключа.
Пример нарушения 2НФ:
Предположим, у нас была бы таблица ДЕТАЛИ_УРОЖАЯ со составным первичным ключом (ИД_Урожая, ИД_Дерева). И в этой же таблице хранилась бы Дата_Посадки дерева.
| ИДУрожая | ИДДерева | ДатаСбора | КоличествоКг | ДатаПосадки |
|---|---|---|---|---|
| 101 | 1 | 2024-08-15 | 50 | 2010-03-20 |
| 102 | 1 | 2025-08-20 | 60 | 2010-03-20 |
Здесь Дата_Посадки зависит только от ИД_Дерева (части первичного ключа), а не от всего ключа (ИД_Урожая, ИД_Дерева). Это частичная зависимость.
Приведение к 2НФ:
Чтобы устранить это нарушение, мы выносим Дата_Посадки в отдельную таблицу ДЕРЕВЬЯ, где ИД_Дерева является первичным ключом. В нашей модели это уже сделано: Дата_Посадки находится в таблице ДЕРЕВЬЯ.
3. Третья нормальная форма (3НФ)
Отношение находится в 3НФ, если оно находится во 2НФ, и отсутствуют транзитивные функциональные зависимости неключевых атрибутов от ключевых. Транзитивная зависимость означает, что неключевой атрибут зависит от другого неключевого атрибута, который, в свою очередь, зависит от первичного ключа. Проще говоря, никакие неключевые атрибуты не должны зависеть от других неключевых атрибутов.
Пример нарушения 3НФ:
Предположим, в таблице УРОЖАЙ у нас, помимо ИД_Урожая, Количество_Кг и ИД_Дерева, также хранилась бы Название_Сорта и Описание_Сорта.
| ИДУрожая | ИДДерева | ДатаСбора | КоличествоКг | ИДСорта | НазваниеСорта | ОписаниеСорта |
|---|---|---|---|---|---|---|
| 101 | 1 | 2024-08-15 | 50 | 1 | Антоновка | Кисло-сладкий |
| 102 | 2 | 2024-08-20 | 60 | 2 | Гала | Сладкий |
Здесь Название_Сорта и Описание_Сорта зависят от ИД_Сорта, который, в свою очередь, является внешним ключом и зависит от первичного ключа ИД_Урожая через ИД_Дерева (или напрямую, если ИД_Сорта был бы атрибутом УРОЖАЯ). Это транзитивная зависимость. Если мы изменим описание сорта «Антоновка», нам придется обновлять все записи в таблице УРОЖАЙ, где есть этот сорт.
Приведение к 3НФ:
Чтобы устранить это нарушение, мы выносим информацию о сортах (ИД_Сорта, Название_Сорта, Описание_Сорта) в отдельную таблицу СОРТА, а в таблице УРОЖАЙ оставляем только внешний ключ ИД_Сорта (или, как в нашей модели, связываем УРОЖАЙ с ДЕРЕВЬЯМИ, а ДЕРЕВЬЯ с СОРТАМИ). В нашей схеме это уже реализовано. Урожай имеет внешний ключ ИД_Дерева, а Деревья имеют внешний ключ ИД_Сорта, что полностью соответствует 3НФ.
Пример применения нормализации к таблицам «Фруктовый сад»:
Рассмотрим таблицу ДЕРЕВЬЯ из нашего проекта:
| ИДДерева (PK) | ДатаПосадки | СостояниеЗдоровья | ИДКвартала (FK) | ИДСорта (FK) |
|---|---|---|---|---|
| 1 | 2010-03-15 | Здорово | 10 | 101 |
| 2 | 2012-04-20 | Болеет | 10 | 102 |
| 3 | 2011-05-01 | Здорово | 11 | 101 |
- 1НФ: Все атрибуты атомарны, нет повторяющихся групп, каждая строка уникальна благодаря
ИД_Дерева. - 2НФ: Первичный ключ
ИД_Дереваявляется простым (не составным), поэтому все неключевые атрибуты (Дата_Посадки,Состояние_Здоровья,ИД_Квартала,ИД_Сорта) полностью зависят от него. - 3НФ: Нет транзитивных зависимостей.
Состояние_Здоровьяне зависит отИД_КварталаилиИД_Сорта. Все неключевые атрибуты зависят только от первичного ключа.
Таким образом, все таблицы в нашей схеме, разработанной на этапе логического проектирования, спроектированы с учетом достижения 3НФ, что обеспечивает их оптимальную структуру, минимизацию избыточности и защиту от большинства аномалий.
Углубленная Нормализация: BCNF, 4НФ и 5НФ
Хотя 3НФ является достаточной для большинства практических сценариев, существуют более строгие нормальные формы, которые позволяют устранить оставшиеся типы зависимостей и аномалий, встречающиеся в сложных моделях данных. Игнорирование этих форм может привести к тонким, но потенциально дорогостоящим проблемам с целостностью данных в долгосрочной перспективе. И действительно, можно ли считать систему надежной, если она не учитывает все возможные источники несогласованности?
Нормальная форма Бойса-Кодда (BCNF)
Нормальная форма Бойса-Кодда (Boyce-Codd Normal Form, BCNF) была предложена Эдгаром Коддом и Рэймондом Бойсом в 1974 году как более строгая версия 3НФ. Отношение находится в BCNF тогда и только тогда, когда каждая нетривиальная функциональная зависимость в нем обладает суперключом в качестве детерминанта. Суперключ — это любой атрибут или набор атрибутов, который однозначно идентифицирует кортеж. Первичный ключ является минимальным суперключом.
Отличие BCNF от 3НФ:
3НФ допускает транзитивные зависимости, если они не являются зависимостями неключевых атрибутов от других неключевых атрибутов. BCNF же требует, чтобы все детерминанты (левые части функциональных зависимостей) были суперключами. Это означает, что в BCNF устраняются зависимости между атрибутами, не являющимися частью первичного ключа, даже если эти зависимости не транзитивны в традиционном понимании 3НФ.
Когда 3НФ не гарантирует отсутствие аномалий, а BCNF их устраняет:
Это происходит в случаях, когда:
- Таблица имеет два или более составных потенциальных ключа (ключей-кандидатов), которые перекрываются.
- В таблице есть неключевой атрибут, который является детерминантом для части потенциального ключа.
Пример (гипотетический, не из «Фруктового сада» для ясности):
Рассмотрим таблицу ПРЕПОДАВАТЕЛЬ_КУРС_ПОМОЩНИК, которая хранит, какой преподаватель ведет какой курс, и какие помощники назначены этому курсу.
| Преподаватель (PK) | Курс (PK) | Помощник |
|---|---|---|
| Иванов | БД | Петров |
| Иванов | БД | Сидоров |
| Сергеев | Сети | Петров |
Дополнительные ограничения:
- Каждый курс может быть назначен только одному преподавателю (Иванов ведет БД, Сергеев ведет Сети). Функциональная зависимость:
Курс → Преподаватель. - Преподаватель может преподавать несколько курсов, и на одном курсе может быть несколько помощников.
- Один и тот же помощник может помогать на разных курсах, но для одного курса один помощник всегда связан с одним преподавателем.
В этой таблице (Преподаватель, Курс) является первичным ключом.
- Таблица находится в 1НФ и 2НФ.
- Для 3НФ нам нужно проверить транзитивные зависимости.
Помощникне зависит транзитивно от (Преподаватель,Курс). - Однако, есть функциональная зависимость
Курс → Преподаватель.Курсне является суперключом этой таблицы. Следовательно, таблица не находится в BCNF.
Аномалии в 3НФ, которые устраняет BCNF:
- Аномалия обновления: Если преподаватель Иванов перестает вести курс «БД» и его заменяет другой преподаватель, нам придется обновить несколько записей, что чревато несогласованностью.
- Аномалия вставки: Мы не можем добавить информацию о новом курсе и его преподавателе, если у этого курса пока нет помощника.
- Аномалия удаления: Если мы удаляем запись о последнем помощнике курса «БД», мы теряем информацию о том, кто преподает этот курс.
Приведение к BCNF:
Разделяем таблицу на две:
ПРЕПОДАВАТЕЛИ_КУРСОВ: (Курс(PK),Преподаватель(FK))КУРС_ПОМОЩНИК: (Курс(PK),Помощник(PK))
В ПРЕПОДАВАТЕЛИ_КУРСОВ детерминант Курс является суперключом для этой таблицы.
В КУРС_ПОМОЩНИК детерминант Курс является частью составного суперключа (Курс, Помощник).
Этот пример демонстрирует, как BCNF устраняет зависимости, которые 3НФ может пропустить, обеспечивая более высокую степень нормализации и предотвращая аномалии.
Четвертая нормальная форма (4НФ)
Четвертая нормальная форма (4НФ) фокусируется на устранении многозначных зависимостей. Отношение находится в 4НФ, если оно находится в BCNF и не содержит нетривиальных многозначных зависимостей. Многозначная зависимость A →→ B (читается как «A многозначно определяет B») существует, если для каждого значения атрибута A существует определенное множество значений атрибута B, не зависящее от значений других атрибутов.
Примеры, иллюстрирующие, как 4НФ борется с аномалиями, связанными с зависимостью одного неключевого атрибута от нескольких других неключевых атрибутов:
Представьте, что в нашем «Фруктовом саду» мы хотим хранить информацию о том, какие сорта фруктов могут выращиваться в каком квартале, и какие болезни могут поражать деревья в этом квартале. Если мы попытаемся хранить это в одной таблице:
| ИДКвартала (PK) | НазваниеКвартала | ДопустимыйСорт | РаспространеннаяБолезнь |
|---|---|---|---|
| 10 | Северный | Антоновка | Парша |
| 10 | Северный | Мельба | Парша |
| 10 | Северный | Антоновка | Мучнистая_роса |
| 10 | Северный | Мельба | Мучнистая_роса |
В этой таблице есть многозначные зависимости:
ИД_Квартала→→Допустимый_Сорт(один квартал может иметь много допустимых сортов)ИД_Квартала→→Распространенная_Болезнь(в одном квартале может быть много распространенных болезней)
Однако Допустимый_Сорт и Распространенная_Болезнь независимы друг от друга. То есть знание Допустимого_Сорта не помогает определить Распространенную_Болезнь, и наоборот.
Эта таблица находится в 3НФ и BCNF (если (ИД_Квартала, Допустимый_Сорт, Распространенная_Болезнь) — первичный ключ, то нет детерминантов, которые не я��ляются суперключами). Тем не менее, она содержит избыточность и аномалии:
- Аномалия обновления: Если мы хотим изменить название квартала «Северный», нам придется обновить несколько строк.
- Аномалия вставки: Мы не можем добавить новую болезнь для квартала, не зная хотя бы одного допустимого сорта, или добавить новый сорт, не зная болезни.
- Аномалия удаления: Если мы удалим все записи о
Паршев «Северном» квартале, мы можем потерять информацию оМельбекак допустимом сорте, если это была последняя запись, гдеМельбафигурировала.
Приведение к 4НФ:
Для приведения к 4НФ необходимо разбить таблицу на отдельные отношения, каждое из которых будет содержать только одну многозначную зависимость:
КВАРТАЛЫ_ДОПУСТИМЫЕ_СОРТА:
ИДКвартала (PK) ДопустимыйСорт (PK) 10 Антоновка 10 Мельба КВАРТАЛЫ_РАСПРОСТРАНЕННЫЕ_БОЛЕЗНИ:
ИДКвартала (PK) РаспространеннаяБолезнь (PK) 10 Парша 10 Мучнистая_роса
Разделение устраняет избыточность и аномалии, связанные с многозначными зависимостями, делая базу данных более чистой и управляемой.
Пятая нормальная форма (5НФ)
Пятая нормальная форма (5НФ), также известная как проекционно-соединительная нормальная форма (PJNF), является самой строгой из нормальных форм, которая занимается устранением зависимостей соединения. Отношение находится в 5НФ тогда и только тогда, когда каждая нетривиальная зависимость соединения в нем определяется потенциальным ключом (ключами) этого отношения. Это означает, что отношение не может быть подвергнуто дальнейшей декомпозиции без потерь информации, то есть оно не может быть восстановлено путем соединения его проекций без добавления «ложных» кортежей (spurious tuples).
Когда 5НФ необходима для декомпозиции без потерь информации:
5НФ требуется в тех редких случаях, когда таблица содержит зависимость соединения, которая не является следствием функциональных или многозначных зависимостей. Такие ситуации обычно возникают, когда существуют сложные, взаимосвязанные ограничения на комбинации значений, но эти ограничения не могут быть выражены через простые функциональные или многозначные зависимости.
Пример (гипотетический, для демонстрации принципа):
Представьте, что у нас есть база данных для учета командных проектов. Таблица ПРОЕКТ_УЧАСТНИК_НАВЫК хранит информацию о том, кто (Участник) обладает каким Навыком для выполнения какого Проекта.
| Проект (PK) | Участник (PK) | Навык (PK) |
|---|---|---|
| А | Иван | SQL |
| А | Петр | Python |
| Б | Иван | Python |
| Б | Петр | SQL |
Дополнительное ограничение (зависимость соединения):
- Если Участник X работает над Проектом Y, и Участник X обладает Навыком Z, и Навык Z требуется для Проекта Y, то (Проект Y, Участник X, Навык Z) является допустимой комбинацией.
- Если (Проект, Участник) существует, и (Участник, Навык) существует, и (Проект, Навык) существует, то (Проект, Участник, Навык) должен существовать.
В данном случае, таблица ПРОЕКТ_УЧАСТНИК_НАВЫК может быть декомпозирована без потерь на три таблицы:
ПРОЕКТ_УЧАСТНИК: (Проект(PK),Участник(PK))УЧАСТНИК_НАВЫК: (Участник(PK),Навык(PK))ПРОЕКТ_НАВЫК: (Проект(PK),Навык(PK))
Если мы попытаемся восстановить исходную таблицу, соединив эти три таблицы, мы получим ровно исходные данные без добавления «ложных» кортежей. Это означает, что исходная таблица ПРОЕКТ_УЧАСТНИК_НАВЫК не была в 5НФ, поскольку ее можно было декомпозировать на три отношения, а потом собрать обратно без потерь.
Применение 5НФ является крайне редким на практике, поскольку такие зависимости соединения встречаются в очень специфических и сложных предметных областях. Большинство бизнес-приложений обходятся 3НФ или BCNF. Однако знание о 5НФ важно для полного понимания теории нормализации и для решения проблем в особо запутанных случаях.
Основы языка SQL для манипуляции данными системы «Фруктовый сад»
SQL (Structured Query Language) — это сердце и душа любой реляционной базы данных. Без него базы данных были бы просто статичными хранилищами информации. SQL позволяет не только определять структуру данных, но и эффективно манипулировать ими, извлекая нужную информацию, добавляя новые записи, обновляя существующие и удаляя устаревшие.
Обзор языка SQL и его стандарты
SQL — это декларативный язык, специально разработанный для работы с реляционными базами данных. Его ключевое преимущество заключается в том, что он позволяет пользователю описать, что он хочет получить или изменить, а не как это должно быть сделано. СУБД самостоятельно оптимизирует и выполняет эти операции.
История и стандартизация:
SQL был разработан в IBM в начале 1970-х годов под названием SEQUEL (Structured English Query Language), а затем переименован в SQL. Его первые коммерческие реализации появились в конце 1970-х.
Важным шагом в развитии SQL стала его стандартизация. Первый стандарт ANSI SQL был утвержден в 1986 году, а в 1987 году этот стандарт был одобрен ISO. Последующие версии, такие как SQL/89, SQL/92 (одна из наиболее значимых), SQL:1999, SQL:2003 и более поздние, постоянно расширяли возможности языка, добавляя новые функции и конструкции. Несмотря на наличие стандартов, каждая СУБД (MySQL, PostgreSQL, Oracle, SQL Server) имеет свои диалекты и расширения SQL, но основные команды и синтаксис остаются универсальными.
Типы команд SQL:
Команды SQL традиционно делятся на несколько категорий:
- DDL (Data Definition Language) — Язык определения данных: Используется для создания, изменения и удаления структур базы данных (таблиц, индексов, представлений). Основные операторы:
CREATE,ALTER,DROP. - DML (Data Manipulation Language) — Язык манипуляции данными: Используется для добавления, извлечения, обновления и удаления данных в таблицах. Основные операторы:
SELECT,INSERT,UPDATE,DELETE. - DCL (Data Control Language) — Язык управления данными: Используется для управления правами доступа пользователей к базе данных. Основные операторы:
GRANT,REVOKE. - TCL (Transaction Control Language) — Язык управления транзакциями: Используется для управления транзакциями (группами операций), обеспечивая их атомарность, согласованность, изоляцию и долговечность (ACID-свойства). Основные операторы:
BEGIN TRANSACTION,COMMIT,ROLLBACK.
В контексте нашей контрольной работы мы сосредоточимся на DDL и DML операторах.
DDL-операторы: Создание структуры базы данных
DDL-операторы позволяют нам создать физическую структуру нашей базы данных «Фруктовый сад» на основе разработанной логической схемы.
Примеры команд CREATE TABLE для создания таблиц:
- Таблица
Кварталы:CREATE TABLE Кварталы ( ИД_Квартала INT PRIMARY KEY, Название_Квартала VARCHAR(100) NOT NULL, Площадь DECIMAL(10, 2) NOT NULL ); - Таблица
Сорта:CREATE TABLE Сорта ( ИД_Сорта INT PRIMARY KEY, Название_Сорта VARCHAR(100) NOT NULL, Описание TEXT, Период_Созревания VARCHAR(50) ); - Таблица
Деревья:CREATE TABLE Деревья ( ИД_Дерева INT PRIMARY KEY, Дата_Посадки DATE NOT NULL, Состояние_Здоровья VARCHAR(50) DEFAULT 'Здорово', ИД_Квартала INT NOT NULL, ИД_Сорта INT NOT NULL, FOREIGN KEY (ИД_Квартала) REFERENCES Кварталы(ИД_Квартала), FOREIGN KEY (ИД_Сорта) REFERENCES Сорта(ИД_Сорта) ); - Таблица
Урожай:CREATE TABLE Урожай ( ИД_Урожая INT PRIMARY KEY, Дата_Сбора DATE NOT NULL, Количество_Кг DECIMAL(10, 2) NOT NULL, Качество VARCHAR(50), ИД_Дерева INT NOT NULL, FOREIGN KEY (ИД_Дерева) REFERENCES Деревья(ИД_Дерева) ); - Таблица
Склад:CREATE TABLE Склад ( ИД_Склада INT PRIMARY KEY, Название_Склада VARCHAR(100) NOT NULL, Адрес VARCHAR(255) ); - Таблица
Партии_Хранения:CREATE TABLE Партии_Хранения ( ИД_Партии INT PRIMARY KEY, Дата_Поступления DATE NOT NULL, Количество_Кг_Хранение DECIMAL(10, 2) NOT NULL, ИД_Урожая INT NOT NULL, ИД_Склада INT NOT NULL, FOREIGN KEY (ИД_Урожая) REFERENCES Урожай(ИД_Урожая), FOREIGN KEY (ИД_Склада) REFERENCES Склад(ИД_Склада) ); - Таблица
Покупатели:CREATE TABLE Покупатели ( ИД_Покупателя INT PRIMARY KEY, Имя VARCHAR(100) NOT NULL, Контактный_Телефон VARCHAR(20), Адрес VARCHAR(255) ); - Таблица
Продажи:CREATE TABLE Продажи ( ИД_Продажи INT PRIMARY KEY, Дата_Продажи DATE NOT NULL, Количество_Кг_Продано DECIMAL(10, 2) NOT NULL, Цена_За_Кг DECIMAL(10, 2) NOT NULL, ИД_Покупателя INT NOT NULL, ИД_Партии INT NOT NULL, FOREIGN KEY (ИД_Покупателя) REFERENCES Покупатели(ИД_Покупателя), FOREIGN KEY (ИД_Партии) REFERENCES Партии_Хранения(ИД_Партии) );
Эти DDL-команды создадут пустую структуру базы данных, готовую к наполнению данными.
DML-операторы: Вставка, обновление, удаление и выборка данных
Язык манипуляции данными (DML) позволяет взаимодействовать с данными внутри таблиц, выполняя основные операции: создание, чтение, обновление и удаление (CRUD).
1. INSERT — Добавление новых записей
Используется для добавления одной или нескольких строк в таблицу.
- Синтаксис:
INSERT INTO имя_таблицы (колонка1, колонка2, ...) VALUES (значение1, значение2, ...); - Пример 1: Добавление нового сорта фруктов:
INSERT INTO Сорта (ИД_Сорта, Название_Сорта, Описание, Период_Созревания) VALUES (101, 'Антоновка', 'Поздний сорт, кисло-сладкий вкус', 'Поздний'); - Пример 2: Добавление нового дерева:
INSERT INTO Деревья (ИД_Дерева, Дата_Посадки, Состояние_Здоровья, ИД_Квартала, ИД_Сорта) VALUES (1, '2020-03-10', 'Здорово', 1, 101); - Пример 3: Добавление записи об урожае:
INSERT INTO Урожай (ИД_Урожая, Дата_Сбора, Количество_Кг, Качество, ИД_Дерева) VALUES (1001, '2024-09-05', 75.5, 'Премиум', 1);
2. UPDATE — Изменение существующих записей
Используется для изменения значений в одной или нескольких строках таблицы. Важно использовать WHERE условие, иначе будут изменены все записи.
- Синтаксис:
UPDATE имя_таблицы SET колонка1=значение1, колонка2=значение2 WHERE условие; - Пример 1: Изменение состояния здоровья дерева:
UPDATE Деревья SET Состояние_Здоровья = 'Болеет' WHERE ИД_Дерева = 1; - Пример 2: Обновление количества фруктов на складе (гипотетически, если бы у Партии_Хранения был атрибут «текущее_количество»):
-- Предположим, что в таблице Партии_Хранения есть колонка Текущее_Количество_Кг_Хранение UPDATE Партии_Хранения SET Количество_Кг_Хранение = Количество_Кг_Хранение - 10 WHERE ИД_Партии = 201;
3. DELETE — Удаление записей
Используется для удаления одной или нескольких строк из таблицы. Крайне важно использовать WHERE условие, иначе будут удалены все записи из таблицы.
- Синтаксис:
DELETE FROM имя_таблицы WHERE условие; - Пример 1: Удаление записи о старом урожае:
DELETE FROM Урожай WHERE ИД_Урожая = 1001; - Пример 2: Удаление покупателя, который больше не сотрудничает:
DELETE FROM Покупатели WHERE ИД_Покупателя = 501;
4. SELECT — Выборка данных
Самый часто используемый DML-оператор, предназначенный для извлечения данных из базы данных.
- Синтаксис:
SELECT колонка1, колонка2 FROM таблица WHERE условие ORDER BY колонка LIMIT количество; - Пример: Выборка всех деревьев из определенного квартала:
SELECT ИД_Дерева, Дата_Посадки, Состояние_Здоровья FROM Деревья WHERE ИД_Квартала = 1;
Эти базовые операции составляют основу любого взаимодействия с данными в реляционной базе данных.
DML-операторы: Детальные запросы на выборку (SELECT)
Оператор SELECT является самым мощным инструментом SQL для извлечения информации. Его гибкость позволяет формировать сложные запросы, агрегировать данные и получать ценные аналитические отчеты.
1. Простая выборка всех данных из таблицы:
SELECT *
FROM Деревья;
Выведет все столбцы и все записи из таблицы Деревья.
2. Выборка определенных столбцов с условием WHERE:
SELECT Название_Сорта, Период_Созревания
FROM Сорта
WHERE Период_Созревания = 'Поздний';
Выведет названия и периоды созревания только для поздних сортов.
3. Агрегация данных с GROUP BY:
- Пример: Общий урожай по сорту:
SELECT S.Название_Сорта, SUM(U.Количество_Кг) AS Общий_Урожай_Кг FROM Сорта AS S JOIN Деревья AS D ON S.ИД_Сорта = D.ИД_Сорта JOIN Урожай AS U ON D.ИД_Дерева = U.ИД_Дерева GROUP BY S.Название_Сорта ORDER BY Общий_Урожай_Кг DESC;Этот запрос объединяет данные из таблиц
Сорта,ДеревьяиУрожай, группирует результаты по названию сорта и суммирует количество урожая, сортируя по убыванию. - Пример: Количество проданных фруктов за месяц:
SELECT SUM(P.Количество_Кг_Продано) AS Общее_Продано_Кг FROM Продажи AS P WHERE P.Дата_Продажи BETWEEN '2025-10-01' AND '2025-10-31';Подсчитывает общее количество проданных килограммов фруктов за октябрь 2025 года.
- Пример: Среднее количество урожая с дерева:
SELECT D.ИД_Дерева, S.Название_Сорта, AVG(U.Количество_Кг) AS Средний_Урожай_С_Дерева_Кг FROM Деревья AS D JOIN Сорта AS S ON D.ИД_Сорта = S.ИД_Сорта JOIN Урожай AS U ON D.ИД_Дерева = U.ИД_Дерева GROUP BY D.ИД_Дерева, S.Название_Сорта ORDER BY D.ИД_Дерева;Рассчитывает средний объем урожая для каждого дерева, с указанием сорта.
4. Использование JOIN для объединения данных из нескольких таблиц:
- Пример: Получить информацию о деревьях, их сортах и кварталах:
SELECT D.ИД_Дерева, D.Дата_Посадки, D.Состояние_Здоровья, S.Название_Сорта, K.Название_Квартала FROM Деревья AS D JOIN Сорта AS S ON D.ИД_Сорта = S.ИД_Сорта JOIN Кварталы AS K ON D.ИД_Квартала = K.ИД_Квартала WHERE D.Состояние_Здоровья = 'Здорово' ORDER BY K.Название_Квартала, S.Название_Сорта;Этот запрос объединяет три таблицы, чтобы показать комплексную информацию о каждом здоровом дереве.
5. Запросы с подзапросами или HAVING:
- Пример: Найти кварталы, где средний урожай с одного дерева превышает 100 кг:
SELECT K.Название_Квартала, AVG(U.Количество_Кг) AS Средний_Урожай_Кг_По_Кварталу FROM Кварталы AS K JOIN Деревья AS D ON K.ИД_Квартала = D.ИД_Квартала JOIN Урожай AS U ON D.ИД_Дерева = U.ИД_Дерева GROUP BY K.Название_Квартала HAVING AVG(U.Количество_Кг) > 100;Здесь
HAVINGиспользуется для фильтрации групп после агрегации.
Эти примеры демонстрируют широкий спектр возможностей SELECT для извлечения, агрегации и анализа данных, что критически важно для эффективного управления информацией в системе «Фруктовый сад».
Обеспечение Целостности Данных и Оптимизация Производительности
Две фундаментальные характеристики любой надежной системы управления базами данных — это целостность данных и производительность. Целостность гарантирует, что данные в базе являются точными, согласованными и надежными, в то время как оптимизация обеспечивает быстрый и эффективный доступ к этим данным.
Принципы целостности данных
Целостность данных — это не просто отсутствие ошибок, это свойство соответствия базы данных предметной области, а также обеспечение полноты и точности информации, отсутствие аномалий. В реляционной модели данных целостность достигается через ряд ограничений:
- Целостность сущностей:
- Принцип: Каждая запись (кортеж) в отношении должна быть уникально идентифицируема. Это означает, что любое отношение должно обладать первичным ключом, который:
- Уникален: Значение первичного ключа не может повторяться в пределах одной таблицы.
- Не-NULL: Первичный ключ не может содержать пустое (NULL) значение.
- Обеспечение: В нашей БД «Фруктовый сад» это обеспечивается путем определения PRIMARY KEY для каждого
ИДв таблицах (ИД_Дерева,ИД_Сорта,ИД_Урожаяи т.д.). Например,ИД_Дерева INT PRIMARY KEYгарантирует, что каждое дерево имеет уникальный и непустой идентификатор.
- Принцип: Каждая запись (кортеж) в отношении должна быть уникально идентифицируема. Это означает, что любое отношение должно обладать первичным ключом, который:
- Ссылочная целостность:
- Принцип: Для каждого значения внешнего ключа в дочерней таблице должно найтись соответствующее значение первичного ключа в родительской таблице, на которую он ссылается. Это предотвращает появление «висячих» ссылок, когда запись ссылается на несуществующий объект.
- Обеспечение: В нашей схеме это достигается с помощью объявления FOREIGN KEY. Например, в таблице
Деревьяесть FOREIGN KEY (ИД_Сорта) REFERENCESСорта(ИД_Сорта). Это означает, что нельзя добавить дерево сИД_Сорта, которого нет в таблицеСорта. СУБД будет проверять это ограничение при каждой попытке вставки или обновления. - Правила удаления/обновления: При нарушении ссылочной целостности (например, попытка удалить родительскую запись, на которую ссылаются дочерние), СУБД может применить одно из действий:
RESTRICT(по умолчанию): Запретить операцию.CASCADE: Каскадно удалить/обновить дочерние записи.SET NULL: Установить значение внешнего ключа в NULL.SET DEFAULT: Установить значение внешнего ключа в значение по умолчанию.
- Целостность домена:
- Принцип: Поддержание правильности данных внутри домена, что позволяет регулировать количество и типы значений в столбцах. Это означает, что значения атрибутов должны соответствовать определенным правилам и форматам.
- Обеспечение:
- Типы данных: Использование правильных типов данных (
INT,DATE,VARCHAR,DECIMAL). Например,Дата_Посадки DATEгарантирует, что в этом поле будут только корректные даты. - Ограничения
CHECK: Дополнительные правила для значений. Например, дляКоличество_Кгв таблицеУрожайможно добавитьCHECK (Количество_Кг > 0)для предотвращения ввода отрицательных значений. - Ограничения NOT NULL: Запрет на пустые значения, где это логически необходимо (например,
Название_Сорта VARCHAR(100) NOT NULL). - Значения по умолчанию DEFAULT: Установка значения по умолчанию, если оно не указано при вставке (например,
Состояние_Здоровья VARCHAR(50) DEFAULT 'Здорово').
- Типы данных: Использование правильных типов данных (
Применение этих принципов целостности данных создает надежную основу для системы «Фруктовый сад», гарантируя, что информация всегда будет точной и согласованной, несмотря на многократные операции чтения и записи.
Методы оптимизации производительности базы данных
Оптимизация базы данных — это непрерывный процесс, направленный на повышение скорости выполнения запросов, сокращение времени отклика и улучшение общей эффективности системы. Для системы «Фруктовый сад», где может быть большой объем данных об урожаях, деревьях и продажах, это критически важно. Но как можно достичь идеального баланса между скоростью и точностью?
- Индексирование:
- Суть: Индексы — это специальные структуры данных, которые улучшают скорость поиска и извлечения данных из таблицы. Они работают аналогично предметному указателю в книге, позволяя СУБД быстро находить нужные строки без полного сканирования таблицы.
- Применение для «Фруктового сада»:
- Создание индексов на внешних ключах (
ИД_Квартала,ИД_Сортав таблицеДеревья,ИД_Деревав таблицеУрожайи т.д.) для ускорения операций JOIN и запросов, использующих эти поля в WHERE условиях. - Индексы на часто используемых для фильтрации или сортировки полях, например,
Дата_СборавУрожайилиНазвание_СортавСорта.
- Создание индексов на внешних ключах (
- Недостатки: Индексы занимают место на диске и могут замедлять операции записи (
INSERT,UPDATE,DELETE), поскольку при каждом изменении данных индекс также должен быть обновлен. Важно найти баланс.
- Нормализация и денормализация:
- Нормализация: Как обсуждалось ранее, она уменьшает избыточность и аномалии. Однако избыточная нормализация (например, до 4НФ или 5НФ, когда это не строго необходимо) может привести к увеличению количества JOIN операций в запросах, что замедляет их выполнение.
- Денормализация: Вводит контролируемую избыточность данных для улучшения производительности запросов, особенно при интенсивных операциях чтения.
- Применение для «Фруктового сада»: Если, например, часто требуется получать
Название_Сортавместе с информацией обУрожае, можно рассмотреть возможность добавленияНазвание_Сортанепосредственно в таблицуУрожай(сохраняя при этомИД_Сортакак внешний ключ) для сокращения JOIN операций. Это компромисс между целостностью и производительностью.
- Оптимизация SQL-запросов:
- Суть: Один и тот же результат можно получить разными SQL-запросами, но их производительность может существенно отличаться. Оптимизация включает переписывание запросов для их более эффективного выполнения.
- Рекомендации:
- Избегать
SELECT *и выбирать только необходимые столбцы. - Оптимизировать WHERE условия.
- Правильно использовать JOIN (предпочтительнее INNER JOIN вместо OUTER JOIN, если это возможно).
- Избегать функций в WHERE условиях по индексированным столбцам.
- Использовать
EXPLAIN(или аналогичные инструменты СУБД) для анализа планов выполнения запросов и выявления «узких мест».
- Избегать
- Мониторинг и тестирование:
- Суть: Постоянный мониторинг производительности базы данных и регулярное нагрузочное тестирование.
- Инструменты: Большинство СУБД предоставляют встроенные инструменты мониторинга (например,
pg_stat_statementsв PostgreSQL, Performance Monitor в SQL Server). - Применение для «Фруктового сада»: Отслеживание времени выполнения самых частых запросов (например, запросов на получение общего урожая, просмотр партий на складе). Нагрузочное тестирование при добавлении большого количества новых записей об урожае или продажах.
- Кэширование:
- Суть: Хранение часто используемых данных или результатов запросов во временной памяти (кэше) для быстрого доступа, минуя обращение к диску.
- Типы: Кэширование на уровне СУБД (буферные пулы), кэширование на уровне приложения (ORM-кэши, пользовательские кэши).
- Применение для «Фруктового сада»: Кэширование данных о сортах фруктов, которые редко меняются, но часто запрашиваются. Кэширование агрегированных отчетов (например, общий урожай за год), которые генерируются раз в день, но просматриваются многократно.
Применение этих методов позволит создать не только функциональную, но и высокопроизводительную систему учета «Фруктовый сад», способную эффективно обрабатывать растущие объемы данных.
Расширение Функционала Системы Учета Фруктового Сада
Проектирование базы данных — это не одноразовый акт, а итеративный процесс. С развитием бизнеса и появлением новых потребностей возникает необходимость расширения функционала информационной системы. Для «Фруктового сада» это может означать учет новых параметров, таких как болезни деревьев, удобрения, климатические данные и т.д.
Включение дополнительных параметров в структуру БД
Расширение функционала часто влечет за собой добавление новых сущностей и связей, которые изначально могли быть не учтены. Рассмотрим, как можно включить дополнительные параметры, такие как болезни деревьев и обработки, в нашу существующую структуру базы данных.
1. Учет болезней деревьев:
- Необходимо создать новую сущность
БОЛЕЗНИ, которая будет содержать информацию о различных заболеваниях. - Поскольку одно дерево может болеть несколькими болезнями, и одна болезнь может поражать несколько деревьев, это отношение «многие-ко-многим». Для его реализации потребуется промежуточная таблица связей.
- Новая сущность:
БОЛЕЗНИИД_БолезниINT PRIMARY KEYНазвание_БолезниVARCHAR(100) NOT NULL (например, «Парша», «Мучнистая роса»)ОписаниеTEXT (подробное описание болезни, симптомы)Методы_ЛеченияTEXT (рекомендуемые методы лечения)
- Новая таблица связей:
ДЕРЕВЬЯ_БОЛЕЗНИИД_ЗаписиINT PRIMARY KEY (или составной ключ)ИД_ДереваINT NOT NULL, FOREIGN KEY (ИД_Дерева) REFERENCESДеревья(ИД_Дерева)ИД_БолезниINT NOT NULL, FOREIGN KEY (ИД_Болезни) REFERENCESБОЛЕЗНИ(ИД_Болезни)Дата_ОбнаруженияDATE NOT NULLДата_ЛеченияDATE (NULLable, если лечение еще не завершено)Статус_БолезниVARCHAR(50) (например, «Активна», «Вылечена», «В ремиссии»)
2. Учет удобрений и обработок:
- Для отслеживания агротехнических мероприятий можно создать отдельные сущности для самих обработок и используемых препаратов, а также связующие таблицы.
- Новая сущность:
ОБРАБОТКИИД_ОбработкиINT PRIMARY KEYТип_ОбработкиVARCHAR(100) NOT NULL (например, «Опрыскивание», «Внесение удобрений»)Дата_ОбработкиDATE NOT NULLОписаниеTEXTИД_ДереваINT NOT NULL, FOREIGN KEY (ИД_Дерева) REFERENCESДеревья(ИД_Дерева) (Если обработка привязана к конкретному дереву)ИД_КварталаINT, FOREIGN KEY (ИД_Квартала) REFERENCESКварталы(ИД_Квартала) (Если обработка для всего квартала)
- Новая сущность:
ПРЕПАРАТЫИД_ПрепаратаINT PRIMARY KEYНазвание_ПрепаратаVARCHAR(100) NOT NULL (например, «Бордоская смесь», «Карбамид»)Тип_ПрепаратаVARCHAR(50) (например, «Фунгицид», «Инсектицид», «Удобрение»)ПроизводительVARCHAR(100)Инструкция_ПримененияTEXT
- Новая таблица связей:
ОБРАБОТКИ_ПРЕПАРАТЫ(для связи обработок с несколькими препаратами)ИД_СвязиINT PRIMARY KEY (или составной ключ)ИД_ОбработкиINT NOT NULL, FOREIGN KEY (ИД_Обработки) REFERENCESОБРАБОТКИ(ИД_Обработки)ИД_ПрепаратаINT NOT NULL, FOREIGN KEY (ИД_Препарата) REFERENCESПРЕПАРАТЫ(ИД_Препарата)ДозировкаVARCHAR(50)Единица_ИзмеренияVARCHAR(20) (например, «г/л», «мл/10л»)
Модификация атрибутивного состава таблиц
Помимо добавления новых сущностей, функционал может быть расширен путем модификации существующих таблиц.
1. Добавление новых столбцов в существующие таблицы:
- Это самый простой способ добавить информацию, которая тесно связана с уже существующей сущностью.
- Пример:
- В таблицу
Деревьяможно добавитьВысота_СмDECIMAL(5,2) иДиаметр_Ствола_СмDECIMAL(5,2) для отслеживания роста дерева. - В таблицу
Урожайможно добавитьКомментарииTEXT для заметок о конкретном сборе. - В таблицу
Сортаможно добавитьОжидаемая_Продолжительность_Жизни_ЛетINT.
- В таблицу
2. Создание новых связанных таблиц для специфических атрибутов:
- Если добавляемые атрибуты могут быть многочисленными, необязательными или иметь свою собственную сложную структуру, лучше создать отдельную таблицу и связать ее с основной через внешний ключ. Это помогает поддерживать нормализацию и чистоту основной таблицы.
- Пример:
- Если
Состояние_Здоровьядерева требует детального логирования, можно создать таблицуЖУРНАЛ_ЗДОРОВЬЯ_ДЕРЕВА(ИД_Записи,ИД_Дерева,Дата_Проверки,Показания,Рекомендации_Агронома). - Для
Покупателейможет понадобиться хранить историю их предпочтений или скидок в отдельной таблицеИСТОРИЯ_ПОКУПАТЕЛЯ(ИД_Записи,ИД_Покупателя,Тип_События,Дата_События,Значение).
- Если
Таким образом, система «Фруктовый сад» может эволюционировать, адаптируясь к меняющимся требованиям и предоставляя все более полную и детализированную информацию для эффективного управления. Гибкость реляционной модели и возможности SQL делают этот процесс управляемым и масштабируемым.
Заключение
В рамках данной контрольной работы мы совершили увлекательное путешествие по миру реляционных баз данных, пройдя путь от фундаментальных теоретических концепций до практической реализации и углубленной оптимизации. Основной замысел — разработка структурированного плана для системы учета фруктового сада — был успешно реализован, демонстрируя не только понимание предметной области, но и мастерское владение инструментарием проектирования БД и языка SQL.
Мы начали с обзора основ реляционной модели данных, подчеркнув революционный вклад Эдгара Ф. Кодда и детально рассмотрев ключевые понятия, такие как отношения, кортежи, атрибуты, домены, а также механизмы первичных и внешних ключей, лежащие в основе всех связей. Это позволило нам заложить прочный теоретический фундамент для дальнейших этапов разработки.
Далее мы перешли к проектированию базы данных «Фруктовый сад», последовательно пройдя через этапы концептуального, логического и физического моделирования. Разработанная ER-диаграмма наглядно представила сущности предметной области (Деревья, Кварталы, Урожай, Продажи и т.д.) и их взаимосвязи, а затем была преобразована в логическую схему реляционных таблиц. Особое внимание было уделено нормализации до Третьей нормальной формы (3НФ), что позволило структурировать данные оптимальным образом, минимизируя избыточность и аномалии.
Выходя за рамки стандартных требований, мы углубились в продвинутые нормальные формы: BCNF, 4НФ и 5НФ. Этот раздел позволил продемонстрировать, как эти более строгие правила помогают устранить специфические типы зависимостей и предотвратить тонкие аномалии, которые 3НФ может не уловить, тем самым повышая качество и надежность базы данных в особо сложных сценариях. В конечном итоге, глубокая нормализация защищает данные от искажений и несогласованности, обеспечивая их долгосрочную ценность.
Практическая часть работы была посвящена основам языка SQL, где мы подробно рассмотрели DDL-операторы для создания структуры базы данных и DML-операторы (INSERT, UPDATE, DELETE, SELECT) для манипуляции данными. Многочисленные примеры SQL-запросов, адаптированных к системе «Фруктовый сад», показали, как можно эффективно извлекать аналитическую информацию, агрегировать данные и поддерживать актуальность записей.
Наконец, мы изучили вопросы обеспечения целостности данных (сущностей, ссылочной, доменной) и методы оптимизации производительности (индексирование, нормализация/денормализация, оптимизация запросов, мониторинг, кэширование), подчеркнув их критическую важность для стабильной и эффективной работы информационной системы. Мы также предложили направления для расширения функционала, показав, как база данных может развиваться, включая новые параметры, такие как болезни деревьев и обработки.
В целом, проделанная работа подтверждает, что реляционные базы данных и язык SQL являются мощными и гибкими инструментами, незаменимыми для создания современных информационных систем. Глубокое понимание их принципов, тщательное проектирование и постоянная оптимизация — залог успеха в построении надежных, масштабируемых и высокопроизводительных решений для любых предметных областей, включая такую специфическую, как учет фруктового сада.
Список использованной литературы
- 11 методов оптимизации баз данных // SQL-Ex blog. URL: https://sql-ex.ru/docs/11-methods-optimization-database (дата обращения: 03.11.2025).
- База данных «Поставки овощей и фруктов». Лабораторная работа на MS Access 2007 (Аксес) // KURSOVIK.COM. URL: https://kursovik.com/bd/246.htm (дата обращения: 03.11.2025).
- Базовые понятия реляционных баз данных // Интуит. URL: https://www.intuit.ru/studies/courses/645/501/lecture/11559 (дата обращения: 03.11.2025).
- В России запатентован БПЛА, собирающий фрукты и складывающий их в корзину // CNews. URL: https://www.cnews.ru/news/top/2025-11-01_v_rossii_zapatentovan_bpla_sobirayushchij (дата обращения: 03.11.2025).
- Задачи проектирования баз данных // Интуит. URL: https://www.intuit.ru/studies/courses/3430/786/lecture/17398 (дата обращения: 03.11.2025).
- Инструкции INSERT, UPDATE и DELETE // bspu.b. URL: http://www.bspu.ru/node/685 (дата обращения: 03.11.2025).
- Какие существуют способы оптимизации производительности баз данных? // Вопросы к Поиску с Алисой (Яндекс Нейро). URL: https://yandex.ru/q/question/kakie_sushchestvuiut_sposoby_optimizatsii_50f83713/ (дата обращения: 03.11.2025).
- Ключевые термины реляционной модели // StudFiles. URL: https://studfile.net/preview/1723508/page:12/ (дата обращения: 03.11.2025).
- Лекция 1. Введение в проектирование баз данных // MSUniversity. URL: https://msuniversity.ru/lecture/bd-1/ (дата обращения: 03.11.2025).
- Манипуляции с данными: SELECT, INSERT, UPDATE, DELETE // Opennet.ru. URL: https://www.opennet.ru/docs/RUS/mysql_guide/c730.html (дата обращения: 03.11.2025).
- Методы оптимизации для всех баз данных // IBM. URL: https://www.ibm.com/docs/ru/spss-modeler/18.3.0?topic=tuning-database-optimization-methods-all-databases (дата обращения: 03.11.2025).
- Методы расширения атрибутивного состава таблиц БД // Habr. URL: https://habr.com/ru/companies/t1/articles/730076/ (дата обращения: 03.11.2025).
- Нормализация отношений. Шесть нормальных форм // Habr. URL: https://habr.com/ru/articles/254427/ (дата обращения: 03.11.2025).
- Нормализация СУБД: пример базы данных 1NF, 2NF, 3NF // Guru99. URL: https://www.guru99.com/database-normalization.html (дата обращения: 03.11.2025).
- Нормальная форма // Википедия. URL: https://ru.wikipedia.org/wiki/%D0%9D%D0%BE%D1%80%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D0%A4%D0%BE%D1%80%D0%BC%D0%B0 (дата обращения: 03.11.2025).
- Обеспечение целостности баз данных // itbook.info. URL: https://itbook.info/db/access/120.php (дата обращения: 03.11.2025).
- Ограничения целостности в реляционной модели данных // StudFiles. URL: https://studfile.net/preview/1723508/page:14/ (дата обращения: 03.11.2025).
- Оптимизация работы с базами данных: методы и рекомендации // Евробайт. URL: https://eurobyte.ru/blog/optimizaciya-baz-dannyh/ (дата обращения: 03.11.2025).
- Основные команды SQL-команды: базовый синтаксис SQL и типы SQL-запросов // МТС Exolve. URL: https://exolve.mts.ru/blog/osnovnye-komandy-sql-komandy-bazovyj-sintaksis-sql-i-tipy-sql-zaprosov (дата обращения: 03.11.2025).
- Основные понятия реляционной модели данных // Tadviser. URL: https://www.tadviser.ru/index.php/%D0%A1%D1%82%D0%B0%D1%82%D1%8C%D1%8F:3.6.1._%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D0%B5_%D0%BF%D0%BE%D0%BD%D1%8F%D1%82%D0%B8%D1%8F_%D0%A0%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%BE%D0%B9_%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D0%B8_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85 (дата обращения: 03.11.2025).
- Основные этапы проектирования БД // StudFiles. URL: https://studfile.net/preview/1806317/page:10/ (дата обращения: 03.11.2025).
- Памятка/шпаргалка по SQL // Хабр. URL: https://habr.com/ru/articles/564344/ (дата обращения: 03.11.2025).
- Проектирование баз данных // Википедия. URL: https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B0%D0%B7_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85 (дата обращения: 03.11.2025).
- Проектирование баз данных // StudFiles. URL: https://studfile.net/preview/1723508/page:13/ (дата обращения: 03.11.2025).
- Разработка информационной системы анализа урожайности зерновых культур и основных элементов ее структуры // КиберЛенинка. URL: https://cyberleninka.ru/article/n/razrabotka-informatsionnoy-sistemy-analiza-urozhaynosti-zernovyh-kultur-i-osnovnyh-elementov-ee-struktury (дата обращения: 03.11.2025).
- Реляционная модель данных // Википедия. URL: https://ru.wikipedia.org/wiki/%D0%A0%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85 (дата обращения: 03.11.2025).
- Реляционная модель данных // Tadviser. URL: https://www.tadviser.ru/index.php/%D0%A1%D1%82%D0%B0%D1%82%D1%8C%D1%8F:3.6._%D0%A0%D0%B5%D0%BB%D1%8F%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85 (дата обращения: 03.11.2025).
- Реляционная модель данных: виды ключей, реализация различных типов связей, виды целостности // Базы данных. Полный курс. URL: https://db.lec.wiki/relational-model.html (дата обращения: 03.11.2025).
- Реляционная модель данных. Понятие таблица, ключ, кортеж, атрибут, домен // StudFiles. URL: https://studfile.net/preview/5753086/page:5/ (дата обращения: 03.11.2025).
- Реляционная модель. Основные понятия: отношение, кортеж, атрибут, домен, первичный ключ, внешний ключ. Ограничения целостности данных // StudFiles. URL: https://studfile.net/preview/9595267/page:30/ (дата обращения: 03.11.2025).
- Создание информационной базы данных агроэкологического мониторинга реперных участков Тувы (методический подход) // КиберЛенинка. URL: https://cyberleninka.ru/article/n/sozdanie-informatsionnoy-bazy-dannyh-agroekologicheskogo-monitoringa-repernyh-uchastkov-tuvy-metodicheskiy-podhod (дата обращения: 03.11.2025).
- SQL-запросы на вставку, модификацию и удаление данных // StudMed.ru. URL: https://www.studmed.ru/view/sql-zaprosy-na-vstavku-modifikaciyu-i-udalenie-dannyh_d83e23d75a6.html (дата обращения: 03.11.2025).
- Универсальные структуры в реляционных базах данных // Systems.Education. URL: https://systems.education/blog/universalnye-struktury-v-relyatsionnyh-bazah-dannyh/ (дата обращения: 03.11.2025).
- Целостность данных (Data integrity) // Loginom Wiki. URL: https://loginom.ru/wiki/data_integrity (дата обращения: 03.11.2025).
- Целостность данных в базах данных: что это и зачем нужно // Staffcop. URL: https://www.staffcop.ru/blog/chto-takoe-tselostnost-dannykh-v-bazakh-dannykh/ (дата обращения: 03.11.2025).
- Целостность базы данных // Википедия. URL: https://ru.wikipedia.org/wiki/%D0%A6%D0%B5%D0%BB%D0%BE%D1%81%D1%82%D0%BD%D0%BE%D1%81%D1%82%D1%8C_%D0%B1%D0%B0%D0%B7%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85 (дата обращения: 03.11.2025).
- Что такое база данных, их типы, свойства, структура — примеры использования и управления таблицами баз данных // Яндекс Практикум. URL: https://practicum.yandex.ru/blog/chto-takoe-baza-dannyh/ (дата обращения: 03.11.2025).
- Что такое нормализация баз данных? // Otus. URL: https://otus.ru/journal/chto-takoe-normalizatsiya-baz-dannykh/ (дата обращения: 03.11.2025).
- Что такое нормализация баз данных? // Первый БИТ. URL: https://www.1cbit.ru/blog/chto-takoe-normalizatsiya-baz-dannykh/ (дата обращения: 03.11.2025).
- Что такое реляционная база данных? // Amazon Web Services (AWS). URL: https://aws.amazon.com/ru/relational-database/ (дата обращения: 03.11.2025).
- Эффективная оптимизация баз данных для повышения производительности // Serverspace. URL: https://serverspace.ru/support/help/database-optimization/ (дата обращения: 03.11.2025).
- Эффективный алгоритм обработки больших баз данных MLM-структур // Habr. URL: https://habr.com/ru/articles/731776/ (дата обращения: 03.11.2025).
- Extend Database Capabilities // SQL Server Data Tools (SSDT). URL: https://learn.microsoft.com/ru-ru/sql/ssdt/extend-database-capabilities?view=sql-server-ver16 (дата обращения: 03.11.2025).