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

SQL_LektsiiRus

.pdf
Скачиваний:
8
Добавлен:
12.02.2016
Размер:
2.1 Mб
Скачать

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

Таблица 1.3. Модифицированная таблица «Заказы»

Номер

Дата

Номер

Строка заказа (наименование,

Стоимость

заказа (ВК)

заказа

клиента

ед.изм., цена, количество)

заказа

100

10.12.09

1

Мыло, 3,50 грн., 10;

410,00

 

 

 

Шампунь, 12,50 грн., 30

 

101

11.12.09

2

Мыло, 3,50 грн., 15;

139,50

 

 

 

Порошок Gala, 8,70 грн., 10

 

102

15.12.09

1

Шампунь , 12,50 грн., 20

250,00

Таблица 1.4. Новая таблица с данными о заказчиках «Клиенты»

Номер клиента

Ф.И.О. клиента

Адрес клиента

Телефон клиента

(ВК)

 

 

 

1

Иванов

Кирова, 45

35-45-88

2

Петров

Пушкина, 43

42-85-72

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

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

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

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

повторяются. Вариант таблицы «Заказы», в котором исключены многозначные значения, но не обеспечивается однозначная идентификация строк, приведен в таблице 1.5.

Таблица 1.5 - Таблица «Заказы», в которой исключены многозначные значения

Номер

Дата

Номер

Наименование

Ед.

Цена

Количе

Стоимость

заказа

заказа

клиента

товара

изм.

товара,

ство

товара

 

 

 

 

 

грн.

товара

 

100

10.12.09

1

Мыло

Шт.

3,50

10

35,00

100

10.12.09

1

Шампунь

Бут.

12,50

30

375,00

101

11.12.09

2

Мыло

Шт.

5,00

15

75,00

101

11.12.09

2

Порошок Gala

Пач.

8,70

10

87,00

102

15.12.09

1

Шампунь

Бут.

12,50

20

250,00

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

Таблица 1.6 - Таблица «Заказы», имеющая составной ключ, основанный на двух первых столбцах

Номер

Номер

Дата

Номер

Наимено

Ед.

Цена

Количест

Стои-

заказа

строки

заказа

клиента

вание

изм.

товара,

во товара

мость

(ВК)

заказа (ВК)

 

 

товара

 

грн.

 

товара

100

1

10.12.09

1

Мыло

Шт.

3,50

10

35,00

100

2

10.12.09

1

Шампунь

Бут.

12,50

30

375,00

101

1

11.12.09

2

Мыло

Шт.

5,00

15

75,00

101

2

11.12.09

2

Порошок

Пач.

8,70

10

87,00

 

 

 

 

Gala

 

 

 

 

102

1

15.12.09

1

Шампунь

Бут.

12,50

20

250,00

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

Вторая нормальная форма.

Следующий этап нормализации состоит в переходе ко второй нормальной форме (Second Normal Form – 2 NF). Применение второй нормальной формы способствует дальнейшему сокращению количества повторяющихся данных (которые не должны обязательно составлять группы).

Вторая нормальная форма определяется в соответствии с двумя приведенными ниже правилами.

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

2.Каждый столбец должен зависеть от всего ключа.

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

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

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

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

Итак, попытаемся устранить указанный недостаток и для этого еще раз разобьем одну из используемых таблиц (таблицу «Заказы»). Фактически вначале целесообразно рассмотреть таблицу расшифровки заказа, поскольку именно в ней находится основная часть оставшихся столбцов (табл. 1.7). Начиная с этого момента таблица расшифровки будет именоваться как «Расшифровка заказа».

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

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

Таблица 1.7 - Таблица «Расшифровка заказа»

Номер

Номер

Наименование

Ед.

Цена

Количество

Стоимость

заказа

строки

товара

изм.

товара,

товара

товара

(ВК)

заказа(ВК)

 

 

грн.

 

 

100

1

Мыло

Шт.

3,50

10

35,00

100

2

Шампунь

Бут.

12,50

30

375,00

101

1

Мыло

Шт.

5,00

15

75,00

101

