Все права на текст принадлежат автору: Джеффри П Мак-Манус, Джеки Голдштейн, Кевин Т Прайс.
Это короткий фрагмент для ознакомления с книгой.
Обработка баз данных на Visual Basic®.NETДжеффри П Мак-Манус
Джеки Голдштейн
Кевин Т Прайс

Джеффри П. Мак-Манус Джеки Голдштейн Кевин Т. Прайс Обработка баз данных на Visual Basic®.NET 3-е издание Database Access with Visual Basic®.NET Third Edition Jeffrey P. McManus Jackie Goldstein Kevin T. Price Addison-Wesley

Посвящается моим родителям Анн и Майку Голдштейн, наставлявшим и поддерживавшим меня на протяжении жизни.

Джеки Голдштейн, октябрь 2002 года

Моей жене.

Кевин Прайс, октябрь 2002 года

Предисловие

В этой книге рассматриваются способы создания приложений для работы с базами данных на основе Visual Basic .NET и ADO.NET.

Хотя в ней описываются в основном провайдеры данных OLEDB и ODBC для .NET (глава 4, "Модель ADO.NET: провайдеры данных"), практически все примеры основаны на провайдере данных для сервера баз данных Microsoft SQL Server, которая используется большинством наших читателей. Более того, описываемые здесь подходы и концепции обычно можно очень просто применить для использования других источников данных. Все наиболее значительные отличия в способах использования этих технологий сопровождаются подробными комментариями.

Предполагая, что большинство читателей уже имеют опыт работы с сервером SQL Server, мы все же постарались сделать книгу доступной и для тех, кто не имеет большого опыта работы с ним. Некоторые читатели имеют ограниченный опыт работы с приложениями для баз данных или работали с другими типами баз данных, например с Microsoft Access или Oracle. Поэтому в главе 3, "Знакомство с SQL Server 2000", предлагается краткий обзор основных приемов работы с сервером Microsoft SQL Server. Опытные специалисты SQL Server могут без ущерба для понимания остальных глав пропустить эту вводную главу. Тем не менее следует учесть, что она покрывает широкий круг тем, а потому даже опытный читатель сможет найти в ней несколько полезных советов, ради которых стоит хотя бы бегло просмотреть всю главу.

Помимо основных сведений об SQL Server, здесь описываются язык XML и способы интеграции XML с ADO.NET. Этот очень важный аспект создания приложений баз данных с помощью Visual Basic .NET часто недооценивается или описывается недостаточно полно. Поскольку XML играет очень важную роль в создании современных приложений для работы с данными, эта тема излагается здесь очень подробно.

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

Для кого предназначена эта книга

Предполагается, что читатель уже знаком с основами Visual Basic.NET. Хотя здесь предлагаются очень подробные и последовательные инструкции по созданию кода, все же в этой книге не ставилась цель обучить читателя основам синтаксиса Visual Basic. Мы считаем, что читатель уже владеет основными навыками работы с Visual Basic.NET и Visual Studio.NET, а потому решили не тратить времени на повторение общеизвестных базовых сведений. В частности, за исключением только первого примера, здесь не рассматриваются такие стандартные операции, как открытие и сохранение проектов. Наряду с этим, выполнение одной и той же операции нередко описывается несколькими разными способами, что позволит читателю расширить свои знания Visual Basic.NET без лишнего повторения одних и тех же базовых сведений. Поэтому часто приводятся разные стили кодирования и копии экранов для разных версий Windows, которые иллюстрируют гибкость Visual Basic.NET.

Большинство примеров этой книги демонстрируются с помощью типа проекта Windows Application на основе Windows Forms. Дело в том, что многие программисты на Visual Basic очень хорошо знают и часто используют этот тип проекта. Это позволяет нам сфокусироваться на способах доступа к базе данных, а не на особенностях использования разных типов проектов.NET. В последних главах книги описываются приложения на основе ASP.NET и Web-службы, поэтому в рассматриваемых там примерах представлены другие технологии и типы проектов.

Структура книги

Книга содержит три части. Первая часть состоит из глав 1-3 с предварительными сведениями о базах данных, языке SQL и сервере баз данных SQL Server. Эти фундаментальные сведения позволят читателю познакомиться с основными концепциями и понятиями, используемыми в книге. Кроме того, эти главы содержат краткие обзоры важных тем, которые будут полезны даже очень опытным специалистам в этих областях.

Вторая часть содержит основной материал книги. В главах 4-7 предлагаются подробные объяснения и многочисленные примеры основных объектов ADO.NET, a также способы использования их свойств и методов. В главе 7, дополнительные компоненты", рассматриваются более сложные компоненты и способы работы с объектами ADO.NET.

В третьей части книги приводятся фундаментальные способы применения ADO.NET для создания профессиональных приложений, а также рассматриваются методы использования проектов Visual Studio Data Projects для работы со сценариями SQL (глава 8, "Работа с проектом базы данных в среде Visual Studio.NET"), язык XML (глава 9, "XML и .NET") и вопросы интеграции XML с ADO.NET (глава 10, "ADO.NET и XML"). Наконец, в последних главах описываются дополнительные типы проектов на основе ADO.NET: Web-приложения на основе ASP.NET (глава 11, "Web-формы: приложения на основе ASP.NET для работы с базами данных"), а также Web-службы и объекты промежуточного уровня (глава 12, "Web-службы и технологии промежуточного уровня").

Используемое программное обеспечение

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

Редакция Visual Studio. NET Возможности
Standard Просмотр таблиц и данных, выполнение хранимых процедур с помощью SQL Server Desktop Engine и Access
Professional Просмотр таблиц и данных, выполнение хранимых процедур с помощью любой базы данных с провайдером данных OLEDB или драйвером ODBC. Проектирование (создание или изменение) таблиц или представлений с помощью SQL Server Desktop Engine
Enterprise Developer, Enterprise Architect Просмотр таблиц и данных, выполнение хранимых процедур с помощыо любой базы данных с провайдером данных OLEDB или драйвером ODBC. Проектирование (создание или изменение) таблиц, представлений и хранимых процедур с помощью SQL Server Desktop Engine, SQL Server или Oracle

В некоторых местах глав 1, 2 и 8 используются компоненты, которые предусмотрены только в редакциях Enterprise Developer или Enterprise Architect среды Visual Studio.

В главе 3, "Знакомство с SQL Server 2000", предлагается подробное описание процесса инсталляции SQL Server 2000, которое будет особенно полезно для читателей, не имеющих опыта инсталляции этого программного продукта. Для тестовой базы данных pubs, которая поставляется вместе с SQL Server, рекомендуется создать резервную копию, потому что она используется во многих примерах этой книги и ее данные часто редактируются.

В предлагаемых бизнес-ситуациях и многих примерах используется специально созданная для этой книги база данных Novelty. В главах 3 и 8 подробно описаны сценарии создания этой базы данных. Для использования примеров нужно сначала создать базу данных Novelty на компьютере с сервером SQL Server 2000 и наполнить ее данными. При описании этих операций предполагается, что читатель обладает всеми необходимыми правами для создания базы данных на этом сервере. Учтите, что некоторые пользователи применяют термин "база данных" к понятию "приложение для работы с базами данных", но в этой книге термин "база данных" означает "структурированный набор реляционных данных, которые хранятся в SQL Server 2000".

