Showing posts with label oltp. Show all posts
Showing posts with label oltp. Show all posts

Friday, March 14, 2008

SAP BW: Муки рождения

Часто от многих людей можно слышать один и тот же вопрос: "Зачем SAP нужно было создавать с нуля систему хранилищ данных и весь инструментарий Business Intelligence, когда на рынке уже существовали производители, предлагающие целый ряд сложившихся продуктов такого класса?" Ответить на это будет довольно просто, если мы сначала взглянем на историю развития SAP в области отчетности, анализа и управления данными. На самом деле, у SAP уже существовали наработки, частично или полностью реализующие такую функциональность в составе системы R/3. И если мы проследим эволюцию этих инструментов, то поймем, что решение о создании отдельного продукта было принято не за один день.

Началось все с разработки внутри R/3 так называемого слоя информационных систем - уровня абстракции, который позволял упростить создание различных отчетов на базе OLTP данных. Этот уровень абстракции появился в R/3 очень давно - еще с версии 2.0 (напомню, что текущая версия 7.10). Однако проблема состояла в том, что реализация слоя информационных систем очень разнилась в различных частях системы. Например, Информационная система логистики (Logistics Information System, LIS) имела один набор инструментов доступа к данным, называемый standard and flexible analysis, в то время как Информационная система персонала (Human Resources Information System, HRIS) имела совсем другой набор инструментов, реализованный с помощью отчетов. Разработка каждой из этих частей системы велась отдельной командой. И хотя такая узкая специализация позволяла создавать более продуманные решения с точки зрения разработки, разность подходов создавала довольно большие проблемы в процессе внедрения.

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

Первая разработка, созданная SAP целенаправленно в области OLAP, называлась аналитический процессор (research processor). В начале 90-х этот инструмент использовался в подмодуле Анализ прибыльности модуля Контроллинг (Controlling Profitability Analysis, CO-PA). Аналитический процессор позволял создавать многомерные отчеты по прибыльности и организовывать просмотр таких отчетов на различных уровнях агрегации. Этот инструмент существует в R/3 и поныне, нося название сквозная отчетность (Drill-Down Reporting). Повсеместному распространению возможностей сквозной отчетности внутри R/3 способствовал постоянно растущий спрос на многомерную отчетность со стороны пользователей системы.

Итак, в определенный момент SAP осознала ситуацию, в которой оказалась. С одной стороны, компания уже обладала рядом очень мощных аналитических инструментов, реализованных в R/3. С другой стороны, существовала масса клиентов, которым были остро необходимы инструменты для анализа данных. На почве этого неудовлетворенного спроса процветал целый ряд производителей продуктов Business Intelligence, а SAP теряла клиентов, обладая при этом всеми компетенциями, необходимыми для создания полноценного решения в области хранилищ данных.

Результатом такой ситуации стало решение создать так называемый Аналитический сервер (Research Server), который позже и получил имя SAP Business Information Warehouse (SAP BW). (Кстати, думаю, многим консультантам SAP BW всегда было интересно, почему все, что связано с BW - транзакции, пакеты, функциональные модули и проч. - имеет префикс RS; так вот и ответ на этот вопрос). Эта инициатива стала самым крупным проектом разработки в истории SAP, не считая, конечно, системы R/3. В первой половине 1997 года SAP отобрала пять компаний-клиентов для проведения пилотных внедрений SAP BW. В начале 1998 года для дополнительного анализа технических требований и проверки продукта "в полевых условиях" среди уже шести клиентов была запущена так называемая Программа первых клиентов (Early Customer Program, ECP). Самой известной компанией, принявшей участие в этой программе, была корпорация DEC (Digital Equipment Corporation). В сентябре 1998 года SAP BW версии 1.2A стал доступен всем остальным клиентам. Вот таким образом и состоялось рождение BW.

