РАБОТАЕМ С ДАННЫМИ | КОМПЬЮТЕРНАЯ ГАЗЕТА
Про деление и размножение Как я уже говорил, истинный уровень мастерства в той или иной области, как правило, выясняется задолго до того, как это самое мастерство можно будет проявить во всей красе и блеске. Это как, например, профессиональный охотник по одному только виду и содержимому рюкзака в сочетании с выбором оружия и прочей амуниции может сказать кто перед ним: матерый волчара или начитавшийся охотничьих журналов дилетант, отродясь не выбиравшийся далее, чем на сто шагов от околицы. (c) Компьютерная газета | В области прикладного программирования также существует масса тонкостей, отличающих опытного разработчика от начинающего программиста. Как-то принято считать, что если ты не самый распоследний ас, значит мнение твое десятое и дальше прихожей заходить даже не думай. А между тем практика показывает, что столь "высокая" оценка возможностей "истинных профессионалов", как это говорится, "несколько преувеличена". Во всяком случае такой вывод следует после более близкого знакомства с большинством прикладных пакетов, типа СУБД Microsoft Access 97. На три четверти весь реализованный в них инструментарий рассчитан на человека, не слишком хорошо владеющего программированием, не обремененного большим опытом разработок аналогичных приложений и частенько допускающего ошибки на начальном этапе проектирования, которые вынужден корректировать уже в процессе разработки, а то и вообще отладки. Хочу заметить, речь идет именно о любителе, так как профессионалы, как правило, набивают руку и, приступая к определенному проекту, действуют по некоторой собственной схеме, обычно достаточно оптимальной. Впрочем, это вовсе не означает, что хорошую базу данных может написать полный дебил. Опыт, знания и способности - вещи, без которых окружающий нас мир не стал бы таким, каким стал. Тем не менее разработчики Microsoft Access 97 изначально исходили из того факта, что в процессе отладки у разработчика возникнет потребность кардинальной переработки определенной таблицы. Сама по себе эта проблема не была бы такой сложной, если бы не одно обстоятельство: обычно, к этапу отладки таблицы уже заполнены фактическими данными, которые не хотелось бы терять. В то же время процедура копирования данных из одной таблицы в другую требует либо разработки специального запроса-действия, либо достаточно обременительной ручной работы, способной отнять много времени. Такая ситуация возникает в том случае, когда первоначально созданная длинная таблица оказывается "загруженной" явно неравномерно: данные из одних полей используются чуть ли ни при каждом пользовательском "чихе", в то время как обращение к другим полям происходит почти что эпизодически, в крайне редких случаях. Эта проблема не была бы столь уж сложной, если бы не чисто технические тонкости. К чему бы вы ни обращались, к одному полю или к полному их перечню, в оперативную память загружается вся таблица полностью и хранится там до тех пор, пока либо вся база данных не будет закрыта, либо какой-нибудь специальный модуль не очистит память конкретно от данной таблицы. Потом, при осуществлении выборок любого рода СУБД Microsoft Access 97 все равно перебирает все поля таблицы, следовательно, чем полей больше, тем запрос работает медленнее. По своду законов Мерфи такая проблема имеет противное свойство проявляться лишь тогда, когда таблица набита данными да еще весь проект давно уже сдан заказчику и каждый огрех виден ему как на ладони. В общем, на этапе отладки нелишне заново распечатать определители каждой таблицы и проанализировать количество обращений к полям каждой из них. Как только обозначится бросающийся в глаза перекос между популярностью разных полей одной и той же таблицы - самое время воспользоваться процедурой, называющейся расщеплением, при помощи которой любую таблицу можно достаточно просто разделить на две и более отдельные таблицы с сохранением данных в соответствующих полях. На практике это весьма и весьма удобно. Предположим следующую ситуацию. В нашем воображаемом книжном магазине (если вы еще не забыли о чем речь) оказалось, что в разрабатываемой базе данных есть таблица "Литература" (см. рис. 1), содержащая восемь полей: Код книги, Рубрика, Наименование, Автор, Издательство, Место печати, Тираж, Стоимость. Однако практика показывает, что основная часть запросов базы данных "интересуется" лишь шестью из них, оставляя почти без внимания поля " Место печати" и " Тираж". Я прекрасно понимаю, что в реальных условиях такая вводная меня бы не заставила перепроектировать данную таблицу, но давайте не будет цепляться к мелочам. В реальной жизни подобная таблица может содержать двадцать полей, из которых явно второстепенными может оказаться добрый десяток из них, в то время как сама процедура расщепления, что для таблицы из примера, что для настоящей таблицы, остается одинаковой. Самый простой и удобный способ расщепления длинной таблицы, как мне кажется, состоит в том, чтобы создать копию текущего проекта, а потом из нее "перебросить" в оригинал все то, что нужно. Как правило, это оказывается однозначно быстрее, чем при помощи любого другого приема. Поэтому начать следует с того, что, закрыв текущий проект СУБД, надо перейти в Проводник Microsoft Windows 95.98 и куда-нибудь скопировать данную базу. С этого момента у вас есть две совершенно одинаковые базы, содержащие абсолютно идентичный набор данных. Теперь самое время взять из копии таблицу "Литература" и перебросить ее в базу-оригинал. Это делается при помощи механизма экспорта/импорта данных в Microsoft Access 97. Откройте оригинал базы данных и выберите режим ТАБЛИЦА в системном меню ВСТАВКА. Это вызовет на экран монитора окно специализированного мастера (см. рис. 2). Собственно говоря, это обычный мастер создания таблицы, только на этот раз нас должен интересовать всего один его режим, который стоит в списке предпоследним - Импорт таблиц, отвечающий как раз за процедуру обмена данными с внешними базами данных и приложениями, в том числе и сторонних организаций. Процедура импорта начинается с предложения пользователю определить тип импортированных данных (см. рис. 3). В левом нижнем углу окна мастера расположено поле со списком " Тип файлов", открыв которое, вы можете узнать, какие типы данных "ваш" Microsoft Access 97 поддерживает. Содержимое данного списка самым тесным образом зависит от того, поддержку каких данных вы "включали" при установке Microsoft Access 97 на ваш компьютер. Если интересующего вас типа в перечне нет, то стоит доустановить соответствующие модели с дистрибутива. В моем примере подобные опасения излишни, так как обычная копия базы данных Microsoft Access 97 также является базой данных в формате Microsoft Access 97, если только вы ничего не меняли в настройках. Далее стандартным для операционной системы Microsoft Windows 95/98 образом нужно найти упомянутую выше копию текущей базы, выбрать ее маркером мыши или клавишами и нажать экранную кнопку " ОК". Компьютер автоматически откроет выделенную базу, найдет в ней все таблицы и их перечень выведет на экран (см. рис. 4). Вам останется лишь выделить нужную таблицу и опять "сказать" " ОК". В зависимости от размеров таблицы и мощности вашего компьютера, очень быстро или вообще мгновенно все лишние окна с экрана исчезнут, а вставленная таблица появится в соответствующем перечне базы данных оригинала. Причем, прошу заметить, что Microsoft Access 97 корректно выявил факт совпадения имен уже имеющейся в базе и импортируемой таблиц, а потому видоизменил наименование импортируемой таблицы, прибавив к ее имени цифру "1". Остаются мелочи. Сначала в таблице "Литература1" удалим в режиме конструктора все поля за исключением " Код книги", " Место печати" и " Тираж". Результат сохраним. Аналогичным образом откроем таблицу " Литература" и удалим из нее поля " Место печати" и " Тираж". Результат также сохраним. Все, процедура расщепления завершена. В случае необходимости таблицу "Литература1" можно переименовать во что-нибудь более благозвучно-информативное, а копию базы за ненадобностью вообще удалить. Теперь рассмотрим нюансы, без которых не обходится ни одно серьезное дело. Если расщепляемая таблица участвует в каких-либо связях, то перед расщеплением "лишние" связи следует удалить. Как правило, лучше всего удалить лишь те связи, которые в основной таблице подлежат удалению, в противном случае Microsoft Access 97 будет долго и витиевато "ругаться умными словами", мешая вам работать. Кстати, после расщепления новая таблица пока нигде и никак не участвует, ее также придется индивидуально "подключать" к существующей в этой базе паутине связей. Потом, непременно следует просмотреть ВСЕ поля данной таблицы (как той, что остается под своим именем, так и той, которую вы импортировали) на предмет наличия каких-нибудь специальных условий. К примеру, если в одном из полей в качестве ограничения любого рода используются данные из другого поля этой же таблицы, то Microsoft Access 97 ни за что не даст вам сохранить результат, если это самое "другое" поле "попадет под нож". Перед сохранением СУБД производит проверку всех оставшихся полей таблицы на корректность, и в случае отсутствия таковой таблицу попросту не сохранит. Аналогичным образом следует просмотреть все формы и запросы, каким-либо образом касающиеся той таблицы, которая подверглась расщеплению. Вероятнее всего, в некоторых из них придется поменять наименование таблицы-источника данных, ибо без корректив они либо станут безбожно врать, либо вообще откажутся функционировать. Процедура обратная расщеплению называется объединением. Ее разработчики также предусмотрели в Microsoft Access 97, так как, кроме нерадивых новичков, в жизни слишком часто встречаются новички чрезмерно упорные, начитавшиеся "умных" книг, чтобы заранее ознакомиться с полным перечнем чужих ошибок в надежде не совершить их самим. Обычно эти люди слишком усердно нормализуют базу и получают в результате массу коротких таблиц, постоянно используемых совместно. Перебор в данном случае также плох, как и недобор, так как каждая таблица в памяти компьютера описывается некоторым набором параметров, требующих некоторых системных ресурсов. Если таблиц много, то велик и перерасход вычислительной мощности на их обслуживание. После того как база в общем и целом собрана и даже относительно успешно проходит тестирование, можно, по аналогии с расщеплением, просмотреть перечень таблиц, соотнести его с перечнем существующих форм и запросов и выявить постоянные зависимости, то есть те таблицы, которые наиболее часто в одних и тех же запросах используются единовременно. Это говорит о двух вещах: во-первых, данная база является перенормализованной, а во-вторых, указанные таблицы нуждаются в объединении. На этот раз придется воспользоваться запросом-действием. Начать следует с того, что, запустив конструктор запросов, "сказать" ему " СОЗДАТЬ", указав вариант " Конструктор". На экране появится пустой бланк запроса и дополнительное окно со списком всех таблиц базы данных для указания тех, поля которых данным запросом будут использоваться. Но в принципе все равно, как сказал кто-то из романистов, "что камнем по сове, что совой об камень". В качестве базовой таблицы можно выбрать сначала "Литература", а потом добавить в бланк "Литература1", можно наоборот - на конечный результат сие не влияет. Самым рациональным мне представляется вставить в бланк сразу обе таблицы. Далее, в строке " Поле" бланка запросов потребуется поочередно открывать в каждой ячейке выпадающий список и выбирать в нем по очереди нужные поля. Только следите за тем, чтобы в один бланк не попали одновременно поля " Код книги", одноименные в обеих таблицах. Как вы знаете, поле "типа счетчик" в любой таблице может быть только одно, все равно, что капитан на корабле. Когда с самим бланком покончено, надобно изменить характер запроса, так как по умолчанию изначально Microsoft Access 97 генерирует запрос-выборку. Если навести маркер на верхнюю часть бланка запроса и нажатием правой клавиши мыши вызвать контекстнозависимое меню, то среди всего прочего там найдется интересующий нас режим "ТИП ЗАПРОСА". Его активизация приводит к появлению автоматически раскрывающегося списка со всеми возможными вариантами (см. рис. 5), из которых нас интересует только один, а именно - "СОЗДАНИЕ ТАБЛИЦЫ". Как только вы его выберите, на экране монитора появится окно диалога (см. рис. 6), в котором программа предложит вам набрать имя той таблицы, которая будет создана в результате выполнения данного запроса. Полученный запрос можно сохранять под каким-либо именем. Вы имеете также право перед этим переключиться в режим таблицы и посмотреть, что получится в результате. Если запрос тестирование "не пройдет", еще не поздно подправить те моменты, которые вам не понравятся. А вот когда запрос сохранен и закрыт, он становится похож на снаряженную гранату, требующую обходительного обращения. В режиме конструктора такой запрос можно открывать в любое удобное время и делать с ним все, что заблагорассудится. Ничего страшного не произойдет. Но любая попытка сразу открыть запрос в режиме таблицы неминуемо приведет к его выполнению, а значит - к созданию новой таблицы. Правда, перед тем как вновь сгенерированная согласно инструкциям таблица окажется сохраненной на диске, Microsoft Access 97 сначала выведет на экран информационное окно, в котором предупредит о сути своей работы (см. рис. 7), а потом - о количестве записей, которые будут перенесены во вновь созданную результирующую таблицу (см. рис. 8). Если исходные таблицы, полями которых данный запрос манипулирует, только что созданы и фактической информации пока не содержат, то, как это видно из рис. 8, новая таблица все равно будет создана, но самих записей в них не появится, так как их не было в исходных таблицах. Если возникает подозрение, что либо вы, либо компьютер что-то напутали с конструированием запроса и процесс пошел "как-то не так", на любом из этапов присутствует экранная кнопка " ОТМЕНИТЬ", при помощи которой процесс разрешается прервать без каких-либо неприятных последствий. В результате работы созданного нами запроса-действия появится новая таблица с тем именем, которое вы задали на этапе проектирования запроса, и с соответствующим содержанием. Просто, быстро и удобно. Александр Запольскис E-mail: leshy@nestor.minsk.by