Вместо того чтобы при регистрации каждого нового клиента возлагать процесс принятия решения на операторов ввода, лучше хранить информацию, связанную с регионами, в отдельной таблице. Эту таблицу можно было бы назвать tblRegion; структура ее совсем проста.
tblRegion ID State Region
Данные в этой таблице выглядели бы следующим образом:
State Region AK Север AL Юг AR Юг AZ Запад ... ...
В этой усовершенствованной версии структуры базы данных для выборки информации о регионе вам придется выполнить двухтабличный запрос с объединением двух таблиц – tblCustomer и tblRegion, причем из одной таблицы вы получите информацию о штате, а из другой – о регионе (на основании информации о штате). В объединениях сопоставляются записи, имеющие общие поля, в отдельных таблицах. (Более подробно объединения описываются в главе 2, "Запросы и команды на языке SQL".) Хранение информации о регионах в отдельной таблице имеет ряд преимуществ.
• Если вы решили выделить новый регион на основе существующего, то для отражения рождения нового региона проще изменить всего несколько записей в таблице tblRegion, чем тысячи записей в таблице tblCustomer.
• Если вы расширите свой бизнес за пределы 50 штатов, то для отражения изменений в бизнесе достаточно опять-таки добавить новый регион. Для этого вам понадобится внести в таблицу tblRegion всего по одной записи для каждой новой области, и эта новая запись немедленно станет доступной для всей системы.
• Если обнаружится необходимость использования принципов регионального деления в других задачах, решаемых на основе этой базы данных (например, для обозначения того, что офис по продажам, расположенный в определенном штате, обслуживает определенный регион), то вы могли бы с успехом использовать таблицу tblRegion без модификаций.
Отсюда вытекает, что для отдельных категорий информации следует всегда ориентироваться на создание отдельных таблиц. Во время разработки структуры базы данных (еще до реального построения самой базы данных) необходимо хорошо продумать, какие таблицы вам нужны и как они будут связаны друг с другом. Создание схемы базы данных (см. раздел о создании схемы базы данных выше в этой главе) является частью этого важного процесса.
Отношения типа один-к-одному
Предположим, в вашей базе данных есть таблицы, в которых хранится информация о сотрудниках и видах работ. Если каждому служащему назначается один вид работы, то отношение между сотрудниками и видами работ можно определить типом один-к-одному, поскольку для каждого сотрудника в базе данных существует только один вид работы. Это простейший тип отношений как для понимания, так и для реализации, поскольку в таких отношениях таблица обычно занимает место поля в другой таблице, причем поля, участвующие в отношении, легко идентифицировать.
Однако это не самый распространенный тип отношений в функционирующих приложениях ведения баз данных. Тому есть две причины.
Почти всегда можно выразить отношение типа один-к-одному без использования двух таблиц. При этом быстродействие только повысится, хотя будет утрачена гибкость, предоставляемая хранением связанных данных в отдельной таблице. В предыдущем примере вместо создания отдельной таблицы с данными о видах работ можно поместить все поля, связанные с работой, в таблицу, предназначенную для хранения данных о сотрудниках.
Выражение отношения один-ко-многим почти такое же простое для понимания (но гораздо более гибкое), как выражение отношения один-к-одному, поэтому сразу же переходим к следующему разделу.
Отношения типа один-ко-многим
Гораздо чаще, чем отношения типа один-к-одному, в базах данных используются отношения типа один-ко-многим, в которых каждая запись таблицы связана с одной или несколькими записями в другой таблице (или вообще не связана ни с какими записями). В созданной ранее схеме базы данных между клиентами и заказами задано отношение один-ко-многим. Каждый клиент может иметь один или несколько заказов (или вообще не иметь заказов), поэтому между таблицами tblCustomers и tblOrder существует отношение один-ко-многим.
Напомним, что для реализации такого отношения в базе данных копируется первичный ключ из таблицы на стороне "один" в таблицу на стороне "многие". В пользовательском интерфейсе для ввода данных этот тип отношения обычно имеет вид формы с основной (master) и подчиненной (slave) частями, в которой одна основная запись отображается со своими подчиненными записями в отдельной части формы. В пользовательском интерфейсе первичный ключ из одной таблицы обычно связывает ся с внешним ключом из связанной таблицы с помощью списка или поля со списком.
Отношения типа многие-ко-многим
Отношение типа многие-ко-многим по сравнению с отношением один-ко-многим идет еще дальше. В качестве классического примера отношения типа многие-ко-многим можно привести отношение между студентами и классами. Каждый студент может иметь много классов, а каждый класс – много студентов. (Конечно же, возможны варианты, когда класс будет состоять из одного студента или в нем вовсе не будет ни одного учащегося, а также вполне возможно для студента иметь только один класс или ни одного.)
В данном бизнес-примере отношение задается между заказами и позициями заказа, т.е. каждый заказ может содержать несколько позиций, а каждая позиция может присутствовать в нескольких заказах.
Чтобы установить отношение многие-ко-многим, необходимо иметь три таблицы: две для хранения реальных данных и третью (именуемую соединительной) для хранения отношения между двумя первыми таблицами. Таблица соединения обычно состоит только из двух внешних ключей – по одному из каждой связанной таблицы, хотя иногда в таблице соединения полезно использовать собственное поле с идентификаторами для предоставления доступа к записям таблицы с помощью программных средств.
В качестве примера отношения многие-ко-многим можно модифицировать пример из предыдущего раздела таким образом, чтобы в базе данных хранилось несколько позиций, связанных с одним заказом, т.е. у каждого заказа было много позиций и каждая позиция относилась к неограниченному количеству заказов. В этом случае таблицы могут выглядеть так, как показано на рис. 1.13.
РИС. 1.13. В этой группе таблиц, участвующих в отношении многие-ко-многим, tbIOrderItem является таблицей соединения
Создание пользовательского интерфейса на основе Windows Forms
Разработчики предыдущих версий Visual Basic первыми предложили концепцию связывания данных, согласно которой связанный с данными объект или элемент управления данными (data control) позволяет программистам с минимальными усилиями создавать простые, связанные с данными пользовательские интерфейсы. В Visual Basic .NET эта концепция также поддерживается, а многие недостатки прежней версии устранены.
В прошлом разработчик мог установить связь между формой Visual Basic и базой данных с помощью элементов управления данными. Они предоставляют основные функции просмотра данных, позволяя приложению манипулировать наборами данных, вводить и обновлять их.
На платформе .NET операциями подключения к базе данных и извлечения данных управляет автоматически созданный код, что позволяет добиться ряда преимуществ.
1. Автоматически созданный код, в отличие от абстрактного элемента управления данными, можно просматривать, поэтому он позволяет в большей степени контролировать способы доступа к данным.
2. Изучая автоматически созданный код, программист может познакомиться с классами платформы .NET, предназначенными для доступа к данным, что особенно полезно для тех, кто не имеет опыта работы на платформе .NET.
3. Основное назначение элементов управления данными в прежней версии Visual Basic это подключение к базе данных, создание запроса к ней и управление данными. Теперь эти функции распределены между несколькими объектами, каждый из которых можно отдельно конфигурировать и использовать.
В приведенных ранее примерах создана база данных, которая вполне подходит для ознакомления с основными принципами создания связанного с данными пользовательского интерфейса. В следующих разделах демонстрируются способы создания связанных с базой данных приложений на основе Windows Forms.