Думаю, никогда при проектировании SAP BW не вставал вопрос использования какой-либо сторонней OLAP разработки. Скорей всего, без долгих колебаний было принято решение просто перенести целый ряд концепций из R/3 и воспользоваться существующим опытом. Двумя яркими примерами концепций BW, изначально реализованных в R/3 (имеются в виду именно концепции, а не сам программный код), могут стать система раннего предупреждения (Early Warning System) и интерфейс "отчет-отчет" (Report-to-Report Interface). Первая из этих концепций позволяет устанавливать пороговые значения или условия, при достижении которых система выдает сообщение с предупреждением. Например, такая возможность может использоваться для мониторинга состояния складских запасов. Пользователь устанавливает минимально допустимое количество единиц на складе и временной интервал, по которому система будет производить проверку. При достижении установленного порогового значения система автоматически уведомит ответственное лицо о том, что нужно отправить поставщику заказ для пополнения складских запасов.

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

Мы рассмотрели лишь две концепции, перенесенные из R/3 в BW. В действительности их намного больше. Выходит, что еще до создания BW, компания SAP имела многолетний опыт построения OLAP инструментов и решений для управления данными. И этот факт совершенно нельзя сбрасывать со счетов при рассмотрении SAP в качестве производителя продуктов Business Intelligence и систем хранилищ данных.

При подготовке материала использовались следующие источники:

  • K. McDonald, A. Wilmsmeier, D.C. Dixon, and W.H. Inmon. 2002. "Mastering the SAP Business Information Warehouse". Wiley Publishing, Inc.
  • N. Hashmi. 2000. "Business Information Warehouse for SAP - Your Guide to Data Warehousing and BW". Prima Publishing
  • help.sap.com

more >>

Sunday, February 24, 2008

Знакомьтесь, это - SAP BW, OLTP-система (проект РЖД №1: КАК+ПОЧЕМУ)

Здесь я продолжу рассмотрение одного проекта внедрения SAP в РЖД. Первую часть, описывающую суть поставленной задачи, смотрите здесь. Ну, а далее последует еще одна, завершающая часть цикла статей об этом проекте, где я покажу, что мог бы получить заказчик, если бы к проекту подошли с других позиций и пользовались подходящими технологиями.
Итак, система была реализована, как уже, наверно, ясно, на базе SAP BW. Был создан набор отчетов, запуская которые пользователь мог получить списки "подозрительных" вагонов. Отчеты брали информацию из хранилища данных BW. Чтобы от организаций в хранилище данных попадала информация о вагонах, был изготовлен web-интерфейс, в котором пользователь указывал имя файла с данными, нажимал кнопку "Обработать", и данные попадали в хранилище. Немногим сложнее устроен процесс работы с акцептами. Сначала пользователь должен сформировать отчет со списком "подозрительных вагонов", затем сохранить его где-нибудь у себя на компьютере и одновременно отослать организации. Потом, когда от организации придет ответ, нужно будет открыть сохраненный отчет, проставить в нем кое-где специальные отметки, и далее через web-интерфейс загрузить этот файл в хранилище. Все звучит просто и логично, не так ли?
Теперь приглядимся чуть внимательнее. Для начала рассмотрим ту часть получившейся системы, с которой уже непосредственно сталкивается заказчик. Что же он видит?

  • Тормозная и глюкавая загрузка. С глюками тут, конечно, вина самого SAP, ибо BW при определенном стечении обстоятельств (встречавшемся, тем не менее, довольно часто) просто "ломается", и пришлось даже описать "пляски с бубном" для обхода этой ситуации в инструкции пользователя. Но тут дело наживное - ошибку исправят и выпустят заплатку. А вот с тормозами принципиально уже ничего не изменится. В инструкции пользователя так и написано: загруженные данные появятся в системе в среднем через 10 минут; чтобы проверить, появились ли данные, запустите или обновите отчет. И вот, представляете, пользователь в течении 10 минут сидит перед открытым отчетом и кликает кнопку "Обновить". И ждет, пока что-то появится. А оно, ведь, может и не появиться. Например, очень часто при загрузке в BW возникают разные ошибки, и процесс загрузки не доходит до конца. Все, что может сделать в данной ситуации пользователь, - это пожаловаться: "Я делаю все, как написано, а файл не грузится". Ведь никто не станет отправлять его на курсы по администрированию BW или нанимать для этой цели специального человека.
  • Отчетный беспредел. В техническом задании были довольно четко расписаны все алгоритмы формирования отчетов. Но наивный заказчик не знал, что за инструмент будет выбран для реализации. Когда изготовили первые несколько отчетов, стали заметны некоторые хитрые вещи: то каких-то вагонов недосчитаются, то какие-то - лишние. Стали разбираться и в итоге выкатили несколько дополнительных проектных решений, которые предусматривали "расчленение" каждого отчета на 3 или даже на 5 подотчетов, имеющими между собой некоторые отличия. Проектные решения подписали и реализовали. Ну, я думаю, понятно, насколько быстрее работают сразу 5 отчетов вместо одного. И это при условии того, что и так каждый из них не быстр. Я лично замерял: был отчет, который открывался 23 минуты! Уже не говорю о том, что знать, как пользоваться всем этим лесом отчетов со всеми нюансами нужно было пользователям, у которых и без этой системы было полно других развлечений.
