Помощь Выход

Глава 3. Структура таблиц приложения

В соответствии с постановкой задачи построим следующие таблицы:

Таблица Поставщик

ПолеТип данныхОписание
Код_поставщикаСчетчикПорядковый номер поставщика (первичный ключ).
ФИО_поставщикаТекстовыйИмя поставщика или название фирмы.
АдресТекстовыйАдрес или банковский счет.

Таблица Сотрудники

ПолеТип данныхОписание
Код_сотрудникаЧисловой (дл.целое)Табельный номер сотрудника (первичный ключ). Используется числовой тип (а не счетчик), чтобы можно было вводить конкретное значение.
ФИО_сотрудникаТекстовыйИмя сотрудника.
АдресТекстовыйАдрес сотрудника.
Дата_рожденияДата/времяДата рождения сотрудника.
СтажЧисловой (байт)Стаж работы сотрудника
РазрядЧисловой (байт)Квалификационный разряд сотрудника.
ФотоПоле объекта OLEИспользуется для ввода/вывода фотографии сотрудника на форме или в отчете.

Таблица Категория товара

ПолеТип данныхОписание
Код_категорииСчетчикПорядковый номер категории товара (первичный ключ).
Наименование_катТекстовыйНаименование категории товара.

Таблица Товары

ПолеТип данныхОписание
Код_товараСчетчикПорядковый номер товара (первичный ключ).
Категория_товараЧисловой (длинное целое)Поле внешнего ключа для связи с таблицей Категория товара.
НаименованиеТекстовыйНаименование товара.
Кол_во_упакЧисловой (целое)Количество упаковок (ящиков, коробок, мешков и т.д.). Если товар не пакуется, то вводится количество единиц товара
Кол_во_в_упакЧисловой (целое)Количество товара в одной упаковке. Если товар не пакуется, то вводится «1».
Цена_оптДенежныйОптовая цена единицы товара (цена поставщика).
Цена_рознДенежныйРозничная цена единицы товара (цена, по которой товар продается).
Срок_годнДата/времяДата предельного срока реализации товара. Используется для контроля истечения срока реализации.
Дата_поступленияДата/времяДата приема товара.
ВозвратЛогическийОпределяет возможность возврата остатков непроданного товара по истечении срока реализации. Используется при подсчете прибыли и убытков.
ПоставщикЧисловой (длинное целое)Поле внешнего ключа для связи с таблицей Поставщик.
СотрудникЧисловой (длинное целое)Поле внешнего ключа для связи с таблицей Сотрудник.

Таблица Магазины

ПолеТип данныхОписание
Код_магазинаТекстовыйНомер магазина (первичный ключ).
НазваниеТекстовыйНазвание магазина.
АдресТекстовыйАдрес магазина.
ФИО_директораТекстовыйИмя директора.
ТелефонТекстовыйНомер контактного телефона.

Таблица Продажи

ПолеТип данныхОписание
КодСчетчикИдентификатор записи о продаже товара (первичный ключ).
ТоварЧисловой (длинное целое)Поле внешнего ключа для связи с таблицей Товары.
Прод_возврТекстовыйОтметка о том, был ли продан («Пр»), возвращен («Вт») или списан («Сп») товар. Удобно вводить информацию в поля, которые имеют ограниченный набор значений, используя список или поле со списком.
КоличествоЧисловой (целое)Количество проданных единиц товара.
Дата_продажиДата/времяДата продажи.
МагазинТекстовыйКод магазина, в котором был продан данный товар. Это поле внешнего ключа для связи с таблицей Магазины.

На рисунке на примере поля Прод_возвр показано применение поля со списком с целью упрощения ввода информации в данное поле таблицы Продажи. Этот элемент управления будет использоваться для ввода данных непосредственно в таблицу, а также по умолчанию на форме, если для построения последней использовать один из мастеров. При этом элементами списка являются введенные в строку Источник строк значения, которые перечисляются через точку с запятой. Если свойство Ограничиться списком имеет значение «Да», то нельзя будет ввести никакие другие значения кроме перечисленных. В противном случае («Нет») допускается ввод и других значений, совместимых с типом поля. (Чего-то не хватает)Подробнее об элементе управления Поле со списком смотри в разделе 2.5, где изложено применение элементов управления на формах. Заметим, что если источником строк являются текстовые константы, то они заключаются в двойные кавычки.

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

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