Коды всех примеров вместе со сценариями создания и наполнения данными базы данных Novelty, которая используется в этой книге, можно найти на Web-сервере Издательского дома "Вильяме" по адресу: http://www.williamspublishing.com. Для создания этой базы данных на компьютере с SQL Server 2000 выполните ряд действий.

1. Откройте программу Query Analyzer с помощью команды Microsoft SQL Server→Query Analyzer и подключитесь к нужному серверу SQL Server.

2. Откройте файл NoveltyDB.sql, выбирая команду меню File→Open (Файл→Открыть) и указывая место расположения этого файла.

3. После открытия этого файла его содержимое будет отображено в диалоговом окне.

4. Для выполнения сценария выберите команду Execute→Query (Выполнить→Запрос) или щелкните на кнопке с изображением зеленой стрелки.

5. После выполнения сценария будет создана база данных Novelty, которую можно наполнить данными, повторяя действия, описанные в пп. 2-4, для других сценариев с суффиксом Data в имени; например, сценарий OrdersData.sql вставляет данные в таблицу с заказами.

Учтите, что исходная версия 1.0 платформы .NET Framework и среда Visual Studio.NET не содержат провайдера данных для ODBC. Он входит в следующие версии и его можно скопировать отдельно с Web-узла компании Microsoft по адресу: http://www.microsoft.com. Кроме того, там же можно скопировать провайдер данных Microsoft.NET для Oracle, если вы используете базу данных Oracle, однако учтите, что в этой книге она не описывается.

Об авторах

Джеффри П. Мак-Манус (Jeffrey P. McManus) — разработчик и автор, специализирующийся на программных продуктах Microsoft. Как разработчик, он занимался созданием оперативных приложений на основе Internet-ориентированных и клиент-серверных технологий. Он автор четырех книг, включая предыдущее издание этой книги — бестселлер Обработка баз данных на Visual Basic® 6, а также две книги, посвященные .NET-ориентированным технологиям. Джеффри регулярно участвует в конференциях VBITS/VSLive, European DevWeek и VBConnections.

Джеки Голдштейн (Jackie Goldstein) — президент компании Renaissance Computer Systems, которая специализируется на создании приложений и предоставлении консультаций в области программных продуктов и технологий Microsoft. Более 18 лет он участвует в создании и сопровождении программных продуктов в США и Израиле, а также обладает огромным опытом оказания консультационных услуг и интеграции новых технологий. Джеки является региональным директором MSDN в Израиле, основателем израильской группы пользователей Visual Basic (VB User Group). Он регулярно выступает на международных конференциях разработчиков, включая VSLive!, TechEd, VBITS, Microsoft Developer Days и SQL2TheMax. Он также работал с компанией Microsoft в качестве эксперта по основным вопросам рецензирования, усовершенствования и завершения технических материалов и презентаций для всемирных конференций Microsoft Developer Days.

О соавторе

Кевин Т. Прайс (Kevin T. Price) — старший технолог, который специализируется на вопросах обеспечения безопасности и масштабирования (штат Вирджиния). В течение многих лет он сумел охватить все аспекты создания приложений с помощью набора инструментальных средств компании Microsoft. Он написал несколько глав для разных книг об XML, системе безопасности и технологиях.NET. Помимо своей основной работы, Кевин увлекается кулинарией и пейнтболом. С ним можно связаться по адресу: kpcrash@patriot.net.

О рецензентах

Энжани Читаджаллу (Anjani Chittajallu) получила диплом мастера в области систем управления в Индийском технологическом институте (Indian Institute of Technology) в Мадрасе. Она специализируется в проектировании и разработке корпоративных систем на основе технологий Microsoft. Энжани имеет сертификат разработчика MSCD и с ней можно связаться по адресу: srianjani@hotmail.com.

Эндрю Дж. Индовина (Andrew J. Indovina) в настоящее время является старшим разработчиком программного обеспечения в Рочестере, штат Нью-Йорк (Rochester, New York). Помимо ученой степени по информатике, он обладает глубокими знаниями языков ассемблера, C/C++, Visual Basic, Java, XML, ASP и навыками программирования на них. Кроме того, он является соавтором двух книг о языках Visual Basic и C++, а также техническим редактором многочисленных книг по информатике. В последнее время Эндрю активно занимается созданием приложений на основе Microsoft .NET.

Благодарности

Мы хотим поблагодарить тех, кто помогал нам создать эту книгу, в частности: Сондру Скотт (Sondra Scott), ответственного редактора, которая решила множество проблем в процессе создания книги;

Лори Мак-Гвайр (Laurie McGuire), нашего наиболее терпеливого редактора, сделавшего очень много полезного;

Кевина Т. Прайса (Kevin T. Price), который согласился принять участие в создании этой книги и пополнить главы своими материалами, несмотря на сложные обстоятельства;

Энжани Читаджаллу (Anjani Chittajallu) и Эндрю Дж. Индовину (Andrew J. Indovina), технических рецензентов, которые не только проверили нашу работу, но и предложили множество полезных идей;

Майкла Пизо (Michael Pizzo) из компании Microsoft, который всегда быстро отвечал на наши вопросы или рекомендовал других более опытных специалистов;

наших жен, детей, родственников и друзей, которые поддерживали нас во время создания этой книги.

ГЛАВА 1 Основы построения баз данных

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

Если вы уже работали с языком Visual Basic и программировали доступ к базам данных, то материал этой главы может показаться вам довольно тривиальным. Однако не стоит пропускать ее, поскольку здесь вы найдете профессиональные термины, которые могут меняться при переходе от одной системы управления базами данных (СУБД) к другой.

Несмотря на относительное постоянство концепций, лежащих в основе различных СУБД, одни и те же вещи имеют обыкновение называться по-разному при переходе от одной конкретной реализации к следующей. Например, многие программисты, разрабатывающие приложения клиент/сервер, называют запросы (query), хранимые в контейнере базы данных, представлениями (view), а программисты, работающие в среде Visual Basic или Access, называют их запросами или объектами QueryDef. По своей сути это одно и то же.

Если вы переходите к Visual Basic .NET от предыдущей версии Visual Basic, то вам следует познакомиться с некоторыми новыми возможностями программирования баз данных с помощью Visual Basic .NET. Дело в том, что в ней используется фундаментально другой способ доступа к данным, который отличается от способов доступа к данным в прежних версиях Visual Basic. Он основан на стандартах Internet с прицелом на создание приложений с возможностями удаленного доступа к данным. Интегрированная среда разработки Visual Studio .NET содержит огромный набор визуальных и интуитивно понятных инструментов, которые упрощают и ускоряют процесс создания баз данных и обеспечивают более высокую степень взаимодействия. Ранее для создания и поддержки баз данных необходимо было иметь глубокие знания многих инструментов. С помощью Visual Studio .NET разработчик может обратиться к многочисленным программам-мастерам, что позволяет избежать создания рутинного кода и повысить гибкость создаваемых приложений.