А сейчас взглянем, что же там в системе "под капотом".
  • Атака клонов. Множество почти одинаковых по настройкам, но, тем не менее, довольно существенно отличающихся по поведению отчетов. В итоге их развелось столько, что ни один консультант уже не был в состоянии удержать в голове, какой из них как работает и что конкретно делает. Для внесения правок в отчет, за который не брался всего несколько дней, приходилось разбираться каждый раз почти заново. Был выбран способ реализации, при котором часто стало невозможно пользоваться простым копированием отчетов. В результате нередко очередной отчет-клон необходимо было настраивать "с нуля". За счет OLAP-направленности отчетного движка каждый отчет требовал использования чудовищных по сложности условий, программирования виртуальных показателей и переменных, и еще черт знает чего. Когда к коллективу подключился человек, ранее не участвовавший в проекте, встала задача передать ему свои знания. По завершению последней беседы он с остекленевшим взглядом промолвил: "Да-а, ну, вы тут и навернули... Я, конечно, понимаю как это все круто, но зачем?!"
  • Жертва программирования. Именно так можно назвать систему, к которой так относятся, когда делают в ней кастомизации. Когда я изучал код коллег, я молчал. Когда я увидел, что написанный мною код довольно небрежно добавили кусок, я решил поинтересоваться: не замечает ли коллега, что правки немного неаккуратны? На это мне сказали, что переписывать ничего не будут, работы и так полно, а тот кусок работает в принципе правильно. Я понял, что мне можно лишь оставаться островком грамотного кода в океане пофигизма, и тем самым сохранить верность своим принципам и остаться честным перед заказчиком. Кстати, система, в которой велась разработка, использовалась другими субподрядчиками, и у меня были возможности увидеть их код. Следует отметить, что плохая ситуация там отнюдь не везде, большое количество кода было написано качественно. Видимо, поучаствовало немало профессиональных разработчиков.
  • Демоны-инвалиды. Для обработки данных, загружаемых пользователями, на стороне BW "крутятся" так называемые демоны - фоновые процессы, которые организуют прием данных и запись их в хранилище. Они являются частью новой подсистемы BW - real-time data acquisition (RDA). Не буду углубляться в технические детали, скажу лишь, что подсистема эта на поверку оказалась довольно капризной, и не такой уж real-time. Даже в спокойной обстановке своего офиса консультантам приходилось подолгу разбираться, "почему ни черта не грузится", что уж говорить о таких ответственных и нервных мероприятиях как тестирование или сдача в опытную эксплуатацию. В результате пришлось дойти до того, чтобы обычным пользователям дать доступ к административной части системы (которую, я считаю, они, вообще, не должны никогда видеть) и обучить заниматься вполне администраторскими задачами.
