Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Базы данных. Курс лекций

.pdf
Скачиваний:
0
Добавлен:
12.08.2026
Размер:
675 Кб
Скачать

по месяцам, можно создать поля для хранения данных о продаже по каждому товару. Однако в этом случае мы имеем дело с повторяющимися группами (серая заливка, рис. 20):

Что делать, если товаров не 4, а 104? Конечно, можно определить, сколько полей, сколько товаров. Но как быть, если число товаров заранее не известноипоодной накладнойможетбытьотпущено2, аподругой— 772 товара?

СТАТИСТИКА ПРОДАЖ

Год

Месяц

Товар 1 Товар 2 Товар 3 Товар 4

Рис. 20. Повторяющиеся группы

Реализовать запись с переменным числом полей в реляционных базах данных невозможно, поскольку запись таблицы реляционной БД должна иметь четкую структуру. Исходя из вышесказанного, повторяющиеся группы следует устранить. В результате получим запись, содержащую информацию о статистике продаж по одному товару (рис. 21). Для 4 товаров будем иметь 4 записи, для 104 товаров — 104 записи и для п товаров - п записей для каждого месяца.

СТАТИСТИКА ПРОДАЖ

Год

Месяц

Товар

Рис. 21. Устранениеповторяющихсягрупп

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

40

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

Поэтому из поля «Адрес» (допускающего толкование как делимого поля) выделим в отдельное поле «Город». Известно, что каждый покупатель может закупить в один день различное количество товаров. Поэтому переборем искушение назначить каждому товару отдельное поле и выделим факт отпуска товара в отдельную запись (рис. 23).

 

 

Накладная№123

 

Дата

Покупатель

Адрес

 

 

10.01.2007

ТОО«Геракл»

г. Москва, ул. Стромынка, 20

 

Отпущентовар

Количество

Ед. изм. Ценазаед. изм.

Общаястоимость

Тушенка

10 000

банки

100

1 000 000

Сахар

200

кг

30

6 000

Макароны

1 000

кг

35

35 000

Итого1 041 000

Рис. 22. Примернакладной ОТПУСК ТОВАРОВ СО СКЛАДА

Дата

Покупатель

Город

Адрес

Товар Ед_измерения Цена_за_ед_изм Отпущено_ед Общая стоимость Номер_накладной

Рис. 23. Таблица без составных полей и циклических групп

41

Для того чтобы продолжить нормализацию данных, приведем данные ко второй нормальной форме (2НФ).

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

Продолжим рассмотрение описанного выше примера. Для приведения к 2НФ выделим поля, которые входят в первичный ключ. Дата накладной и номер накладной по отдельности не могут уникально определять запись, поскольку они будут одинаковы для всех записей, относящихся к одной и той же накладной. Поэтому введем в первичный ключ поле «Товар». При этом исходим из имеющегося правила, что по одной накладной может быть отпущено одно наименование конкретного товара, т. е. не может иметь место ситуация, когда отпуск одного и того же товара оформляется в накладной двумя строками (что влечет за собой две одинаковые записи в таблице «Отпуск товаров со склада», рис. 24):

 

 

Накладная№123

 

Дата

Покупатель

Адрес

 

 

10.01.2007

ТОО«Геракл»

г. Москва, ул. Стромынка, 20

 

Отпущентовар

Количество

Ед. изм. Ценазаед. изм.

Общаястоимость

 

 

 

 

 

Тушенка

6 000

банки

100

600 000

Тушенка

4 000

банки

100

400 000

 

 

 

 

 

Сахар

200

кг

30

6 000

Макароны

1 000

кг

35

35 000

 

 

 

 

Итого1 041 000

Рис. 24. Примернакладной

Покажем на рис. 25 структуру таблицы «Отпуск товаров со склада» после выделения полей в составе первичного ключа (эти поля отчеркнуты от прочих полей линией и располагаются в верхней части структуры таблицы).

42

ОТПУСК ТОВАРОВ СО СКЛАДА

Дата

Покупатель Номер_накладной Товар

Город

Адрес Ед_измерения Цена_за_ед_изм Отпущено_ед Общая стоимость

Рис. 25. Таблица с избыточным первичным ключом

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

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

ОТПУСК ТОВАРОВ СО СКЛАДА

Номер_накладной Товар

Дата

Покупатель

Город

Адрес Ед_измерения Цена_за_ед_изм Отпущено_ед Общая стоимость

Рис. 26. Таблица с неизбыточным первичным ключом, не приведенная к 2НФ

Первое требование 2НФ выполнено. Чего не скажешь о втором требовании, гласящем, что значения всех полей записи должны однозначно зависеть от сово-

43

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

ТОВАРЫ

Товар

Ед_измерения Цена_за_ед_изм

ОТПУСК ТОВАРОВ СО СКЛАДА

Номер_накладной Товар (FK)

Дата

Покупатель

Город

Адрес Отпущено_ед Общая_стоимость

Рис. 27. Выделение таблицы «Товар»

ТОВАРЫ ПОКУПАТЕЛИ

Товар Покупатель

Ед_измерения Город Цена_за_ед_изм Адрес

ОТПУСК ТОВАРОВ СО СКЛАДА

Номер_накладной Товар (FK)

Дата Отпущено_ед Общая_стоимость

Рис. 28. Выделение таблицы «Покупатели»

44

Действительно, при дальнейшем анализе можно увидеть, что поля «Единица измерения», «Цена за единицу измерения» зависят только от значения поля «Товар». В самом деле, стоимость единицы измерения товара и название самой единицы измерения не зависят от конкретной накладной и будут одинаковыми для всех накладных, в которые входит данный товар.

