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

Эффективное обращение к наборам данных

Удаленные данные представляют собой данные на основе их наборов; вы можете обращаться к данным, выбрав набор данных из большого из количества с помощью предложений SELECT - SQL. Наиболее значимым различием между разработкой традиционного локального приложения и разработкой клиент-серверного приложения заключается в противоположности между традиционными методами навигации Visual FoxPro и методами обращения к основанных на наборах серверных данных.

Использование традиционных методов навигации

В традиционном программировании локальной базы данных, вы можете обращаться к конкретным и часто большим объемам данных с помощью команд GOTO BOTTOM, which you then query against. Вы можете перемещаться по данным, создав временные отношения между двумя таблицами с помощью команды SET RELATION и, затем, выдав команду SKIP для перемещения по связанным записям.

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

Использование параметризированных запросов

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

Вы не должны использовать команду GOTO BOTTOM для удаленных серверных данных по приведенным ниже причинам:

  • чрезмерная и не являющаяся необходимой нагрузка на сеть из-за загрузки огромных объемов данных;

  • уменьшение производительности приложения из-за обработки данных, которые не требуются в данный момент времени;

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

Например, если вы желаете создать клиент/серверное приложение, которое обращается к заказам конкретного потребителя, создайте удаленное представление, которое будет обращаться к таблице Customer. Создайте второе удаленное представление, которое будет обращаться к таблице Orders, но сделайте его параметризированный на основе поля cust_id. Затем используйте текущую запись потребителя в качестве параметра для представления, обращающегося к таблице Orders.

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

Выбор наилучшего дизайна для клиент/серверного приложения

Приведенные ниже примеры описывают - как достичь преимуществ технологии клиент/сервер и избежать просчетов при скромных методиках программирования. Первый метод использует традиционную практику программирования для извлечения всех данных из удаленного источника данных в локальные курсоры, которые затем связываются отношениями с помощью команды SET RELATION. Второй, третий и четвертый методы перенимают прогрессивно развитые методики извлечения данных, эффективно ограничивая количество сгружаемых данны по технологии just-in-time (как раз вовремя), которая обеспечивает свежесть данных и быстрое время ответа в сети.

Использование неоптимизированной стратегии клиент/сервер

Непосредственное, неоптимизируемое приложение использует метод навигации по локальным данным с удаленными данными. Например, если у вас имеется 10 миллионов записей потребителей и 100 миллионов записей заказов на удаленном источнике данных, вы можете создать совершенно неэффективное приложение, которое сгрузит все записи из таблиц Customer и Order в локальные курсоры. Затем  вы должны индексировать 100 миллионов записей заказов, создать временные отношения межде таблицами Customer и Orders в ваших локальных курсорах и использовать команду SKIP для навигации по записям.

Такой метод не оптимизирован по производительности, однако, может быть полезен в случае, если только сторона "one" отношения типа "one-to-many" - локальная,  а сторона "many" является удаленной.

Фильтрация на стороне "Many"

Немного улучшенное приложение клиент/сервер ограничивает сторону отношения "many", но извлекает все записи на стороне "one", для того, чтобы вы могли перемещаться по записям. В этом сценарии, вы создаете удаленное представление стороны отношения "many", таблицу Orders, параметризированную по идентификатору потребителя ID. Затем вы сгружаете таблицу Customer целиком.

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

Фильтрация на стороне "One"

Лучший метод клиент/серверного программрования создает удаленные представления для всех удаленных данных. Вы ограничиваете число записей Customer, загружаемых в удаленное представление таблицы Customer, используя в представлении предложение SELECT, выбирающее потребителей только из одного региона. Затем вы создаете удаленное представление стороны отношения "many", таблицы Orders, параметризированное по идентификатору потребителя ID.

Такой сценарий извлевает совсем небольшой набор записей. Вы используете команду SKIP для перемещения на стороне отношения "one" (представление Customer). Вы используете функцию REQUERY( ) для обращения к новым данным на стороне отношения "many" (Orders).

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

Использование первичного ключа для обращения к отношению "One-to-Many"

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

Например, вы можете создать форму для отношения "one-to-many" в которой информация о потребителе формируется на стороне отношения "one", а элемент управления Grid отображает сторону отношения "many". Элемент управления Grid может быть связан с идентификатором потребителя ID, выбранного в форме на стороне отношения "one". Вы можете, затем установить свойство MaxRecords функции CURSORSETPROP() в 1 и использовать приведенный ниже код для заполнения в форме стороны отношения "one":

 CopyCode imageСкопировать код
SELECT * FROM customer WHERE customer.cust_id = ?cCust_id

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

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

Такой метод рекомендуется, когда вы желаете часто обращаться к отношению "one-to-many" с помощью значения первичного ключа. Вы можете пожелать сгрузить первичные ключи в элемент управления типа выпадающего списка, при открытии формы и затем предоставить пользователю элемент управления, с помощью которого он сможет выбрать когда выwhen you open the form and then provide a control that the user can choose to refresh the list of primary key values on demand.

Использование Data Environment в клиент/серверных приложениях

Если вы используете в формах удаленные данные, включите в окружение данных формы (DataEnvironment) представления. Вы можете установить свойство AutoOpenTables для DataEnvironment в false (.F.), для того, чтобы вы смогли указать, когда приложение будет заполнять представления новыми удаленными данными. Устанавливайте свойство ControlSource элементов управления, таких как textbox или иных, привязанных к данным после того, как вы вызовите OpenTables для DataEnvironment, что обычно делается в коде, связанном с событием Init формы. Для получения более подробной информации смотрите Создание форм.

Смотрите также