Дежа
Вас попросили разработать базу данных для отслеживания технического обслуживания нескольких
машин среднего
производителя. Плановое техническое обслуживание несложно,
но когда что-то идет не так, обычно для решения
проблемы вызывается бригада рабочих
.
Техническое обслуживание
станка Идентификатор станка: A202 Дата покупки: 23 августа 2002 г.
Местоположение: Этаж C Менеджер: Дэниел Хью
Адрес: 22 Castle Street, Luton Департамент: Производство
Запланированная
дата Назначение Рабочий Комментарий
2 января Проверка масла Штраф Питера Вуда
5 февраля Несоответствие Штраф Даррен Хилл
9 февраля Ремонт колес Peter Wood Незавершенный
внеплановый
Дата Проблема Сотрудник Специальность Описание исправления
13 января Сбой инструмента Джон Смит Отложено От
вас требуется нормализовать таблицу в взаимосвязанные
реляционные таблицы, чтобы
база данных могла быть спроектирована в Microsoft Access в соответствии с нормализованными таблицами.
A) Нормализовать таблицу в реляционные таблицы (до 3-й нормальной формы); перечислите
атрибуты в каждой таблице.
Clotilde
Первая нормальная форма (1NF) устанавливает самые основные правила для организованной базы данных:
* Удалите повторяющиеся столбцы из одной и той же таблицы.
* Создайте отдельные таблицы для каждой группы связанных данных и идентифицируйте каждую строку с помощью уникального столбца (первичного ключа).
Что означают эти правила при рассмотрении практического дизайна базы данных? На самом деле это довольно просто.
Первое правило гласит, что мы не должны дублировать данные в одной строке таблицы. В сообществе баз данных эта концепция называется атомарностью таблицы. Таблицы, соответствующие этому правилу, называются атомарными. Давайте рассмотрим этот принцип на классическом примере - таблице в базе данных отдела кадров, в которой хранятся отношения «менеджер-подчиненный». Для целей нашего примера мы введем бизнес-правило, согласно которому у каждого менеджера может быть один или несколько подчиненных, а у каждого подчиненного может быть только один менеджер.
Интуитивно понятно, что при создании списка или электронной таблицы для отслеживания этой информации мы могли бы создать таблицу со следующими полями:
* Менеджер
* Подчиненный1
* Подчиненный2
* Подчиненный3
* Subordinate4
Однако вспомните первое правило, наложенное 1NF: удаляйте повторяющиеся столбцы из одной и той же таблицы. Ясно, что столбцы Subordinate1-Subordinate4 дублируются. Найдите минутку и поразмышляйте над проблемами, вызванными этим сценарием. Если у менеджера есть только один подчиненный, столбцы Subordinate2-Subordinate4 - это просто потраченное впустую пространство для хранения (драгоценный товар для базы данных). Кроме того, представьте себе случай, когда у менеджера уже есть 4 подчиненных - что произойдет, если он возьмет на себя другого сотрудника? Вся структура таблицы потребует модификации.
На этом этапе новичкам в базах данных обычно приходит в голову вторая яркая идея: мы не хотим иметь более одного столбца и хотим обеспечить гибкий объем хранилища данных. Попробуем примерно так:
* Менеджер
* Подчиненные,
где поле «Подчиненные» содержит несколько записей в форме «Мэри, Билл, Джо».
Это решение ближе, но оно также не соответствует требованиям. Столбец подчиненных по-прежнему дублирует и не атомарен. Что происходит, когда нам нужно добавить или удалить подчиненного? Нам нужно прочитать и записать все содержимое таблицы. В данной ситуации это не имеет большого значения, но что, если бы у одного менеджера было сто сотрудников? Кроме того, это усложняет процесс выбора данных из базы данных в будущих запросах.
Вот таблица, которая удовлетворяет первому правилу 1NF:
* Менеджер
* Подчиненный
В этом случае каждый подчиненный имеет одну запись, но менеджеры могут иметь несколько записей.
А что насчет второго правила: идентифицировать каждую строку с помощью уникального столбца или набора столбцов (первичный ключ)? Вы можете взглянуть на таблицу выше и предложить использовать подчиненный столбец в качестве первичного ключа. Фактически, подчиненный столбец является хорошим кандидатом на роль первичного ключа, поскольку в наших бизнес-правилах указано, что у каждого подчиненного может быть только один менеджер. Однако данные, которые мы выбрали для хранения в нашей таблице, делают это менее чем идеальным решением. Что произойдет, если мы наймем другого сотрудника по имени Джим? Как мы сохраняем его отношения между руководителем и подчиненным в базе данных?
Лучше всего использовать действительно уникальный идентификатор (например, идентификатор сотрудника) в качестве первичного ключа. Наша итоговая таблица будет выглядеть так:
* Идентификатор менеджера
* Идентификатор подчиненного
2-я Нормальная форма
За последний месяц мы рассмотрели несколько аспектов нормализации таблицы базы данных. Сначала мы обсудили основные принципы нормализации базы данных. В прошлый раз мы исследовали основные требования, предъявляемые к первой нормальной форме (1НФ). Теперь давайте продолжим наше путешествие и рассмотрим принципы второй нормальной формы (2NF).
Напомним общие требования 2NF:
* Удалите подмножества данных, которые применяются к нескольким строкам таблицы, и поместите их в отдельные таблицы.
* Создавайте связи между этими новыми таблицами и их предшественниками с помощью внешних ключей.
Эти правила можно резюмировать в простом заявлении: 2NF пытается уменьшить количество избыточных данных в таблице, извлекая их, помещая в новые таблицы и создавая связи между этими таблицами.
Давайте посмотрим на пример. Представьте себе интернет-магазин, который хранит информацию о покупателях в базе данных. У них может быть одна таблица под названием «Клиенты» со следующими элементами:
* CustNum
* FirstName
* LastName
* Address
* City
* State
* ZIP.
Беглый взгляд на эту таблицу показывает небольшой объем избыточных данных. Мы сохраняем записи «Си Клифф, Нью-Йорк 11579» и «Майами, Флорида 33157» по два раза каждая. В нашем простом примере это может показаться не слишком большим объемом дополнительного хранилища, но представьте себе потраченное впустую пространство, если бы в нашей таблице были тысячи строк. Кроме того, если бы почтовый индекс Sea Cliff изменился, нам нужно было бы внести это изменение во многих местах базы данных.
В структуре базы данных, совместимой с 2NF, эта избыточная информация извлекается и хранится в отдельной таблице. В нашей новой таблице (назовем ее ZIP) могут быть следующие поля:
* ZIP
* Город
* Штат
Если мы хотим быть сверхэффективными, мы можем даже заполнить эту таблицу заранее - почтовое отделение предоставляет каталог всех действительных почтовых индексов и их взаимосвязи между городом и штатом. Конечно, вы столкнулись с ситуацией, когда использовался этот тип базы данных. Кто-то, принимающий заказ, мог сначала запросить ваш почтовый индекс, а затем узнать город и штат, из которого вы звоните. Такое расположение снижает вероятность ошибки оператора и повышает эффективность.
Теперь, когда мы удалили повторяющиеся данные из таблицы Customers, мы удовлетворили первое правило второй нормальной формы. Нам все еще нужно использовать внешний ключ, чтобы связать две таблицы вместе. Мы будем использовать почтовый индекс (первичный ключ из таблицы ZIP), чтобы создать эту связь. Вот наша новая таблица клиентов:
* CustNum
* FirstName
* LastName
* Address
* ZIP
Теперь мы минимизировали количество избыточной информации, хранящейся в базе данных, и наша структура имеет вторую нормальную форму!
Нормальная форма 3RD
Существует два основных требования к базе данных, чтобы иметь третью нормальную форму:
* Уже удовлетворять требованиям как 1NF, так и 2NF
* Удалять столбцы, которые не полностью зависят от первичного ключа.
Представьте, что у нас есть таблица заказов виджетов, содержащая следующие атрибуты:
* Номер заказа
* Номер клиента
* Цена за единицу
* Количество
* Итого.
Помните, что наше первое требование - таблица должна удовлетворять требованиям 1NF и 2NF. Есть ли повторяющиеся столбцы? Нет. У нас есть первичный ключ? Да, номер заказа. Таким образом, мы удовлетворяем требованиям 1НФ. Существуют ли какие-либо подмножества данных, применимые к нескольким строкам? Нет, поэтому мы также выполняем требования 2NF.
Все ли столбцы полностью зависят от первичного ключа? Номер клиента зависит от номера заказа и не зависит от других полей. А как насчет цены за единицу? Это поле может зависеть от номера клиента в ситуации, когда мы взимаем с каждого клиента установленную цену. Однако, глядя на данные выше, кажется, что мы иногда взимаем с одного и того же клиента разные цены. Таким образом, цена за единицу полностью зависит от номера заказа. Количество товаров также варьируется от заказа к заказу, так что у нас все в порядке.
А как насчет общей суммы? Похоже, здесь у нас могут быть проблемы. Итоговую сумму можно получить, умножив цену за единицу на количество, поэтому она не полностью зависит от первичного ключа. Мы должны удалить его из таблицы, чтобы соответствовать третьей нормальной форме. Возможно, мы используем следующие атрибуты:
* Номер заказа * Номер
клиента
* Цена за единицу
* Количество
Теперь наша таблица находится в 3NF. Но вы можете спросить, а как насчет общего? Это производное поле, и его лучше вообще не хранить в базе данных. Мы можем просто вычислить его «на лету» при выполнении запросов к базе данных. Например, мы могли ранее использовать этот запрос для получения номеров заказов и итогов:
SELECT OrderNumber, Total
FROM WidgetOrders
Теперь мы можем использовать следующий запрос:
SELECT OrderNumber, UnitPrice * Quantity AS Total
FROM WidgetOrders
для достижения тех же результатов без нарушения правил нормализации.
Прежде чем мы начнем обсуждение обычных форм, важно отметить, что они являются только рекомендациями и рекомендациями. Иногда возникает необходимость отклониться от них, чтобы удовлетворить практические бизнес-требования. Однако, когда имеют место вариации, чрезвычайно важно оценить любые возможные разветвления, которые они могут иметь в вашей системе, и учесть возможные несоответствия.