Если же вы не понаслышке знакомы с разработкой баз данных в прежней версии Visual Basic 6.0, возможно, вам имеет смысл забежать вперед и перейти к главе 4, "Модель ADO.NET: провайдеры данных", посвященной новым способам доступа к данным в Visual Basic .NET.

Что представляет собой база данных

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

• сохраняют данные в таблицах, которые, в свою очередь, состоят из строк, называемых здесь записями, и столбцов, называемых здесь полями;

• позволяют считывать подмножества данных из таблиц (или создавать для них запросы);

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

Что такое платформа базы данных

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

Вместе с Visual Basic.NET можно использовать множество различных платформ баз данных, но в этой книге в основном рассматривается платформа Microsoft SQL Server 2000. (Более подробно она рассматривается в главе 3, "Знакомство с SQL Server 2000".) Процессором базы данных (database engine) называется сам механизм, лежащий в основе платформы базы данных и непосредственно "отвечающий" за выполнение функций и управление данными.

Бизнес-ситуации

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

Цель настоящей книги – представить программное обеспечение в терминах бизнес-решений. Поэтому каждая глава содержит несколько бизнес-вариантов, в которых некая фиктивная компания, столкнувшись с реальными проблемами в сфере бизнеса, пытается автоматизировать работу офиса. В приведенных бизнес-ситуациях используются наработки компании Jones Novelties Incorporated, которая занимается так называемым малым бизнесом — распространением сувениров, мелких дешевых товаров и организацией вечеринок.

Бизнес-ситуация 1.1: основные сведения о компании Jones Novelties Incorporated

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

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

Таблицы и поля

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

Таблицы содержат записи — отдельные частицы данных внутри широкой категории, которую они представляют. Например, таблица с клиентами содержит информацию обо всех потребителях товаров и услуг данной компании. Записи могут содержать данные практически любого типа. Они могут редактироваться, извлекаться и удаляться с помощью хранимых процедур и/или запросов на языке структурированных запросов (Structured Query Language — SQL).

Записи, в свою очередь, содержат поля. Поле — это некоторый раздел данных в записи. Например, запись, которая представляет некий элемент в адресной книге, может состоять из полей имени и фамилии, адреса, названия города, почтового индекса и номера телефона.

Для доступа к базам данных, таблицам, записям и полям можно использовать код Visual Basic .NET. Одна из новинок программирования баз данных в Visual Basic .NET заключается в строгой проверке типов данных. Например, в Visual Basic .NET предусмотрены новые методы getString() и getInt(), которые позволяют сократить объем вводимого программистом кода и автоматически форматируют извлекаемые данные согласно их типу.

Проектирование базы данных

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

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

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

tblMyTable
ID
FirstName
LastName

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

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

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

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

Бизнес-ситуация 1.2: проектирование таблиц и отношений

Брэд Джонс понял, что компании Jones Novelties Incorporated необходим способ сохранения информации о клиентах. Он совершенно уверен в том, что большинство его деловых контактов не будут однократными, и поэтому хочет иметь возможность связываться с постоянными клиентами, чтобы отсылать им каталоги два раза в год.

Размышляя таким образом за коктейлем, Брэд начертил на салфетке первую схему базы данных. "Итак, – подумал он, – чтобы поддерживать контакты с клиентами, мне нужно хранить следующие данные:

• имя клиента, его адрес, город, штат, почтовый индекс и телефонный номер;

• территориальный регион страны (северо-запад, юго-запад, средний запад, северо-восток, юг или юго-восток);

• дату последней покупки клиента".

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

Информация, которую Брэд хочет включить в таблицу, не преобразуется напрямую в ее поля. Например, поскольку регион является функцией от штата, в котором проживает данный клиент, то вряд ли имеет смысл помещать поля State и Region в одну таблицу. Если все-таки пойти на это, то оператору, занимающемуся вводом данных, придется дважды вводить аналогичную информацию о клиенте. Логичнее хранить поле State в таблице Customer, а остальные сведения, относящиеся к регионам, – в таблице Region. Если по таблице Region всегда можно определить, в каком регионе находится тот или иной штат, то оператору не придется вводить регион для каждого клиента. Вместо этого достаточно ввести только название штата, а затем после обработки данных из таблиц Customer и Region автоматически будет определен регион проживания данного клиента.

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

Поэтому Брэд и его сотрудники решили, что информация о клиентах компании Jones Novelties Incorporated будет храниться в таблице tblCustomer, которая содержит перечисленные ниже поля.

tblCustomer
ID
FirstName
LastName
Company
Address
City
State
PostalCode
Phone
Fax
Email

Данные, относящиеся к региону страны, в котором проживает клиент, следует хранить в таблице tblRegion. 

tblRegion
ID
State
RegionName 

Между двумя этими таблицами существует отношение по полю State. Обратите внимание на то, что это поле присутствует в обеих таблицах. Отношение между таблицами Region и Customer является отношением один-ко-многим, поскольку для каждой записи в таблице tblRegion может существовать или одна, или ни одной, или много записей в таблице tblCustomer, совпадающих по полю State. (Далее в главе подробно описывается, как воспользоваться преимуществами такого отношения при выборке записей.)

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

Несмотря на то что механизм управления базами данных Microsoft SQL Server позволяет использовать в именах объектов баз данных пробелы, символы подчеркивания и другие символы, не входящие в число алфавитно-цифровых, все-таки стоит избегать их использования, поскольку это затрудняет запоминание точного написания имени поля. (В этом случае вам не придется, например, гадать, как называется поле, содержащее имя: FirstName или FIRST_NAME.) Эта директива может показаться сейчас незначительной, но, когда вы начнете писать код для базы данных, содержащей 50 таблиц и 300 полей, вы по достоинству оцените существующие соглашения о присвоении имен, особенно на первом этапе разработки.

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

tblOrder
ID
CustomerID
OrderDate
Amount 

В этой таблице поле ID уникальным образом идентифицирует каждый заказ. Поле CustomerID, с другой стороны, связывает заказ с клиентом. Чтобы установить эту связь, идентификатор клиента копируется в поле CustomerID таблицы Order. Таким образом, совсем нетрудно отыскать все заказы для конкретного клиента (как будет продемонстрировано ниже).

Манипулирование данными с помощью объектов

После создания таблиц можно приступить к манипуляциям с данными: вводить данные в таблицы, извлекать их из таблиц, проверять и изменять структуру таблиц. Для манипулирования структурой таблиц используются команды определения данных (более подробно они описываются в главе 2, "Запросы и команды на языке SQL"), а для манипулирования данными – объекты DataSet или DataReader платформы .NET.

Объект DataSet обычно представляет подмножество записей, которые извлекаются из базы данных. Оно концептуально аналогично таблице (а в некоторых случаях — группе связанных полей), но также содержит несколько важных собственных свойств. Объекты DataSet можно легко представить в виде XML-данных и использовать для передачи удаленных данных (как, например, при передаче результатов выполнения запроса от сервера к клиенту или при обмене данными между двумя серверами). В Visual Basic .NET объекты DataSet не ограничены только сохранением извлеченных данных. Например, объект DataSet может использоваться для управления статическими данными в XML-документе или файле конфигурации, либо для управления динамическими данными, созданными на основе пользовательских данных в более сложных ситуациях.

