Нормализация модели данных
Основным критерием качества разработанной модели данных является ее соответствие так называемым нормальным формам (НФ). Основная цель нормализации – устранение избыточности данных. Коддом были определены три нормальные формы, которые включают одна другую. Другими словами, если модель данных соответствует 2НФ, то она одновременно соответствует и 1НФ. Соответствие 3НФ подразумевает соответствие 1НФ и 2НФ.
Первая нормальная форма гласит: информация в каждом поле таблицы является неделимой и не может быть разбита на подгруппы. Пример информации, не соответствующей 1НФ:
… | Иванов, 15 отдел, начальник | … |
Правильно:
Фамилия | Должность | № отдела |
Иванов | Начальник |
Вторая нормальная форма гласит: таблица соответствует 1НФ и в таблице нет неключевых атрибутов, зависящих от части сложного (состоящего из нескольких столбцов) первичного ключа. Пример информации, не соответствующей 2НФ:
№ отдела | Должность | Отдел | Количество сотрудников |
Начальник | Производственный отдел | ||
Инженер | Производственный отдел | ||
Начальник | Отдел продаж | ||
Менеджер | Отдел продаж |
Предположим, что данная модель описывает структуру отделов по должностям. Первичный ключ (выделен серым цветом) является сложным и состоит из двух столбцов (номер отдела и наименование должности). В данном случае наименование отдела логически зависит только от номера отдела и не зависит от должности (одна и та же должность может существовать в разных отделах). Чтобы привести модель ко 2-й НФ, необходимо разбить эту таблицу на две логически взаимосвязанные:
Отделы | ||||
№ отдела | Наименование | |||
Производственный отдел | ||||
Отдел продаж | ||||
Структура | ||||
№ отдела | Должность | Количество сотрудников | ||
Начальник | ||||
Инженер | ||||
Начальник | ||||
Менеджер | ||||
Кстати, это пример случая, когда вторичный ключ (“№ отдела”) одновременно является частью первичного (“№ отдела”, “Должность”).
Следствие: если в таблице первичный ключ состоит из одного столбца, то эта таблица автоматически соответствует 2НФ (при условии соответствия и 1НФ).
Третья нормальная форма гласит: таблица соответствует первым двум НФ
и все неключевые атрибуты зависят только от первичного ключа и не зависят друг от друга. Пример несоответствия 3НФ:
Сотрудники | |||||
Табельный № | Фамилия | Оклад | Наименование отдела | № отдела | |
Иванов | Производственный отдел | ||||
Петров | Производственный отдел | ||||
Иванов | Отдел продаж | ||||
Очевидно, что неключевые атрибуты “Наименование отдела” и “№ отдела” логически взаимосвязаны друг с другом, в то время как комбинация фамилия-отдел-оклад имеет смысл только в сочетании с табельным номером сотрудника (предположим, что в организации работают два Иванова-однофамильца в разных отделах). Решение может быть следующим:
Сотрудники | |||
Табельный № | Фамилия | Оклад | № отдела |
Иванов | |||
Петров | |||
Иванов |
Отделы | |
№ отдела | Наименование |
Производственный отдел | |
Отдел продаж |
Язык SQL
Взаимодействие приложений и пользователей с реляционными СУБД осуществляется посредством специального языка структурированных запросов (Structured Query Language, сокращенно – SQL). SQL был разработан еще в начале 70-х годов ХХ века и представляет собой непроцедурный язык, состоящий из набора стандартных команд на английском языке. Термин “непроцедурный” означает, что изначально в языке отсутствуют алгоритмические конструкции (переменные, переходы по условию, циклы и т.д.) и возможность компоновать логически связанные команды в единые программные блоки (процедуры и функции).
Язык SQL в настоящий момент стандартизован, последний действующий стандарт носит название SQL2. Практически все известные СУБД поддерживают требования стандарта SQL2 плюс вводят собственные расширения языка SQL, учитывающие особенности конкретной СУБД (в том числе и процедурные расширения).
Общий принцип работы с СУБД посредством SQL можно кратко описать следующим образом: выдал команду – получил результат. Отдельные команды изначально никак логически не связаны друг с другом. Например, для извлечения данных из таблицы пользователь должен сформировать специальное предложение на языке SQL. СУБД обрабатывает запрос, извлекает нужные данные и возвращает их пользователю, после чего “забывает” об этом и переходит в состояние готовности выполнить любой очередной запрос SQL.
“Общение” пользователя с СУБД осуществляется с помощью специальных утилит, которые обычно входят в комплект поставки СУБД. В частности, у Oracle эта утилита называется SQL*Plus, а у MS SQL Server – Query Analyzer. Любая из них способна как минимум принять от пользователя SQL-команду, отправить ее на выполнение ядру СУБД и отобразить на экране результат операции. Вот как выглядит экран Oracle SQL*Plus:
Рис. 1. Интерактивная утилита
В состав дистрибутива СУБД входят и API-библиотеки, позволяющие исполнять SQL-запросы из написанного пользователем программного кода.
Команды SQL
Как будет подробнее рассмотрено ниже, SQL позволяет не только извлекать данные, но и изменять их, добавлять новые данные, удалять данные, определять структуру данных, управлять пользователями, разграничивать доступ к данным и многое другое.
Базовый вариант SQL содержит порядка 40 команд (часто еще называемых запросами или операторами) для выполнения различных действий внутри СУБД.
Все SQL-команды начинаются с глагола (команды), определяющего, что именно нужно сделать. Далее с помощью внутренних ключевых слов задаются дополнительные условия выполнения. Например, команда на выборку табельных номеров сотрудников с зарплатой больше 500 у.е. из таблицы, содержащей список сотрудников некоей организации, выглядит следующим образом:
SELECTTabNumFROMEmployeesWHERESalary>500
где:
- SELECT – глагол (“выбрать”);
- FROM, WHERE – ключевые слова (“откуда”, “где”);
- Employees – имя таблицы;
- TabNum, Salary – имена столбцов таблицы.
В общем случае структура каждой команды зависит от ее типа.
В зависимости от вида производимых действий все команды разбиты на несколько групп.
Команды определения структуры данных
(Data Definition Language – DDL)
В состав DDL-группы входят команды, позволяющие определять внутреннюю структуру базы данных. Перед тем как сохранять данные в БД, необходимо создать в ней таблицы и, возможно, некоторые другие сопутствующие объекты (увеличивающие скорость поиска индексы, ограничения целостности и др.).
Пример некоторых DDL-команд:
Команда | Описание |
CREATE TABLE | Создать новую таблицу |
DROP TABLE | Удалить существующую таблицу |
ALTER TABLE | Изменить структуру существующей таблицы |
Команды манипулирования данными
(Data Manipulation Language – DML)
DML-группа содержит команды, позволяющие вносить, изменять, удалять
и извлекать данные из таблиц.
Примеры DML-команд:
Команда | Описание |
SELECT | Извлечь данные из таблицы |
INSERT | Добавить новую строку данных в таблицу |
DELETE | Удалить строки из таблицы |
UPDATE | Изменить информацию в строках таблицы |
Команды управления транзакциями
(Transaction Control Language – TCL)
TCL-команды используются для управления изменениями данных, производимыми DML-командами. С их помощью несколько DML-команд могут быть объединены в единое логическое целое, называемое транзакцией. При этом все команды на изменение данных в рамках одной транзакции либо завершаются успешно, либо все могут быть отменены в случае возникновения каких-либо проблем с выполнением любой из них. Транзакции есть одно из средств поддержания целостности и непротиворечивости данных и являются одной из важнейших функций современных СУБД.
TCL-команды:
Команда | Описание |
COMMIT | Завершить транзакцию и зафиксировать все изменения в БД |
ROLLBACK | Отменить транзакцию и отменить все изменения в БД |
SET TRANSACTION | Установить некоторые условия выполнения транзакции |
Команды управления доступом (Data Control Language – DCL)
DCL-команды управляют доступом пользователей к БД и отдельным объектам:
Команда | Описание |
GRANT | Разрешить доступ |
REVOKE | Отменить доступ |
Работа с командами SQL