Глава 3. Структура таблиц приложения
В соответствии с постановкой задачи построим следующие таблицы:
Таблица Поставщик
Поле | Тип данных | Описание |
Код_поставщика | Счетчик | Порядковый номер поставщика (первичный ключ). |
ФИО_поставщика | Текстовый | Имя поставщика или название фирмы. |
Адрес | Текстовый | Адрес или банковский счет. |
Таблица Сотрудники
Поле | Тип данных | Описание |
Код_сотрудника | Числовой (дл.целое) | Табельный номер сотрудника (первичный ключ). Используется числовой тип (а не счетчик), чтобы можно было вводить конкретное значение. |
ФИО_сотрудника | Текстовый | Имя сотрудника. |
Адрес | Текстовый | Адрес сотрудника. |
Дата_рождения | Дата/время | Дата рождения сотрудника. |
Стаж | Числовой (байт) | Стаж работы сотрудника |
Разряд | Числовой (байт) | Квалификационный разряд сотрудника. |
Фото | Поле объекта OLE | Используется для ввода/вывода фотографии сотрудника на форме или в отчете. |
Таблица Категория товара
Поле | Тип данных | Описание |
Код_категории | Счетчик | Порядковый номер категории товара (первичный ключ). |
Наименование_кат | Текстовый | Наименование категории товара. |
Таблица Товары
Поле | Тип данных | Описание |
Код_товара | Счетчик | Порядковый номер товара (первичный ключ). |
Категория_товара | Числовой (длинное целое) | Поле внешнего ключа для связи с таблицей Категория товара. |
Наименование | Текстовый | Наименование товара. |
Кол_во_упак | Числовой (целое) | Количество упаковок (ящиков, коробок, мешков и т.д.). Если товар не пакуется, то вводится количество единиц товара |
Кол_во_в_упак | Числовой (целое) | Количество товара в одной упаковке. Если товар не пакуется, то вводится «1». |
Цена_опт | Денежный | Оптовая цена единицы товара (цена поставщика). |
Цена_розн | Денежный | Розничная цена единицы товара (цена, по которой товар продается). |
Срок_годн | Дата/время | Дата предельного срока реализации товара. Используется для контроля истечения срока реализации. |
Дата_поступления | Дата/время | Дата приема товара. |
Возврат | Логический | Определяет возможность возврата остатков непроданного товара по истечении срока реализации. Используется при подсчете прибыли и убытков. |
Поставщик | Числовой (длинное целое) | Поле внешнего ключа для связи с таблицей Поставщик. |
Сотрудник | Числовой (длинное целое) | Поле внешнего ключа для связи с таблицей Сотрудник. |
Таблица Магазины
Поле | Тип данных | Описание |
Код_магазина | Текстовый | Номер магазина (первичный ключ). |
Название | Текстовый | Название магазина. |
Адрес | Текстовый | Адрес магазина. |
ФИО_директора | Текстовый | Имя директора. |
Телефон | Текстовый | Номер контактного телефона. |
Таблица Продажи
Поле | Тип данных | Описание |
Код | Счетчик | Идентификатор записи о продаже товара (первичный ключ). |
Товар | Числовой (длинное целое) | Поле внешнего ключа для связи с таблицей Товары. |
Прод_возвр | Текстовый | Отметка о том, был ли продан («Пр»), возвращен («Вт») или списан («Сп») товар. Удобно вводить информацию в поля, которые имеют ограниченный набор значений, используя список или поле со списком. |
Количество | Числовой (целое) | Количество проданных единиц товара. |
Дата_продажи | Дата/время | Дата продажи. |
Магазин | Текстовый | Код магазина, в котором был продан данный товар. Это поле внешнего ключа для связи с таблицей Магазины. |
![]() |
На рисунке на примере поля Прод_возвр показано применение поля со списком с целью упрощения ввода информации в данное поле таблицы Продажи. Этот элемент управления будет использоваться для ввода данных непосредственно в таблицу, а также по умолчанию на форме, если для построения последней использовать один из мастеров. При этом элементами списка являются введенные в строку Источник строк значения, которые перечисляются через точку с запятой. Если свойство Ограничиться списком имеет значение «Да», то нельзя будет ввести никакие другие значения кроме перечисленных. В противном случае («Нет») допускается ввод и других значений, совместимых с типом поля. (Чего-то не хватает)Подробнее об элементе управления Поле со списком смотри в разделе 2.5, где изложено применение элементов управления на формах. Заметим, что если источником строк являются текстовые константы, то они заключаются в двойные кавычки.
Связи между таблицами, обеспечивающие ссылочную целостность данных, наглядно представлены на схеме данных (команда меню Сервис)
![]() |
Все таблицы базы данных нормализованы и находятся в 3НФ (третья нормальная форма). Это обусловлено тем, что каждая из таблиц имеет простой первичный ключ (т.е. ключ, состоящий из одного поля), и все неключевые поля зависят только от этого ключа.
Здесь уместно обсудить характер ключевого поля. В таблицах Магазин и Сотрудник используется так называемый естественный ключ, т.е. столбец, несущий информацию, обусловленную спецификой предметной области. Например, поле Код_магазина в таблице Магазин имеет смысл номера магазина. Этот номер может официально быть присвоен магазину и фигурировать во всех регистрационных документах. Поле первичного ключа Код_сотрудника в таблице Сотрудник может содержать уникальный идентификатор типа ИНН или номера страхового свидетельства и, соответственно, нести дополнительно определенную информационную нагрузку.
Ключи другого типа обычно называют синтетическими. Синтетический ключ не несет смысловой информации предметной области, а служит лишь для обеспечения уникальности записей в таблице. Неслучайно для таких полей мы использовали тип данных Счетчик, который автоматически генерирует произвольные уникальные значения.
Возникает вопрос: зачем нужен такой ключ? Чтобы на него ответить, нужно рассмотреть ситуацию, когда такого поля совсем не будет в таблице. Согласно реляционной теории, каждая запись в таблице должна быть уникальна, т.е. у нас должен быть способ отличить одну запись от другой. Справедливости ради следует сказать, что реализации (и, в частности, язык SQL) не требуют уникальности записей в таблице, однако, для обеспечения ссылочной целостности поле в главной таблице, участвующей в связи, должно быть уникальным. Таким образом, синтетический ключ необходим, если в таблице без него возможны одинаковые записи. Например, для таблицы Продажи возможна ситуация, когда несколько раз в день фиксируется продажа в одинаковом количестве одного и того же товара в одном и том же магазине.
Для таблицы Товары имеет место другая ситуация. Здесь все записи будут различаться, т.к. даже если один и тот же товар поставляет один и тот же поставщик, то дата поставки будет уже другая. Таким образом, здесь в качестве естественного ключа следовало бы выбрать все множество полей, потому что только такая комбинация значений гарантированно будет уникальной. В результате, для того, чтобы установить связь с таблицей Продажи, нам пришлось бы все эти поля дублировать в таблице Продажи. В этом случае проще добавить синтетический ключ – Код_товара, который и будет использоваться для поддержания ссылочной целостности. Кроме того, это существенно упростит написание запросов, в которых потребуется соединять эти две таблицы. Заметим, что в силу уникальности Код_товара будет различаться даже для одного и того же товара, поставка которого осуществлялась в разные дни. Это дает нам возможность отслеживать периодичность поставок одного и того же товара и динамику изменения его цены.
В таблицу Категория товара синтетический ключ добавлен для удобства, т.к. проще использовать для связи числовое поле (длинное целое – 4 байта), чем текстовое поле (по одному или двум байтам на каждый символ в названии). Здесь, в принципе, хватило бы и типа целое (2 байта), однако, использование счетчика избавляет нас от контроля ввода уникальных значений при добавлении новой категории товара.
Честно говоря, мы погрешили против истины, утверждая, что все таблицы имеют простой ключ, от которого зависят все остальные неключевые атрибуты. Это не вполне справедливо для таблиц Магазины и Сотрудник. Дело в том, что эти таблицы содержат несколько потенциальных ключей. В частности, у таблицы Магазины, помимо ключа Код_магазина, может быть еще один потенциальный ключ, состоящий из пары полей {Название, Адрес}. Тем самым мы полагаем, что по одному и тому же адресу не может быть двух магазинов с одним и тем же названием. По отдельности ни одно их этих полей не может обеспечить уникальности записи, т.к. в одном здании может размещаться несколько магазинов, да и названия зачастую повторяются. Здесь, как и в случае с таблицей Товары, наличие синтетического ключа упрощает связи и написание запросов.
Связь с таблицами из внешнего источника и импорт объектов базы данных
Итак, мы создали структуру реляционной базы данных. Пусть файл, содержащий описанные выше таблицы, называется Tables_2003.mdb. Создадим теперь новую базу данных, которую назовем Firma.mdb. Эта база данных будет содержать все остальные объекты (запросы, формы, отчеты, макросы, модули) – все, за исключением таблиц. Если одни и те же данные используются для работы нескольких приложений, установленных на разных компьютерах в сети, необходимо файл с данными (у нас это Tables_2003.mdb) поместить на один из компьютеров сети (так называемый файловый сервер). Тогда файл Firma.mdb и/или другие приложения можно разместить на любых компьютерах в сети.
В том случае, если файл приложения содержит таблицы, для перемещения последних в другой файл можно воспользоваться мастером разделения базы данных. В этом случае нужно выполнить команду Сервис\Служебные программы\Разделение баз данных.
![]() |
С таблицами, находящимися во внешнем файле, можно создать связь. Это дает возможность работать с данными так, как будто они находятся локально. Таким образом, нам не придется при обращении к данным из связанных таблиц указывать имя файла и путь к нему. Для установления связи с таблицами воспользуемся командой Внешние данные\Связь с таблицами… в меню Файл, после чего в появившемся на экране окне проводника найдем и выделим файл и нажмем кнопку Связь. Следующим шагом является выбор необходимых таблиц. Чтобы выбрать все таблицы, можно нажать кнопку Выделить все. Операция завершается нажатием кнопки ОК.
![]() |
На рисунке видно, что можно устанавливать связь не со всеми таблицами файла, а лишь с теми, которые необходимы для работы данного приложения.
ПримечаниеОбратите внимание на символ стрелки слева от имени таблицы в окне базы данных. Этот символ говорит о том, что таблицы хранятся в другом файле, а в данной базе данных с ними установлена связь. База данных может содержать как связанные таблицы, так и локальные, т.е. находящиеся в том же самом файле. Разница в работе с присоединенными таблицами, по сравнению с локальными, состоит лишь в том, что изменение структуры и свойств возможно только для локальных таблиц Поэтому для изменения свойств присоединенной таблицы необходимо предварительно открыть файл, фактически содержащий эту таблицу.
Связь с таблицами нарушится, если файл, содержащий таблицы, будет переименован или перемещен в другую папку или на другой компьютер. В этом случае можно, конечно, повторить описанную выше операцию, предварительно удалив связанные таблицы из базы данных. Заметим, что удалить любой объект базы данных можно, выделив его и нажав кнопку Delete на клавиатуре. Однако есть полезная утилита, которая называется диспетчером связанных таблиц. Эта программа позволяет восстановить потерянные связи. Чтобы воспользоваться этой утилитой, нужно выполнить команду Сервис\Служебные программы\Диспетчер связанных таблиц. При этом на экране появится следующее окно.
![]() |
Теперь нужно выделить те таблицы, связь с которыми требуется восстановить, и нажать кнопку ОК. Если местоположение таблиц изменилось или вы хотите установить связи с таблицами из другого файла, перед нажатием кнопки ОК включите флажок Всегда выдавать запрос нового местонахождения. В этом случае Вы сможете в появившемся окне проводника указать требуемый файл с таблицами; иначе программа попытается переустановить указанные в окне связи, и окно проводника появится только в том случае, если файл или нужная таблица не будут обнаружены.
Описанную выше операцию чаще всего приходится выполнять при переносе приложения с одного компьютера на другой. Заметим, однако, что если местоположение таблиц относительно данного приложения при этом не меняется, переустанавливать связи не придется.
Подобно связыванию таблиц можно выполнить операцию импортирования. При этом в текущей базе данных создается копия объекта из другой базы данных. Импортировать можно любые объекты базы данных, а не только таблицы. Чтобы импортировать объекты, следует:
1. Выполнить команду Файл\Внешние данные\Импорт…2. Выбрать файл, содержащий необходимые объекты и нажать кнопку Импорт.3. Выбрать вкладку (Формы, Запросы и т.д.) в окне базы данных и выделить нужные объекты; для выделения всех объектов на вкладке можно нажать кнопку Выделить все.4. Повторить предыдущий пункт для каждой требуемой вкладки.5. Нажать кнопку ОК.ВниманиеЕсли имя импортируемого объекта совпадет с именем имеющегося, то к имени первого будет добавлена цифра 1 (или 2, если объект с тем же именем и цифрой 1 уже имеется в базе данных, и т.д.)