Как и при работе с технологией ADO, в Visual Basic .NET и ADO.NET можно использовать подключенные и неподключенные объекты DataSet. Неподключенный объект DataSet с данными передается приложению, соединение с базой данных закрывается, а базе данных ничего не известно о манипуляциях с этими данными до тех пор, пока приложение вновь не обратится к базе данных. Допустим, что пользователь открывает форму и щелкает на кнопке для обновления данных. В таком случае приложение должно снова соединиться с базой данных и выполнить код изменения данных. В то же время с помощью подключенного объекта DataSet используемые данные "блокируются" и все изменения данных мгновенно воспроизводятся в базе данных. Эта технология более подробно рассматривается в главе 5, "ADO.NET: объект DataSet".

Объект DataReader работает аналогично объекту DataSet, но обладает другими возможностями и характеристиками производительности. Одно из отличий отражено в его названии: объект DataReader считывает данные, т.е. он предоставляет доступ к данным только для чтения. Для объекта DataReader также не предусмотрен простой способ представления данных в формате XML.

Для простоты (что также рекомендуется делать на практике) в данной книге объект DataReader используется для выполнения базовых операций доступа к данным, а объект DataSet — только в случае крайней необходимости, например для создания Web-служб (более подробно они рассматриваются в главе 12, "Web-службы и технологии промежуточного уровня").

Объект DataSet устроен так же, как и объект ADODB.Recordset в прежних версиях языка Visual Basic. Аналогично другим типам объектов языка Visual Basic, объект DataSet имеет свойства и методы. Более подробно он рассматривается в других главах книги, а здесь достаточно отметить, что на платформе .NET объекты используются для организации в приложении ясного, согласованного и относительно простого способа работы с базами данных.

Типы данных

Один из этапов проектирования базы данных заключается в объявлении типа каждого поля, что позволяет процессору базы данных эффективно сохранять и извлекать данные. В SQL Server предусмотрено использование 21 типа данных, которые перечислены в табл. 1.1.

Таблица 1.1. Типы данных в SQL Server

Тип данных Описание
bigint Восьмибайтовое целое число в диапазоне от -9223372036854775808 до 9223372036854775807
binary Двоичные данные фиксированного размера до 8 Кбайт
char Символьное поле фиксированного размера до 8000 символов
datetime Время и дата между 1 января 1753 года и 31 декабря 9999 года
decimal Десятичное число с фиксированной точностью и размером от 5 до 17 байт. Во время создания поля можно указать число десятичных знаков
float Десятичное число размером от 4 до 8 байт и не более 53 десятичных знаков после запятой
image Двоичные данные переменного размера до 2147483647 байт
int Четырехбайтовое целое число в диапазоне от -2147483648 до 2147483647
money Числовое поле со специальными свойствами для сохранения денежных значений
nchar Символьное поле фиксированного размера до 4000 символов Unicode
ntext Символьное поле произвольного размера до 1 073 741 823 символов Unicode
nvarchar Символьное поле произвольного размера до 4000 символов Unicode
real Десятичное число размером 4 байта и не более 24 десятичных знаков после запятой
smalldatetime Время и дата между 1 января 1900 года и 6 июня 2079
smallint Двухбайтовое целое число в диапазоне от -32768 до 32767
text Символьное поле произвольного размера до 2147483647 символов (в базе данных Microsoft Access есть аналогичное поле типа Memo)
tinyint Однобайтовое целое число в диапазоне от 0 до 255
uniqueidentifier Целое число, которое также называется глобально уникальным идентификатором и используется для уникальной идентификации записи (часто применяется для репликации данных)
varbinary Двоичные данные переменного размера до 8000 байт
varchar Символьные данные переменного размера до 8000 символов 

Хотя типы данных Visual Basic.NET более близки к типам данных полей SQL Server, чем типы данных Visual Basic 6, между ними все равно нет однозначного соответствия. Например, тип данных int в SQL Server соответствует типу integer в Visual Basic .NET, потому что оба они являются 32-битовыми целыми числами. Однако в SQL Server нельзя создать поле с определенным пользователем типом или типом Object языка Visual Basic .NET.

Схема базы данных

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

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

Схемы не теряют своей актуальности и после завершения процесса проектирования базы данных. Без такой схемы вам будет трудно выполнять многотабличные запросы. Толково составленная графическая схема поможет ответить на вопросы типа: "Какие таблицы мне нужно объединить, чтобы составить список всех заказов с объемом, превышающим $50,00, поступивших от клиентов из штата Миннесота в течение последних 24 часов?" (За дополнительной информацией по созданию запросов, включающих более одной таблицы, обращайтесь к главе 2, "Запросы и команды на языке SQL".)

Официальных способов создания схем баз данных не существует, но есть много средств, которыми можно воспользоваться при их создании. Например, графический редактор Visio отличается гибкостью, быстротой и простотой применения. Более того, он хорошо интегрируется с другими приложениями Windows, в частности с Microsoft Office. Этот редактор распространяется отдельно, а также входит в состав Visual Studio.NET Enterprise Architect.

Все сказанное в пользу Visio не означает, что при создании графической схемы базы данных вы должны использовать только программу Visio. Можно применять любые другие инструменты рисования, с которыми вы знакомы. Приемлемый вариант – программа Microsoft Windows Paint, можно также воспользоваться средствами рисования, предусмотренными в программе Microsoft Word.

Использование инструментов Visual Studio для создания базы данных

Существует несколько способов создания баз данных в SQL Server. С помощью набора инструментов SQL Enterprise Manager базы данных можно создавать графически или программно (с помощью команд на языке SQL). Помимо него, существует множество других внешних инструментов для создания баз данных, например Visio, который описывается далее в главе.

Visual Studio .NET также содержит очень удобный инструмент для работы с базами данных SQL Server. Он входит в состав нового компонента Server Explorer, который предназначен для централизованного управления всеми видами серверного программного обеспечения. Для создания базы данных SQL Server с помощью компонента Server Explorer выполните перечисленные ниже действия.

1. Запустите интегрированную среду разработки Visual Studio .NET, выбрав команду меню Start→Programs→Microsoft Visual Studio .NET→Microsoft Visual Studio .NET.

2. В левой части окна Visual Studio .NET откройте окно Server Explorer, выбрав команду меню View→Server Explorer (учтите, что эта вкладка может иметь горизонтальную или вертикальную ориентацию).

3. В этом окне раскройте узел Servers, найдите ваш компьютер, а затем раскройте узел SQL Servers и найдите в нем экземпляр SQL Server, который установлен на вашем компьютере, как показано на рис. 1.1.

РИС. 1.1. Вкладка Server Explorer интегрированной среды разработки Visual Studio .NET, с помощью которой можно централизованно управлять серверными процессами


4. Для создания новой базы данных щелкните правой кнопкой мыши на имени экземпляра SQL Server, который установлен на вашем компьютере. На рис. 1.1 показан компьютер ROCKO, хотя ваш компьютер может иметь совершенно другое имя. В контекстном меню выберите команду New Database (Создать новую базу данных).

5. На экране появится диалоговое окно Create Database (Создать базу данных). Введите в нем имя базы данных Novelty и щелкните на кнопке OK.