2

Порошок Gala

Пач.

8,70

10

87,00

102

1

Шампунь

Бут.

12,50

20

250,00

Таблица 1.8 - Таблица «Заказы»

Номер заказа (ВК)

Дата заказа

Номер клиента

100

10.12.09

1

100

10.12.09

1

101

11.12.09

2

101

11.12.09

2

102

15.12.09

1

Третья нормальная форма

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

Как было указано в конце описания второй нормальной формы, созданная структура данных все еще характеризуется определенными недостатками, поскольку в ней еще не достигнута третья нормальная форма (Third Normal Form – 3NF). Применение третьей нормальной формы позволяет добиться того, чтобы ни один столбец в таблице не зависел от каких-либо других столбцов, кроме столбцов первичного ключа. Требования

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

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

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

3.Наличие в таблице производных данных не допускается.

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

Вначале попытаемся выяснить, есть ли какие-либо столбцы, зависящие от столбца, отличного от столбца первичного ключа. Ответ на этот вопрос является положительным. Фактически в таблице «Расшифровка заказа» имеются столбцы, которые зависят от столбца наименование товара не меньше, а, возможно, даже больше, чем от столбца первичного ключа рассматриваемой таблицы. В частности, от столбца «Наименование товара»

полностью зависят столбцы «Единица измерения» и «Цена товара», поэтому необходимо снова выполнить разбиение одной таблицы на две.

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

Таблица 1.9 - Таблица «Товары»

Наименование

Ед. изм.

Цена товара, грн.

товара (ВК)

 

 

Мыло

Шт.

3,50

 

 

 

Шампунь

Бут.

12,50

 

 

 

Мыло

Шт.

5,00

 

 

 

Порошок Gala

Пач.

8,70

 

 

 

Шампунь

Бут.

12,50

 

 

 

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

Таблица 1.10 - Таблица «Расшифровка заказа»

Номер

Номер строки

Наименование

Количество

Стоимость

заказа

заказа

товара

товара

товара

(ВК)

(ВК)

 

 

 

100

1

Мыло

10

35,00

100

2

Шампунь

30

375,00

101

1

Мыло

15

75,00

101

2

Порошок Gala

10

87,00

102

1

Шампунь

20

250,00

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

значений столбцов «Цены товара» и «Количество товара»). Наличие подобных столбцов полностью противоречит требованиям нормализации.

Иногда разработчики сознательно идут на нарушение требований нормализации, причем чаще всего такие нарушения допускаются применительно к производным данным. Это связано с тем, что применение производных данных позволяет существенно повысить быстродействие. Например, запрос с условием WHERE ТоtalРгiсе > 100 выполняется намного быстрее по сравнению с запросом, содержащим условие WHERE Qty*Рriсе >50, особенно если имеется возможность создать индекс на вычисленном столбце ТоtalРгiсе.

Если какой-то столбец становится очень важным с точки зрения производительности (например, если критерии, в которых учитываются значения из этого столбца, применяются во многих запросах), то может потребоваться задать индекс на этом новом вычисленном столбце. Важность индекса состоит в том, что в нем ―материализуются‖ вычисленные данные, а это означает, что для СУБД SQL Server исключается необходимость рассчитывать значения в вычисленном столбце динамически. Вместо этого значение вычисляется только единожды, при сохранении данных о строке в индексе, а в дальнейшем используется заранее вычисленное значение столбца. Такая организация работы позволяет действительно добиться очень высокого быстродействия.

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

1.5Связи

Связи, поддерживаемые между объектами в базе данных (в основном строками), подразделяются на три основных типа:

-―один к одному‖;

-―один ко многим‖;

-―многие ко многим‖.

Каждый из этих типов связей имеет определенные разновидности, определяемые тем, может ли одна из сторон связи быть пустой или нет.

Например, иногда возникает необходимость ввести в действие вместо связи ―один к одному‖ связь ―нуль или один к одному‖.

Связь “один к одному”. Определение связи ―один к одному‖ полностью соответствует ее названию. Связью ―один к одному‖ называется такая связь, из наличия которой следует, что если имеется какая-то одна строка в одной таблице, то должна быть точно одна соответствующая ей строка в другой таблице.