Здесь уместно обсудить характер ключевого поля. В таблицах Магазин и Сотрудник используется так называемый естественный ключ, т.е. столбец, несущий информацию, обусловленную спецификой предметной области. Например, поле Код_магазина в таблице Магазин имеет смысл номера магазина. Этот номер может официально быть присвоен магазину и фигурировать во всех регистрационных документах. Поле первичного ключа Код_сотрудника в таблице Сотрудник может содержать уникальный идентификатор типа ИНН или номера страхового свидетельства и, соответственно, нести дополнительно определенную информационную нагрузку.

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

Возникает вопрос: зачем нужен такой ключ? Чтобы на него ответить, нужно рассмотреть ситуацию, когда такого поля совсем не будет в таблице. Согласно реляционной теории, каждая запись в таблице должна быть уникальна, т.е. у нас должен быть способ отличить одну запись от другой. Справедливости ради следует сказать, что реализации (и, в частности, язык SQL) не требуют уникальности записей в таблице, однако, для обеспечения ссылочной целостности поле в главной таблице, участвующей в связи, должно быть уникальным. Таким образом, синтетический ключ необходим, если в таблице без него возможны одинаковые записи. Например, для таблицы Продажи возможна ситуация, когда несколько раз в день фиксируется продажа в одинаковом количестве одного и того же товара в одном и том же магазине.

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

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

Честно говоря, мы погрешили против истины, утверждая, что все таблицы имеют простой ключ, от которого зависят все остальные неключевые атрибуты. Это не вполне справедливо для таблиц Магазины и Сотрудник. Дело в том, что эти таблицы содержат несколько потенциальных ключей. В частности, у таблицы Магазины, помимо ключа Код_магазина, может быть еще один потенциальный ключ, состоящий из пары полей {Название, Адрес}. Тем самым мы полагаем, что по одному и тому же адресу не может быть двух магазинов с одним и тем же названием. По отдельности ни одно их этих полей не может обеспечить уникальности записи, т.к. в одном здании может размещаться несколько магазинов, да и названия зачастую повторяются. Здесь, как и в случае с таблицей Товары, наличие синтетического ключа упрощает связи и написание запросов.


Сказанное, ни в коей мере не отменяет утверждение о нахождении всех таблиц в 3НФ, однако, мы не будем углубляться в теорию нормализации и рассматривать нормальные формы более высоких порядков [2, 3].

Связь с таблицами из внешнего источника и импорт объектов базы данных

Итак, мы создали структуру реляционной базы данных. Пусть файл, содержащий описанные выше таблицы, называется Tables_2003.mdb. Создадим теперь новую базу данных, которую назовем Firma.mdb. Эта база данных будет содержать все остальные объекты (запросы, формы, отчеты, макросы, модули) – все, за исключением таблиц. Если одни и те же данные используются для работы нескольких приложений, установленных на разных компьютерах в сети, необходимо файл с данными (у нас это Tables_2003.mdb) поместить на один из компьютеров сети (так называемый файловый сервер). Тогда файл Firma.mdb и/или другие приложения можно разместить на любых компьютерах в сети.

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

С таблицами, находящимися во внешнем файле, можно создать связь. Это дает возможность работать с данными так, как будто они находятся локально. Таким образом, нам не придется при обращении к данным из связанных таблиц указывать имя файла и путь к нему. Для установления связи с таблицами воспользуемся командой Внешние данные\Связь с таблицами… в меню Файл, после чего в появившемся на экране окне проводника найдем и выделим файл и нажмем кнопку Связь. Следующим шагом является выбор необходимых таблиц. Чтобы выбрать все таблицы, можно нажать кнопку Выделить все. Операция завершается нажатием кнопки ОК.

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


Примечание

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

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

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

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

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


1. Выполнить команду Файл\Внешние данные\Импорт…
2. Выбрать файл, содержащий необходимые объекты и нажать кнопку Импорт.
3. Выбрать вкладку (Формы, Запросы и т.д.) в окне базы данных и выделить нужные объекты; для выделения всех объектов на вкладке можно нажать кнопку Выделить все.
4. Повторить предыдущий пункт для каждой требуемой вкладки.
5. Нажать кнопку ОК.
Внимание
Если имя импортируемого объекта совпадет с именем имеющегося, то к имени первого будет добавлена цифра 1 (или 2, если объект с тем же именем и цифрой 1 уже имеется в базе данных, и т.д.)