6. После этого в окне Server Explorer появится новая база данных Novelty. При раскрытии узла этой базы данных будут отображены следующие категории объектов базы данных:

• Database Diagrams (Диаграммы базы данных);

• Tables (Таблицы);

• Views (Представления);

• Stored Procedures (Хранимые процедуры);

• Functions (Функции).

Для использования базы данных нужно создать в ней хотя бы одну таблицу. Для этого выполните перечисленные ниже действия.

1. В окне Server Explorer щелкните правой кнопкой мыши на узле Tables базы данных Novelty, а затем из контекстного меню выберите команду New Table (Создать таблицу).

2. После этого в окне Visual Studio .NET появится диалоговое окно для создания структуры новой таблицы. Создайте таблицу tblCustomer с перечисленными ниже определениями полей. 

Имя поля Тип данных Длина Наличие неопределенных значений
ID int* 4 Нет
FirstName varchar 20 Да
LastName varchar 30 Да
Company varchar 50 Да
Address varchar 50 Да
City varchar 30 Да
State char 2 Да
PostalCode varchar 9 Да
Phone varchar 15 Да
Fax varchar 15 Да
E-mail varchar 100 Да

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

3. После ввода этих определений таблица будет иметь вид, показанный на рис. 1.2.

4. Щелкните на поле ID и выберите команду меню Diagram→Set Primary Key (Диаграмма→Создать первичный ключ). Благодаря этому все значения данного поля будут уникальны, т.е. все клиенты будут иметь разные идентификаторы. (Более подробные сведения о первичных ключах приводятся в следующем разделе.)

5. Далее нужно указать, что поле ID используется в SQL Server в целях автоматической генерации идентификационных номеров для клиентов. Для этого щелкните правой кнопкой мыши на окне с определением таблицы и выберите в контекстном окне Indexes/Keys (Индексы/ключи).

6. После этого на экране появится диалоговое окно Property Pages (Страницы свойств) со вкладкой Indexes/Keys. Выберите вкладку Tables (Таблицы) со свойствами таблицы.

7. В списке Table Identity Column (Поле таблицы с идентификаторами) выберите поле ID.

8. Щелкните на кнопке Close (Закрыть).

РИС. 1.2. Создание определения таблицы с помощью Visual Studio .NET


9. Выберите команду меню File→Save Table1 (Файл→Сохранить таблицу Table1). В диалоговом окне Choose Name (Выбрать имя) введите имя tblCustomer и щелкните на кнопке OK. Обратите внимание, что после сохранения таблицы ее имя появится в списке таблиц базы данных Novelty в окне компонента Server Explorer.

Определение индексов и первичного ключа

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

Если вы поняли, какая польза от применения индексов в структуре базы данных, у вас может возникнуть вопрос: если наличие индексов значительно ускоряет поиск, почему бы не создать индексы для каждого поля каждой таблицы? Ответ прост: индексы — это не только плюс, но и минус. При увеличении количества индексов физически увеличивается размер базы данных, а значит, и объем занимаемой памяти и дискового пространства, в результате чего компьютер работает медленнее. В этом случае польза от применения индексов сводится к нулю. Не существует жесткого правила насчет оптимального количества индексов для каждой таблицы, но основная рекомендация состоит в создании индексов только по таким полям, которые, по вашему мнению, будут чаще всего использованы в запросах. (За дополнительной информацией о том, как использовать содержимое поля в качестве критерия запроса для выборки наборов записей, обращайтесь к главе 2, "Запросы и команды на языке SQL".)

Первичный ключ (primary key) – это специальный тип индекса. Поле, которое определено в качестве первичного ключа таблицы, служит для уникальной идентификации записей. Поэтому, в отличие от других типов индексов, никакие две записи в одной и той же таблице не могут иметь одинакового значения в поле их первичного ключа. Кроме того, при определении поля в качестве первичного ключа никакие две записи в этом поле не могут содержать пустое или неопределенное значение (null). Определив некоторое поле таблицы как первичный ключ, вы можете создать в своей базе данных отношения между этой и другими таблицами.

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

Попробуем создать еще два индекса для полей FirstName и LastName, для этого выполните перечисленные ниже действия.

1. Щелкните правой кнопкой мыши на окне с определением таблицы tblCustomer в окне компонента Server Explorer и выберите в контекстном меню команду Indexes/Keys.

2. После этого на экране появится страница свойств со списком существующих индексов, в котором уже присутствует индекс первичного ключа PK_tblCustomer. Щелкните на кнопке New (Создать) для создания нового индекса для поля FirstName.

3. В списке полей выберите поле FirstName, как показано на рис. 1.3, а затем щелкните на кнопке Close.

4. Повторите действия из пп. 1-3, чтобы создать индекс для поля FirstName.

ВНИМАНИЕ!

В нижней части диалогового окна Property Pages находится параметр Create UNIQUE (Создать уникальный индекс). Не устанавливайте флажок для этого параметра, потому что в таком случае в таблицу можно будет вводить только разные имена клиентов! Уникальные индексы следует создавать только для того, чтобы гарантировать уникальность значений данного поля.

РИС. 1.3. Диалоговое окно Property Pages после определения индекса для поля FirstName


5. Для сохранения внесенных изменений в базу данных выберите команду меню File→Save tblCustomer (Файл→Сохранить таблицу tblCustomer). После успешного сохранения внесенных изменений закройте окно создания схемы базы данных Visual Studio .NET.

Создав структуру данных для таблицы, можно приступить к вводу данных в нее. В окне Server Explorer предусмотрены удобные средства ввода данных в таблицу. Для этого нужно щелкнуть правой кнопкой мыши на таблице в окне Server Explorer и выбрать из контекстного меню команду Retrieve Data from Table (Извлечь данные из таблицы). В результате в окне Server Explorer появится сетка с полями ввода данных (рис. 1.4).

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

Получив эти базовые знания о создании таблицы с помощью Visual Studio .NET, вы сможете создавать базы данных практически любого вида. Однако для создания сложных баз данных с несколькими таблицами часто требуется установить отношения (связи) между ними. Чтобы упростить эту задачу, используется схема базы данных.

Создание схемы базы данных

Схема базы данных (database diagram) – это визуальное представление таблиц в базе данных. Для создания таблиц и отношений между ними можно использовать инструменты создания схемы баз данных, которые предусмотрены в SQL Server. А для создания схемы баз данных с помощью окна Server Explorer среды Visual Studio .NET выполните перечисленные ниже действия. 

РИС. 1.4. Ввод данных в таблицу с помощью команды контекстного меню Retrieve Data from Table


1. Разверните узел базы данных Novelty в окне Server Explorer, щелкните правой кнопкой мыши на узле Database Diagrams и выберите в контекстном меню команду New Diagram (Создать схему).

2. В диалоговом окне Add Table (Добавить таблицу) будет приведен список таблиц базы данных. Выберите созданную ранее таблицу tblCustomer, щелкните на кнопке Add (Добавить), а затем на кнопке Close.

3. В результате будет создана новая схема базы данных с таблицей tblCustomer (рис. 1.5).