Поэтому выделяем данные поля в отдельную таблицу «Товары» и определяем связь: поскольку один товар может присутствовать во многих накладных, таблицы «Товары» и «Отпуск товаров со склада» находятся в связи «один-ко- многим» (рис. 27) 6. После анализа структуры таблицы «Отпуск товаров со склада» можно заметить, что значение поля «Покупатель» никоим образом не зависит от пары значений «Номер накладной», «Товар», а зависит только от значения поля «Номер накладной». Поэтому данное поле и зависящие от его значения поля «Город», «Адрес» выделяются в отдельную таблицу «Покупатели» (рис. 28).

Анализируя далее структуру таблицы «Отпуск товаров со склада», можно заметить, что одно из оставшихся полей – «Дата» – зависит только от значения поля «Номер накладной». Поэтому выделяем дату и номер накладной в отдельную таблицу «Накладные» (рис. 29). Установим связи между таблицами.

Один покупатель может встречаться во многих накладных. Поэтому между таблицами «Покупатели» и «Накладные» имеется связь «один-ко-многим» по полю «Покупатель». Одной накладной могут соответствовать несколько товаров. Поэтому между таблицами «Накладные» и «Отпуск товаров со склада» имеется связь «один-ко-многим» по полю «Номер накладной» (рис. 30).

Для того чтобы уяснить, до конца нормализованы таблицы в составе разрабатываемой нами БД или нет, проанализируем ее структуру с позиций третьей нормальной формы (3НФ).

6На рис. 27 и далее FK обозначение внешнего ключа (Foreign Key).

45

ТОВАРЫ ПОКУПАТЕЛИ

Товар Покупатель

Ед_измерения Город Цена_за_ед_изм Адрес

НАКЛАДНЫЕ

Номер_накладной

Дата

ОТПУСК ТОВАРОВ СО СКЛАДА

Товар (FK)

Отпущено_ед Общая_стоимость

Рис. 29. Выделение таблицы «Накладные»

ТОВАРЫ

Товар

Ед_измерения Цена_за_ед_изм

ПОКУПАТЕЛИ

Покупатель

Город

Адрес

НАКЛАДНЫЕ

Номер_накладной

Дата Покупатель (FK)

ОТПУСК ТОВАРОВ СО СКЛАДА

Товар (FK) Номер_накладной (FK)

Отпущено_ед Общая_стоимость

Рис. 30. Связи между таблицами

46

Третья нормальная форма (3НФ) требует, чтобы в таблице не имелось транзитивных зависимостей между неключевыми полями, т. е. чтобы значение любого поля таблицы, не входящего в первичный ключ, не зависело от значения другого поля, не входящего в первичный ключ. Продолжим рассмотрение примера. Можно увидеть, что в таблице «Отпуск товаров со склада» имеется зависимость значения поля «Общая стоимость» от значения поля «Количество». Значение поля «Общая стоимость» может вычисляться как значение поля «Количество», умноженное на значение поля «Цена за единицу измерения» из таблицы «Товары» (из записи с таким же значением поля «Товар»).

Поэтому поле «Общая стоимость» из таблицы «Отпуск товаров со склада» удаляем. В результате получаем нормализованную базу данных, структура которой приводится на рис. 31.

ТОВАРЫ ПОКУПАТЕЛИ

Товар Покупатель

Ед_измерения Город Цена_за_ед_изм Адрес

НАКЛАДНЫЕ

Номер_накладной

Дата Покупатель (FK)

ОТПУСК ТОВАРОВ СО СКЛАДА

Товар (FK) Номер_накладной (FK)

Отпущено_ед

Рис. 31. Нормализованная база данных

Замечание. В таблице «Покупатели» значение поля «Адрес» зависит от значения поля «Город», поскольку в разных городах могут оказаться улицы с одина-

47

ковыми названиями и соответственно дома с одинаковыми номерами (вспомним известный кинофильм «Ирония судьбы, или с легким паром!»). Думается, что такой зависимостью можно пренебречь, поскольку поле «Адрес» в нашем случае носит чисто информационный характер и не должно входить в условия запросов самостоятельно. Вообще говоря, на практике не всегда возможно получить идеально нормализованную БД. Часто к этому и не стремятся — по причинам, изложенным в следующем разделе.

3.9. Нормализация– заипротив

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

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

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

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

48

о расходе товара со склада, требуется выдать отчет, в котором для каждой накладной указаны покупатель и его реквизиты (город и адрес). Для этого необходимо каждую запись в таблице «Накладные» объединить по названию покупателя (поле связи) с соответствующей записью из таблицы «Покупатели». Операции такого объединения подразумевают поиск и позиционирование в таблице «Покупатели» и могут выполняться достаточно медленно, особенно когда одна из таблиц имеет большой объем, данные в базе данных и на диске фрагментированы и т. д. Замечено, что ненормализованные (скажем так: «не вполне нормализованные») данные отыскиваются быстрее, если они хранятся в одной таблице, по сравнению со случаем поиска данных в одной или более связанных таблицах. Подобное ускорение тем заметнее, чем больше число записей в связанных таблицах. На скорость поиска в подчиненной таблице могут оказывать негативное влияние такие факторы, как слишком большое число вложенных полей в индексе; индекс, структура которого не совсем корректно определена, и др.

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

3.10. Пример транзакции

Разберем пример. Рассмотренную выше нормализованную БД, содержащую сведения об отпуске товаров со склада, дополним двумя таблицами (рис. 32):

«Статистика по товару» содержит сведения о суммарном отпуске каждого товара со склада начиная с начала года;

«Статистика по покупателю» содержит сведения о суммарном отпуске товаров каждому покупателю начиная с начала года.

Тогда транзакция по добавлению в БД сведений о расходе товара со склада будет состоять из следующих операций:

добавление записи в таблицу «Отпуск товаров»;

отыскание записи по данному товару в таблице «Статистика по товару» и

49

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]