И последнее. Какие я вижу причины такого замечательного результата? Вот они:
  • BW - это OLTP-система. Звучит утрированно, но я лично видел на примере нескольких проектов, что многие даже не задумываются о природе BW. Не задумываются о том, что это хранилище данных, а не транзакционная (OLTP) система, не задумываются о том, в чем разница. Меня настолько удручает такая ситуация, что я решил вынести данное заблуждение в заголовок цикла статей. Возможно, с эти можно и поспорить, но я считаю, что отчетность на основе плоских массивов данных должна быть в BW явлением исключительным, маргинальным. То есть, такие отчеты имеют право на существование, но, скажем, в случаях, когда нужно "провалиться" из многомерного OLAP-отчета на детальный уровень. Например, находясь в отчете, отражающем месячную выручку по подразделениям, проверить проводки, составляющие сумму в конкретной ячейке отчета. Использование BW для создания целой системы плоских отчетов - это уже от лукавого.
    Ведь несмотря на то, что отчет строится на плоском массиве данных, сам подход к его настройке остается многомерным, то есть система составляет один запрос к таблицам, быть может, со множеством условий. Но это всего один запрос! И если у нас появляется необходимость с помощью отчета, по существу, соединять несколько независимых выборок данных или производить внутри массива данных какое-то подобие поиска, то придется применять некие "извращения". Например, накладывать дополнительные изощренные условия (что и было сделано в этом проекте), либо получать заведомо более раздутую выборку данных и с помощью самописных подпрограмм вычленять нужные данные. А смысл? Зачем тут, вообще, BW, если все равно программировать? Более того, такие приемы весьма существенно замедляют быстродействие, ведь тогда системе не дают воспользоваться ни специально разработанной для OLAP многомерной схемой "звезда", ни применить множество оптимизаций, которые оказываются бессильными в случаях применения условий или дополнительного программирования. Результат - тормоза и чудовищная сложность настройки.
  • BW - это генератор отчетов. "Раз BW умеет выгружать цифры в Excel, значит будем делать все отчеты в BW". Именно так думают многие "специалисты". Нет, и еще раз нет! Ведь, подумайте, что нужно сделать, чтобы вожделенный отчет "заработал в BW". Сначала нужно передать в BW все основные данные, то есть справочники, атрибуты и проч. Затем нужно передать в BW необходимые транзакционные данные. Для каждого из этих процессов, во-первых, нужно подготовить данные к отправке из исходной системы, а для этого нужны настройки и, часто, программирование. Во-вторых, при передаче в BW задействуется вся заложенная там махина ETL со множеством проверок, перекачек и служебных операций. В-третьих, процедуру закачки в BW надо будет проводить регулярно, чтобы отчеты отображали актуальную информацию. И, в завершение, нужно настроить OLAP-отчет, который будет отображать ваши не-OLAP данные. А это, как я уже говорил, значит, что будет программирование, замороченные настройки и тормоза. А что, если захочется еще иметь такую кнопочку, которая бы делала у нас системе то-то? Замечательно, тогда добавим сюда еще немного программирования, обратную выгрузку из BW (ретракцию) или межсистемное взаимодействие. То есть, в результате вместо, допустим, одного ABAP-отчета в R/3 вы получаете полноценное внедрение BW средней степени сложности. Весело? Мне - нет. И даже если это не один отчет, а несколько. Всегда нужно, прежде всего, смотреть на природу задачи, а уже потом выбирать инструмент. И я знаю, что это было сказано до меня, но это так. BW подходит для многомерного анализа данных. Это ваш случай?
  • Профессионалы-универсалы. Об этом явлении я уже говорил, посвятив ей отдельное эссе: Басня об "одном флаконе". Замечу, что я на этом проекте видел куски кода от таких "универсалов" и знаю, какие в них сидят ошибки и нерациональности, а также, как их можно было бы переработать. Но я не стал в них залезать, во-первых, потому что, мне дали ясно понять, как здесь относятся к проблеме качества кода, а во-вторых, просто-напросто мне нужно было успевать делать свою работу.
  • Любопытство. Или какие еще можно назвать причины, которые толкают почти каждого профессионала опробовать в действии в своей системе новую модную "мульку"? Под "мулькой" в данном случае я имею в виду real-time data acquisition (RDA) - новую технологию в BW, позволяющую "на лету" подкачивать пакеты данных из внешних систем. Технология эта призвана заменить довольно тяжеловесный процесс загрузки данных BW (длительность которого, к тому же, невозможно гарантированно предсказать) на облегченную процедуру в случаях, когда данные могут поступать регулярно и относительно небольшими порциями. Что ж, несмотря на используемое здесь словосочетание "на лету", RDA не подразумевает использования в режиме интерактива с пользователем. Основная цель этой технологии - сделать аналитическую отчетность, получаемую на базе данных из транзакционных систем, более оперативной; перейти от концепции "ночная загрузка данных" к концепции "данные в течение рабочего дня".
    Неявным, но от того не менее важным, тут является предположение, что данные получаются из надежных источников, целостность данных в которых подразумевается априори. Получаемые данные тогда будут, в основном, безошибочно ложиться на свои места в хранилище, может быть, только в исключительных случаях вызывая ошибки. У нас же в качестве внешних данных выступают файлы с выгрузками из негармонизированных, "недружелюбных" систем, которые содержат множество ошибок, неточностей и отклонений от формата.
    Ну, и наконец, технология RDA пока очень и очень молода, и еще не преодолела, как говорится, первую волну глюков. Это, к сожалению, отразилось на нашем проекте, а не должно было бы. Ведь везде, а в IT - так в особенности, профессионалы всегда должны сначала серьезно протестировать новинку, прежде чем предлагать ее клиенту. Это уже прописная истина.
  • Оставьте ваши притязанья. По моей информации, Микротесту "отдали" только делянку с BW. Всем, что касается R/3 и других систем, занимаются другие субподрядчики. А поэтому, даже если в Микротесте захотели бы реализовать этот функционал в R/3, им бы не дали этого сделать. Следовательно, в интересах самого же Микротеста было, ну, если не "впаривать", то строить все свои внедрения вокруг BW. Вот так. Системная архитектура системной архитектурой, а кушать хочется всегда. Рождения уродца было неизбежным, заказчик был обречен. Хочу заметить, что такой фатализм встречается на российском рынке системной интеграции очень часто. Именно поэтому я, все же, довольно мягко отношусь к использованным на этом проекте подходам, точнее к людям, которые их реализовали. В конце концов, выбора у них большого не было, а их работа стала результатом политических решений. А следовательно, вся команда Микротеста была изначально "запрограммирована" на использование BW. Правда, если бы выбор у них таки был, я не уверен, что не вступил бы в действие другой фактор: "BW-шники у нас простаивают, а ABAP-еров свободных нет", как я уже наблюдал впоследствии. Но об этом позже, и это уже совсем другая история.