4. Для добавления второй таблицы в эту схему щелкните правой кнопкой мыши на пустом пространстве возле таблицы tblCustomer и выберите в контекстном меню команду New Table (Создать таблицу).

5. На экране появится диалоговое окно Choose Name, в которое следует ввести имя новой таблицы tblOrder.

6. После этого в окне схемы появится сетка для определения полей новой таблицы. Создайте в ней поля, показанные на рис. 1.6.

7. Выберите команду меню File→Save для сохранения схемы базы данных, и на экране появится диалоговое окно с просьбой подтвердить создание новой таблицы. Щелкните на кнопке Yes, и в окне Server Explorer появится вновь созданная таблица. 

РИС. 1.5. Схема базы данных Novelty, которая содержит все таблицы, выбранные в диалоговом окне Add Table

РИС. 1.6. Схема базы данных Novelty, которая содержит все таблицы, выбранные в диалоговом окне Add Table


После создания таблиц для клиентов и заказов следует установить связь (отношение) между ними. Например, при создании заказа идентификатор клиента ID из таблицы tblCustomer копируется из записи клиента в поле CustomerID таблицы tblOrder. Для указания этого отношения между таблицами на схеме базы данных выполните перечисленные ниже действия.

1. Щелкните на поле ID в таблице tblCustomer и перетащите его к полю CustomerID таблицы tblOrder.

2. На экране появится диалоговое окно Create Relationship (Создать отношение), в котором можно указать свойства отношения между двумя таблицами. После этого уже нельзя создавать заказы для клиентов с идентификаторами, которых нет в таблице клиентов. Это ограничение имеет большое практическое значение и потому с ним следует согласиться.

3. Схема базы данных обновляется для отражения нового отношения, как показано на рис. 1.7.

РИС. 1.7. Схема базы данных с обозначением отношения между табл tblCustomer и tblOrder


Для сохранения созданной схемы базы данных DatabaseDiagram1 выберите команду File→Save DatabaseDiagram1. В диалоговом окне Save New Database Diagram (Сохранить имя новой схемы базы данных) введите имя Relationships (Отношения) для новой схемы базы данных. При этом возможно появление диалогового окна с просьбой подтвердить создание новой таблицы. Щелкните на кнопке Yes для сохранения вновь созданной таблицы tblOrder.

SQL Server может сохранять схему базы данных вместе с самой базой данных. Таким образом, всегда можно получить доступ к схеме, даже с помощью других инструментов, например с помощью программы Enterprise Manager или среды Visual Studio .NET.

Использование программы Microsoft Visio для просмотра и изменения схемы базы данных

Помимо инструментов среды Visual Studio .NET, для создания, просмотра и изменения схем базы данных могут использоваться другие очень удобные средства. Программа Microsoft Visio обладает всеми необходимыми возможностями автоматического создания схемы для уже имеющейся базы данных, т.е. реинжиниринга базы данных. Эта функциональная возможность особенно полезна для работы с унаследованными базами данных, которые создавались очень давно и с использованием совсем других инструментов.

НА 3AMETKУ

Для создания базы данных SQL Server совсем необязательно знать особенности работы с программой Visio. Это всего лишь еще один способ создания и документирования схемы базы с помощью одного набора операций. Если вы предпочитаете использовать компонент Server Explorer среды Visual Studio (или инструмент Enterprise Manager) либо у вас нет программы Visio, то в таком случае можно пропустить данный раздел без ущерба для понимания остального материала.

Реинжиниринг (reverse engineering) базы данных заключается в проверке схемы существующей базы данных и создании диаграммы отношений между объектами базы данных (Entity Relationship Diagram – ERD). ERD-диаграмма — это способ символьного представления базы данных, основанный на широких категориях данных, или сущностях (entities), которые обычно хранятся в базе данных в виде таблиц.

Для реинжиниринга схемы базы данных с помощью программы Visio выполните перечисленные ниже действия.

1. Запустите программу Microsoft Visio 2002 for Enterprise Architects, выбрав команду Start→Programs→Microsoft Visio. В панели Choose Drawing Type (Выбрать тип рисования) выберите категорию Database (База данных).

2. Затем в панели Template (Шаблон) выберите параметр Database Model Diagram (Схема базы данных), и на экране появится основное окно программы Visio (рис. 1.8).

3. Выберите команду меню Database→Reverse Engineer (База данных→Реинжиниринг) для запуска программы-мастера Reverse Engineer Wizard.

4. Из списка Installed Visio drivers (Инсталлированные драйверы Visio) выберите драйвер Microsoft SQL Server.

5. Затем нужно определить источник данных, который позволит получить доступ к базе данных Novelty. Для этого щелкните на кнопке New.

6. На экране появится диалоговое окно Create New Data Source (Создать новый источник данных) с предложением указать тип создаваемого источника данных.

Выберите источник данных System Data Source и щелкните на кнопке Next. 

РИС. 1.8. Основное окно программы Visio: слева показан шаблон, а справа – область рисования. Элементы схемы создаются с помощью перетаскивания элементов шаблона в область рисования


7. В следующем окне снова предлагается выбрать драйвер базы данных. Прокрутите список драйверов и выберите SQL Server. Щелкните на кнопке Next, a затем на кнопке Finish.

8. На экране появится новое диалоговое окно Create a New Data Source to SQL Server (Создать новый источник данных для SQL Server) с предложением указать источник данных. Введите имя базы данных Novelty в поле Name, а затем в списке с надписью Which SQL Server do you want to connect to? (К какому серверу SQL Server нужно присоединиться?) выберите После этого щелкните на кнопке Next.