Связь нуль или один к одному”. СУБД SQL Server обеспечивает поддержку экземпляров связи ―нуль или один к одному‖. По существу такая связь аналогична связи ―один к одному‖, за исключением того, что с одной из сторон связи допускается наличие или отсутствие строки, соответствующей другой строке.

СУБД SQL Server позволяет обеспечить принудительную поддержку связей «нуль или один к одному‖ с помощью описанных ниже способов.

1.С использованием сочетания уникального или первичного ключа с ограничением внешнего ключа. Ограничение внешнего ключа позволяет следить за тем, чтобы существовала по меньшей мере одна строка в таблице на стороне ―один‖ (в рассматриваемом примере — в таблице головной компании), но это ограничение не позволяет добиться того, чтобы существовала только одна строка (ограничение внешнего ключа выполняется, даже если в родительской таблице имеется несколько соответствующих ему строк). А применение первичного ключа или ограничения уникальности позволяет гарантировать соблюдение условия, согласно которому количество уникальных строк не превышает одного.

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

таблицах.

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

помощью таблиц Заказы и Расшифровка заказов отдельно представлены заказы и содержимое заказов. Таблица расшифровки (находящаяся на стороне ―один или многие‖ этой связи) не может применяться отдельно от таблицы заголовка, «Заказы», к которой она относится (безусловно, в таблице «Расшифровка заказов» содержатся многие данные о заказе, но нет информации о том, кем сделан сам заказ). Аналогичным образом, не может отдельно использоваться и сама таблица «Заказы», поскольку в ней отсутствует информация о том, что фактически входит в сам заказ (в частности, информация, позволяющая выявлять такие ситуации, что для заказа зарезервирован номер, но сама расшифровка заказа не введена).

Тем не менее, из-за наличия жесткой связи между таблицами возникает та же основная проблема, что и при использовании связей ―один к одному‖. Дело в том, что снова приходится решать, в какую таблицу необходимо вставить строку (строки) в первую очередь. И в данном случае в СУБД SQL Server единственный способ полностью реализовать эту связь состоит в реализации требования, чтобы операции вставки или удаления всех данных осуществлялись с помощью хранимых процедур.

Связь “один к нулю, одному или многим”. Связь ―один к нулю,

одному или многим‖ — это еще одна разновидность производственной, обычной, повседневно применяемой связи с помощью внешнего ключа, которая, возможно, находит даже еще более широкое распространение, чем связь ―один к одному или многим‖. Единственное заметное отличие в реализации этой связи по сравнению со связью ―один к одному или многим‖ состоит в том, что допускается отсутствие значения в ссылающемся столбце (так называется столбец таблицы, на котором задано ограничение внешнего ключа); это означает, что из самого факта, что имеется строка в таблице на стороне ―один‖, не обязательно следует наличие каких-либо экземпляров соответствующих ей строк в ссылающейся таблице (таблице на стороне ―нуль, один или многие‖).

Связь “многие ко многим”. Связь ―многие ко многим‖ характеризуется тем, что на обеих сторонах связи может присутствовать несколько согласующихся строк, а не только одна. В качестве примера такой связи можно указать связь между товарами и заказами. В каждом конкретном заказе может быть указано много разных товаров. С другой стороны, каждый конкретный товар может стать предметом нескольких разных заказов. Тем не

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

В СУБД SQL Server не предусмотрен способ непосредственного определения связи многие ко многим‖, поэтому для организации подобной связи применяется способ, основанный на использовании промежуточной таблицы. (В некоторых таблицах связи многие ко многим‖ создаются почти случайно, в ходе обычного процесса нормализации, а в других таблицах создание подобной связи предусматривается с самого начала процесса проектирования базы данных с единственной целью — обеспечить Взаимодействие между таблицами по такому принципу.) Промежуточная таблица, выполняющая роль ―посредника‖, часто именуется связующей таблицей, соединительной таблицей, а иногда объединяющей таблицей.

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