Ждите продолжения в следующих постах. more >>

Sunday, January 27, 2008

Знакомьтесь, это - SAP BW, OLTP-система (проект РЖД №1: ЧТО)

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

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

На данный момент, у меня в голове находится концепция серии заметок, когда каждая из них будет отвечать на один из вопросов "ЧТО автоматизировалось", "КАК шло внедрение", "ПОЧЕМУ оно так шло" и "как было БЫ, если бы внедрение шло по-другому".

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

Итак, к первому ЧТО.

Задачка такая. РЖД. Вагоны регулярно отправляются в рейсы. Есть некий набор станций, на которых происходит передача вагонов от одной организации к другой. При передаче для каждого вагона составляется документ, в котором фиксируется номер вагона, а также дата и время его передачи. Каждая организация, и сдающая, и принимающая, составляет свой такой документ. В целом, организаций в процесс вовлечено много, и вагон в каждом рейсе может несколько раз передаваться между ними. А потом возникает вопрос, кто сколько должен РЖД за пользование вагоном. Плата рассчитывается на основе времени пробега. В установленные сроки все организации отсылают свои документы за прошедший отчетный период (месяц) в одно из расчетных подразделений РЖД, где и производится начисление. Технически документы организации за один отчетный период попадают в РЖД в электронном виде, грубо говоря, как массив данных вида вагон-период-дата-время.

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

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

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

Что же хотел заказчик от автоматизации? До внедрения несколько целых подразделений занимались перелопачиванием поистине гигантских объемов информации. За каждым компьютером сидел человек с двумя окнами Microsoft® Excel, в каждом из которых было открыто по массиву данных, и глазами искал "несходки". Иногда надо свериться с распечаткой, иногда - залезть в специализированную информационную систему РЖД. Хотелось, чтобы была создана система, умеющая формировать отчеты, в которые бы попадали "подозрительные" вагоны. Далее бы пользователи их бегло проверяли, возможно, удаляли бы из них "несправедливо оклеветанные" вагоны, и отправляли ли бы список прямиком виноватой организации. Те, в свою очередь, должны либо согласиться с претензиями (акцептовать), либо обосновать отказ от претензий, либо предложить свой вариант правды.

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

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

Читайте продолжение в следующем посте. Там я расскажу КАК было проведено внедрение.

more >>