9. Укажите режим аутентификации на сервере SQL Server. (Более подробно этот вопрос рассматривается в главе 3, "Знакомство с SQL Server Затем щелкните на кнопке Next.

10. В следующем диалоговом окне установите флажок Change the default database to: (Заменить используемую по умолчанию базу данных:) и выберите в списке базу данных Novelty. Щелкните на кнопке Next, а затем на кнопке Finish.

 11. В последнем диалоговом окне ODBC Microsoft SQL Server Setup (Установки параметров драйвера ODBC Microsoft SQL Server) можно протестировать соединение с базой данных с помощью известных параметров соединения. Щелкните на кнопке Test Data Source (Проверка источника данных), чтобы убедиться в работоспособности соединения. После успешной проверки соединения щелкните на кнопке OK.

12. После этого источник данных Novelty будет автоматически выбран и представлен в диалоговом окне программы-мастера Reverse Engineer Wizard. Дважды щелкните на кнопке Next, чтобы пропустить экран для выбора типов объекта.

13. На следующем экране выберите таблицы tblCustomer и tblOrder для выполнения реинжиниринга. Затем щелкните на кнопке Finish. После этого программа Visio самостоятельно создаст схему вашей базы данных, включая отношение междуопределенными ранее таблицами tblCustomer и tblOrder (рис. 1.9).

РИС. 1.9. Схема, созданная с помощью программы-мастера Reverse Engineer Wizard, с двумя таблицами базы данных Novelty и отношениями между ними


В результате такого трудоемкого и рутинного процесса программа-мастер Reverse Engineer Wizard устраняет необходимость использования отдельной программы-мастера для создания источника данных ODBC – устаревшей технологии компании Microsoft, предназначенной для обеспечения взаимодействия приложений с реляционными базами данных. (Более подробно технология ODBC описывалась в прежнем издании книги, но она не очень широко используется в среде Visual Studio .NET, а потому эта тема опущена в данном издании.)

Важной особенностью технологии ODBC является то, что после создания именованного источника данных ODBC его не нужно создавать повторно. Для следующих попыток доступа к базе данных Novelty используется уже созданный источник данных ODBC.

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

1. В окне Entity Relationship (Отношения между объектами) в левой части окна программы Visio щелкните на компоненте Entity (Объект) и перетащите его в область рисования. При этом будет создан новый объект (таблица), который по умолчанию называется Table 1.

2. Щелкните правой кнопкой мыши на созданном объекте и выберите в контекстном меню команду Database Properties (Свойства базы данных). На экране появится страница свойств базы данных Database Properties.

3. Введите новое имя таблицы tblRegion в текстовом поле Physical name (Физическое имя).

4. В списке Categories (Категории) страницы свойств базы данных Database Properties щелкните на категории Columns (Поля) и создайте три поля в сетке с определением таблицы, как показано на рис. 1.10. Обратите внимание, что для длины поля типа char или varchar нужно выбрать поле и щелкнуть на кнопке Edit (Редактировать) с правой стороны страницы свойств.

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

НА ЗАМЕТКУ

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

Между таблицами tblRegion и tblCustomer существует отношение на основе связи между их полями State. Для отражения этого отношения в схеме нужно использовать компонент Relationship так, как описано ниже. 

РИС. 1.10. ERD-диаграмма с определением новой таблицы tblRegion


1. В окне Entity Relationship (Отношения между объектами) в левой части окна программы Visio щелкните на компоненте Relationship и перетащите его в область рисования. Он представляет собой линию со стрелкой и с зелеными квадратиками (метка-манипулятор) на концах линии.

2. Щелкните и перетащите одну из зеленых меток на таблицу tblRegion. При этом цвет метки станет красным, что означает незавершенность выполняемых действий с данным отношением.

3. Щелкните и перетащите другую зеленую метку на таблицу tblCustomer.

4. В странице свойств в нижней части окна Visio выберите поля State в обеих таблицах, а затем щелкните на кнопке Associate (Связать). Теперь ERD-диаграмма будет выглядеть, как показано на рис. 1.11. Обратите внимание, что кнопка между двумя списками полей из таблиц tblRegion и tblCustomer либо будет неактивной, либо будет содержать надпись Disconnect (Разорвать) или Associate (Связать). Например при выборе по одному полю в каждом списке эта кнопка будет иметь надпись Associate.

Рис. 1.11. ERD-диаграмма с отображением отношения между таблицами tblCustomer и tbIOrder


После создания таблицы в схеме базы данных можно использовать программу Visio для создания таблицы в базе данных. Для этого нужно выбрать команду меню Database→Update (База данных→Обновить). На экране появится диалоговое окно программы-мастера Database Update Wizard с предложением выполнить обновление. Для обновления базы данных можно создать сценарий на языке определения данных (Data Definition Language — DDL), который внесет все необходимые изменения в базу данных. Этот способ позволяет задокументировать все вносимые изменения и использовать их для репликации. (Более подробно DDL рассматривается в главе 2, "Запросы и команды на языке SQL".) Для обновления базы данных программа Visio может просто внести их в базу данных без создания сценария на DDL. Программа-мастер Database Update Wizard позволяет использовать любой из этих вариантов либо оба вместе.

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

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

tblOrderItem
ID
OrderID
ItemID
Quantity
Cost

Теперь между таблицами tblOrder и tblOrderItem существует отношение типа один-ко-многим, как показано на рис. 1.12.

Полностью схему всей базы данных Novelty можно скопировать в виде файла для программы Visio с Web-страницы этой книги на Web-сервере Издательского дома "Вильяме" по адресу: www.williamspublishng.com.

НА ЗАМЕТКУ

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

Отношения

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

РИС. 1.12. Схема базы данных с отношениями между четырьмя таблицами


Полями, создающими отношение, являются первичный ключ (представленный выше в этой главе) и внешний (foreign) ключ. Внешний ключ — это ключ в связанной таблице, который хранит копию первичного ключа из основной таблицы.

Предположим, у вас есть таблицы с характеристиками отделов и сотрудников компании. Отношение между отделом и группой сотрудников можно определить типом один-ко-многим. Каждому отделу присваивается собственный идентификационный номер (ID), и каждый сотрудник имеет свой ID. Но, чтобы указать, в каком отделе работает каждый сотрудник, необходимо сделать копию номера ID отдела в каждой записи, содержащей данные о сотруднике. Итак, чтобы идентифицировать каждого сотрудника как члена некоторого отдела, в таблице Employees (Сотрудники) должно быть предусмотрено поле (именуемое, допустим, Department ID) для хранения ID отдела, в котором работает данный сотрудник. Поле Department ID в таблице Employees служит внешним ключом таблицы Employees, поскольку хранит копию первичного ключа таблицы Departments (Отделы).

Благодаря отношению процессор баз данных "знает", какие две таблицы участвуют в этом отношении и какой внешний ключ связан с первичным ключом. Для прежнего процессора Jet базы данных Access явное объявление отношений не обязательно, но это в ваших же интересах, поскольку при таком объявлении упрощается задача выборки данных из записей двух или нескольких связанных таблиц (подробнее об этом в главе 2, "Запросы и команды на языке SQL"). Отсутствие такого объявления – один из основных недостатков технологии Jet, который можно устранить с помощью переноса унаследованных приложений на основе технологии Jet на платформу ADO.NET. Помимо соответствия связанных записей в отдельных таблицах, отношение определяется для того, чтобы воспользоваться преимуществами ссылочной целостности, под которой понимают свойство процессора базы данных, обеспечивающее непротиворечивость информации, хранимой в многотабличной базе данных. Когда ссылочная целостность имеет место в базе данных, то процессор баз данных препятствует удалению записи в случае, если в базе данных существуют другие записи, связанные с ней.

После того как вы определите отношение в базе данных, это определение сохраняется до тех пор, пока вы не удалите его. Отношения можно создавать графически, используя инструменты Visual Studio .NET, SQL Enterprise Manager, Visio, или с помощью сценариев на языке DDL.

Использование ссылочной целостности для поддержания непротиворечивости данных

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

Допустим, у вас есть таблицы tblCustomer и tblOrder. Эти две таблицы связаны через общее поле ID.

Предполагается, что сначала вы регистрируете клиентов в таблице tblCustomer, а затем создаете записи с информацией о заказах в таблице tblOrder. Но что произойдет, если запустить процесс, удаляющий запись с данными о клиенте, который оформил заказы, зарегистрированные в таблице tblOrder? А если создать заказ, для которого не существует действительного значения поля CustomerID? Любой заказ без значения поля CustomerID не будет отгружен, поскольку адрес отгрузки представляет собой функцию от записи в таблице tblCustomer. Когда данные в связанных таблицах страдают от такого рода проблемы, их называют несогласованными или противоречивыми.

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

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

Проверка ограничений ссылочной целостности с помощью Server Explorer

Для проверки отношения между таблицами tblCustomer и tblOrder попробуем использовать окно Server Explorer среды Visual Studio .NET. Для этого выполните перечисленные ниже действия.

1. Откройте схему базы данных Novelty с двумя таблицами- tblCustomer и tblOrder. Обратите внимание на то, что эта схема содержит и другие таблицы, но в данном случае нас интересует отношение между этими таблицами.

2. Щелкните правой кнопкой мыши на линии отношения между двумя этими таблицами и из контекстного меню выберите команду Property Pages.

3. После появления на экране страницы свойств данного отношения выберите вкладку Relationships, в которой указаны поле ID таблицы tblCustomer, поле CustomerID таблицы tblOrder и ограничения ссылочной целостности в нижней части.

НА ЗАМЕТКУ

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

4. Установите флажок Enforce Relationship for INSERTS and UPDATES (Применять каскадное обновление и удаление), а затем щелкните на кнопке Close.

5. Для сохранения внесенных изменений выберите команду File→Save Relationships.

Для проверки заданного ограничения выполните перечисленные ниже действия.

1. В окне Server Explorer щелкните правой кнопкой мыши на таблице tblOrder и выберите из контекстного меню команду Retrieve Data from Table.

2. Введите заказ для клиента идентификатором которого на самом деле нет в таблице с данными о клиентах.

3. Перейдите в другую строку для автоматического сохранения введенного заказа.

В результате на экране появится диалоговое окно с предупреждением: INSERT statement conflicted with COLUMN FOREIGN KEY constraint ' FK_tblOrder_tblCustomer'. Conflict occurred in database 'Novelty', table 'tblCustomer', column 'ID'. The statement has been terminated. (Команда INSERT конфликтует с ОГРАНИЧЕНИЕМ ПО ВНЕШНЕМУ КЛЮЧУ 'FK_tblOrder_tblCustomer'. Конфликт произошел в базе данных 'Novelty', таблице 'tblCustomer', поле 'ID'. Выполнение команды прекращено.)

4. Щелкните на кнопке OK в окне с предупреждением и отмените команду вставки новой записи с помощью клавиши <Esc>.

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

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

Каскадные обновления и каскадные удаления

Каскадные обновления и каскадные удаления – весьма полезные свойства процессора баз данных SQL Server. И вот почему.

Каскадные обновления. При изменении значения первичного ключа таблицы связанные данные во внешних ключах, относящихся к этой таблице, также изменяются, отражая изменения в первичном ключе. Следовательно, если вы измените идентификатор ID клиента Хокки Марта (Hockey Mart) в таблице tblCustomer с 48 на 72, то значение поля CustomerID всех заказов, сгенерированных этим Хокки Мартом в таблице tblOrder, автоматически изменится с 48 на 72. В рабочем приложении редко приходится изменять значения ключа (основная концепция заключается в том, что ключ должен быть уникальным и неизменным), но если это все-таки приходится делать, то все каскадные обновления этого ключа во внешних ключах будут выполнены автоматически.

Каскадные удаления. При удалении записи в таблице все записи, связанные с этой записью в соответствующих таблицах, автоматически удаляются. Следовательно, если вы удалите запись для Хокки Марта в таблице tblCustomer, все записи в таблице tblOrder для клиента Хокки Марта автоматически удаляются.

НА ЗАМЕТКУ

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

Каскадные обновления и удаления работают только в том случае, если вы установили отношение между двумя таблицами. Если вы всегда создаете таблицы с первичным ключом типа AutoNumber (Счетчик), (или первичными ключами типа AutoIncrement в терминах SQL Server), то каскадные удаления для вас окажутся более полезными, чем каскадные обновления, поскольку вы не в силах изменить значение поля типа AutoNumber или поля AutoIncrement (т.е. нет обновлений – нечего и тиражировать).

Для проверки возможностей каскадного удаления с помощью окна Server Explorer выполните перечисленные ниже действия.

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

2. Создайте запись о новом клиенте, щелкнув правой кнопкой мыши на таблице tblCustomer узла Tables в окне Server Explorer, выбрав в контекстном меню команду Retrieve Data from Table и введя необходимые данные. Запомните идентификатор ID, присвоенный процессором базы данных новому клиенту, потому что он потребуется для создания заказов данного клиента. Пусть эта таблица остается открытой, потому что она нам еще понадобится чуть позже.

3. Откройте таблицу tblOrder и создайте 2-3 заказа для нового клиента. Для этого укажите в поле CustomerID идентификатор ID, присвоенный процессором базы данных новому клиенту. Пусть эта таблица также остается открытой.

4. Вернитесь к таблице tblCustomer и попытайтесь удалить запись с данными этого клиента, щелкнув правой кнопкой мыши на левом конце записи и выбрав из контекстного меню команду Delete.

5. После этого на экране появится диалоговое окно с предупреждением и просьбой подтвердить удаление данных. Щелкните на кнопке Yes.

6. Вернитесь к таблице tblOrder, и вы обнаружите, что заказы этого клиента не удалены. Что произошло? На самом деле они удалены, но дают устаревшее представление данных. Для его обновления нужно выбрать команду меню Query→Run (Запрос1→Запуск). После этого вид таблицы будет обновлен и связанные заказы данного клиента будут удалены благодаря параметрам каскадного удаления.

Нормализация

Нормализация — это тесно связанное с отношениями понятие, которое означает устранение противоречий и повышение эффективности базы данных.

Базы данных считаются противоречивыми, если данные одной таблицы не соответствуют данным другой. Например, если ряд ваших сотрудников считают, что Арканзас находится на западе, а остальные — что на юге, при этом те и другие выполняют ввод данных, опираясь только на свои знания, то отчеты о состоянии дел на западе будут недостоверными.

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

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

НА ЗАМЕТКУ

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

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

tblCustomer
ID
FirstName
LastName
Address
Company
City
State
PostalCode
Phone
Fax
Email
Region  

Эта структура первоначально может показаться рациональной, однако посмотрим, что произойдет, если кто-нибудь постарается ввести данные в приложение, основанное на этой таблице.

Если бы вы вводили обычную информацию о клиенте - имя, адрес и т.д., то после ввода названия штата вам бы пришлось задуматься, чтобы определить регион проживания данного клиента. Где же находится этот Арканзас – на западе или на юге? Где находится клиент с Виргинских островов? Если существует большая вероятность ошибки, то такого рода решения не стоит оставлять в руках операторов, занимающихся вводом данных, даже несмотря на их высокую квалификацию. Если же полагаться только на человеческую память, то рано или поздно ваши данные станут противоречивыми. А чтобы защитить данные от противоречивости, и следует обращаться к нормализации.

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


tblRegion
ID
State
 Region

Данные в этой таблице выглядели бы следующим образом:  ...




Все права на текст принадлежат автору: Джеффри П Мак-Манус, Джеки Голдштейн, Кевин Т Прайс.
Это короткий фрагмент для ознакомления с книгой.
Обработка баз данных на Visual Basic®.NETДжеффри П Мак-Манус
Джеки Голдштейн
Кевин Т Прайс