Logo    
Деловая газета CitCity.ru CITKIT.ru - все об Open Source Форумы Все публикации Учебный центр Курилка
CitForum    CITForum на CD    Подписка на новости портала Море(!) аналитической информации! :: CITFORUM.RU
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

20.02.2017

Google
WWW CITForum.ru
С Новым годом!

Обзор статей журнала DataBase Programming & Design
vol.10, N 2, February 1997

www.dbpd.com

Support for Data Warehouses

Patrick O'Neil
Professor of Computer Science at the University of Massachusetts at Boston

www.cs.umb.edu/~poneil

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

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

В статье приводится введение в основные понятия эффективных методов индексации для поддержки приложений класса DSS (Decision Support System): битовые (bitmap) индексы и индексы соединений. Затем рассматриваются новые возможности индексации, внедренные в Informix Extended Parallel Server (XPS)

Битовые индексы похожи на традиционные индексы, основанные на списках идентификаторов строк (RID - Row Identifier). Но битовые индексы в некоторых случаях позволяют получить существенный выигрыш в производительности.

Начнем с определения списка RID. Каждой строке в таблице приписывается RID, который можно рассматривать как указатель на строку на диске. Обычно RID состоит из номера страницы на диске и номера позиции записи на этой странице. Набор строк с данным свойством может быть представлен как список RID этих строк. В большинстве СУБД используются 4-байтовые RID (хотя в Oracle RID имеет длину по крайней мере 6 байт). Традиционно списки RID использовались в индексах для определения набора строк, ассоциированных с каждым значением некоторого индексируемого столбца. Если предположить потребность в индексе на таблице SALES, содержащей 100 миллионов строк и включающей столбец department c 40 разными значениями, то для каждого значения этого столбца мы получим список RID, который в среднем будет соответствовать 2.5 миллионам строк.

При наличии громадного числа RID, ассоциированных с каждым значением department, трудно рассчитывать, что удастся целиком переместить список RID в основную память. Список разбивается на фрагменты по несколько сотен RID, которые могут быть помещены в последовательные листовые узлы B-дерева. Для каждого фрагмента можно хранить в B-дереве только одно значение department, так что критически остается лишь потребность в хранении 100 миллионов 4-байтовых RID.

Теперь мы готовы ввести идею битовой индексации. В таблице, для которой используется эта техника, все строки должны быть перенумерованы: 0, 1, 2, ..., N-1. Нумерация строк должна производиться в соответствии с порядком их RID (физически последовательно относительно расположения строк на диске). Требуется метод преобразования номера строки в RID и наоборот. Теперь, если имеется последовательность из N бит, установим k-тый бит в 1, если строка с номером k входит в набор строк, а в противном случае - в 0. Битовый индекс на SALES по столбцу department аналогичен тому, который основан на RID, но вместо фрагментов RID в нем используются соответствующие битовые фрагменты. Каждый битовый фрагмент будет занимать 12.5 Мб, так что вполне вероятно разместить его на последовательных страницах диска. Отношение числа битов, установленных в 1, к общей длине набора бит, называется плотностью этого набора и аналогична селективности условия выборки. Фрагменты с низкой плотностью можно компрессировать. Пока же будем считать, что все фрагменты обладают высокой плотностью.

В этом случае полный битовый индекс требует на листовом уровне чуть больше 500 Мб внешней памяти, т.е. больше, чем индекс, основанный на RID. Однако ситуация меняется, если индексируемый столбец содержит мало различных значений. Если, например, таблица SALES содержит столбец gender (пол) со всего двумя значениями M и F, то для листового уровня битового индекса потребуется всего 25 Мб, в то время как для RID-индекса по-прежнему было бы нужно иметь 400 Мб. Для индексов с менее чем 32 значениями битовые индексы позволяют экономить память.

Однако наиболее важным свойством неупакованных битовых индексов является не экономия памяти, а возможность существенно повысить скорость выполнения операций AND, OR, NOT и COUNT. Предположим, что имеются два битовых фрагмента B1 и B2, где B1 представляет свойство gender = 'M', а B2 - department = 'sports'. Тогда для получения битового фрагмента, соответствующего свойству B1 & B2, требуется всего лишь выполнить поразрядное логическое умножение B1 и B2.

Для выполнения операции AND над двумя списками RID требуется более сложная техника: слияние с пересечением. Нужно использовать два курсора, каждый из которых продвигается по одному из списков, и в результирующем списке остаются те RID, которые встречаются в каждом из исходных списков.

Конечно, если списки-операнды включают только по несколько десятков RID, то цикл со списками RID окажется более эффективным, чем цикл, в котором выполняется логическое умножение битовых шкал, длина каждой из которых равна общему числу строк в таблице. Но при плотности битовой шкалы большей, чем 1/100, алгоритм на основе битовых шкал работает быстрее. Аналогично обстоят дела с алгоритмами для выполнения операций OR, NOT и COUNT.

Если битовая шкала становится очень разреженной, то битовые индексы работают плохо по сравнению с RID-индексами не только в связи с нагрузкой на процессор, но и по причине большого числа обменов с внешней памятью. Для решения обеих проблем требуется какой-либо метод сжатия, который позволил бы сократить расходы внешней памяти, но в то же время позволил бы по-прежнему быстро выполнять операции AND, OR, NOT и COUNT. Один из подходов состоит в совместном использовании битовой и RID индексации: когда битовый фрагмент становится слишком разреженным, он заменяется на RID-фрагмент. В других подходах используется техника кодирования битовых шкал. В этом случае становится сложно эффективно выполнять перечисленные выше операции между сжатой и несжатой шкалами. Потребность нахождения техники сжатия, которая бы не тормозила выполнение этих операций является наиболее важной проблемой битовой индексации.

Операции соединения при выполнении SQL-запросов требуют больше всего ресурсов по сравнению с другими реляционными операциями. Производители СУБД реализовали несколько алгоритмов для эффективного выполнения соединений (соединения путем слияния - Merge Join, соединения на основе хэширования - Hash Join и т.д.). Однако появившийся в последнее время новый специализированный подход, называемый индексацией соединения, может обеспечить существенное ускорение многих запросов.

Индекс соединения обеспечивает средства, с помощью которых СУБД может эффективно транслировать ограничения на столбец одной таблицы в ограничения на другую таблицу путем стандартного соединения. Предположим, что мы имеем таблицу SALES, каждая строка которой является агрегацией данных о продажах конкретного продукта для конкретного заказчика в конкретный день (это называется грануляцией агрегации). SALES является таблицей фактов и соединяется с таблицами, представляющими три измерения,- CUSTOMER, PRODUCT и TIME через внешние ключи cid, pid и day. Предположим, что следующий запрос является распространенным:


(SEL1)



SELECT SUM(dollar_sales), SUM(unit_sales)

 FROM SALES s, CUSTOMERS c, PRODUCTS p, TIME t

 WHERE s.cid = c.cid AND s.pid = p.pid AND s.day = t.day

 AND t.month = 'May95' AND p.package_type = 'box'

  AND c.gender = 'M'

Желательно заранее иметь индексы для эффективного выполнения этого запроса. В этом запросе столбец gender принадлежит таблице CUSTOMER, но только столбцы таблицы SALES агрегированы; ограничение на gender кажется естественным выполнять после соединения. Но предположим, что производится некоторая предварительная подготовка, заключающаяся в соединении всех строк SALES со всеми соответствующими строками CUSTOMER (для каждой продажи имеется только один заказчик) и ограничим строки SALES условием, что заказчики - мужчины. В результате будет выбрано около половины строк SALES, что лучше всего представляется битовой шкалой. Аналогично, можно ограничить строки SALES условием, что заказчики - женщины, и создать соответствующую битовую шкалу. Теперь создадим индекс на SALES с двумя значениями "M" и "F" и свяжем две ранее полученных шкалы с этими значениями. Реально мы создали индекс по половому признаку для SALES, хотя сама таблица SALES не содержит такого столбца. Этот индекс делает не обязательным реально выполнять соединение между SALES и CUSTOMERS при выполнении запроса. Такой индекс называется индексом соединения внешнего столбца (FCJ - Foreign Column Join). Чтобы еще больше сократить работу по выполнению запроса, можно создать на таблице SALES FCJ-индексы для p.package_type и t.month. Тогда оптимизатор запросов сможет выполнить этот запрос с использованием только индексов на таблице SALES. FCJ-индекс является вариантом битового индекса соединения, предложенного в статье Valduriez P., "Join Indexes", ACM TODS, 12 (2), 218-246, June 1987.

Вместо создания трех FCJ-индексов можно создать многотабличный индекс соединения (MTJ - Multi-Table Index) на таблице SALES, объединяющий столбцы нескольких таблиц - t.month, p.package_type и c.gender. Хотя такие индексы позволяют еще больше повысить эффективность соединения, их наличие может привести к определенной потере гибкости. Кроме того, по соображениям эффективности, возможно, пришлось бы создать MTJ-индекс для каждой комбинации внешних таблиц, которая характерна для данной рабочей загрузки системы. С другой стороны, число FCJ-индексов возрастает только линейно с увеличением числа внешних столбцов. По этой причине MTJ-индексы могут быть полезны только в исключительно специальных ситуациях.

Возникает вопрос: если понадобится создать много индексов соединения, не приведет ли это к деградации системы? Ответ: нет. На платформах DSS, где отсутствуют параллельные изменения, индексы соединения позволяют повысить эффективность выполнения запросов лишь за счет расходов на дополнительное дисковое пространство.

Как сделаны битовые индексы в продуктах компании Informix, предназначенных для поддержки DSS? Новая форма индекса, называемая GK-индекс (Generalized Key) представляет гибкую комбинацию традиционных и битовых индексных структур. Вот синтаксис оператора CREATE GK INDEX:


CREATE GK INDEX INDEXNAME

ON T

 (SELECT AS KEY X.c1 {, Y.c2, ...}

   FROM T, X, Y, ...

   WHERE }

 );

В результате будет создан именованный индекс на таблице T. Раздел SELECT AS KEY явно определяет значение ключа индекса, который может быть вычислен для каждой строки T, и индекс позволяет выбрать строку T с этим ключом. Ключ индекса может состоять из набора конкатенированных значений столбцов таблиц X, Y, ..., а раздел WHERE будет специфицировать (среди прочего), каким образом строки со столбцами, значения которых входят в значение ключа индекса, соединяются в результирующую строку. Список SELECT не порождает какого-либо порядка таблиц. Он означает только то, что столбцы перечисленных таблиц могут выбираться в любом порядке, но из таблицы T будет выбираться только один столбец; в разделе FROM не требуется указывать несколько таблиц.

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


CREATE GK INDEX ORDERGENDER

ON SALES

 (SELECT AS KEY c.gender

   FROM SALES s, CUSTOMER c

   WHERE s.cid = c.cid);

При наличии этого индекса оптимизатор SQL-запросов будет использовать его для выполнения соответствующих операторов SQL без какой-либо потребности во вмешательстве пользователя. Например, индекс будет использован для выполнения следующих двух операторов SELECT. В обоих случаях доступ к таблице CUSTOMER не требуется.


SELECT SUM(s.dollar_sales) FROM CUSTOMER c, SALES s

 WHERE s.cid = c.cid AND c.gender = 'M';



SELECT SUM(dollar_sales) FROM SALES

 WHERE CID IN (SELECT CID FROM CUSTOMERS WHERE

  c.gender = 'M');

MTJ-индекс, который конкатенирует значения столбцов из нескольких таблиц разных измерений, чтобы ограничить строки центральной таблицы фактов, создается следующим SQL-оператором. При использовании этого индекса не потребуются соединения для выполнения звезднообразного оператора SELECT, приведенного выше (SEL1).


CREATE GK INDEX ORDERSMPG

ON SALES

 (SELECT AS KEY t.month, p.package_type, c.gender

  FROM SALES s, TIME t, PRODUCT p, CUSTOMER c

  WHERE s.day = t.day AND s.pid = p.pid

   AND s.cid = c.cid);

Формат GK-индекса настолько гибок, что поддерживает совершенно новые возможности индексации, такие как индекс на виртуальном столбце, представленном выражением над базовыми столбцами. Предположим, что в таблице SALES определяется новый виртуальный столбец по формуле:


profit_per_unit = (dollar_sales - dollar_cost) / unit_sales

Все три составляющих являются реальными столбцами таблицы SALES, так что вычисление производится легко для каждой строки SALES. Такой виртуальный столбец может быть определен с помощью операторов CREATE TABLE или ALTER TABLE диалекта языка SQL компании Informix. После этого виртуальный столбец можно использовать в запросах точно так же, как и реальные столбцы. Для этого столбца можно создать GK-индекс с помощью простого оператора


CREATE GK INDEX PROFITX

ON SALES

 (SELECT AS KEY profit_per_unit

  FROM SALES);

Селективный индекс напоминает набор строк, выбираемых из таблицы при задании в разделе WHERE некоторого набора ограничений. Этот набор строк, представленный битовой строкой, называется foundset ("найденным набором"). Если имеется желание ограничить внимание в таблице EMPLOYEES "технарями", можно определить следующий селективный GK-индекс:


CREATE GK INDEX TECHIES

ON EMPLOYEES

 (SELECT AS KEY 'constant'

   FROM EMPLOYEES

   WHERE hobby = 'math' AND reading = 'Dibert');

Informix старается добиться еще более высоких показателей эффективности в будущем.

Размещение рекламы — тел. +7 495 4119920, ICQ 232284597

Подписка на новости IT-портала CITForum.ru
(библиотека, CITKIT.ru, CitCity)

Новые публикации:

24 декабря

CITKIT.ru:

  • Новогодние поздравления
  • Сергей Кузнецов. Цикл Операционные системы: Ностальгия по будущему:

  • Алексей Федорчук. OpenSolaris 2008.11 Release

  • Сергей Голубев:

  • Евгений Чайкин aka StraNNik (Блогометки):

    17 декабря

  • С.Д.Кузнецов. Базы данных. Вводный курс

    10 декабря

    CITKIT.ru:

  • OpenSolaris 2008.11 Release

  • Альтернативные ОС: две грустные истории (С.Кузнецов)
  • Nokia N810 — доведение до ума
  • CitCity:

  • Платформа 2009: заоблачные перспективы Microsoft

    4 декабря

  • Лекция С.Д.Кузнецова Понятие модели данных. Обзор разновидностей моделей данных

    CITKIT.ru:

  • OpenSolaris 2008.11 Release. Первые впечатления

  • Linux vs FreeBSD: продолжим "Священные войны"?

  • Nokia N810 as is

  • Индульгенция для FOSS

  • Друзья СПО'2008

    26 ноября

  • Нечеткое сравнение коллекций: семантический и алгоритмический аспекты

    CitCity:

    CITKIT.ru:

  • Глава из книги А.Федорчука
    Сага о FreeBSD:
  • 19 ноября

  • Проблемы экономики производства крупных программных продуктов

  • Язык модификации данных формата XML функциональными методами

    CITKIT.ru:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:

    Заметки к книге:

  • FreeBSD: монтирование сменных устройств и механизм HAL
  • Текстовый редактор ee

    12 ноября

  • Правило пяти минут двадцать лет спустя, и как флэш-память изменяет правила (Гоц Грейф, перевод: Сергей Кузнецов)

    CITKIT.ru:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:
  • OSS в России: взгляд правоведа (В.Житомирский)

  • Новая статья из цикла С.Голубева "Железный марш":

    29 октября

  • О некоторых задачах обратной инженерии

  • Веб-сервисы и Ruby

  • Тестирование web-приложений с помощью Ruby

    CITKIT.ru:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:

  • PuppyRus Linux - беседа с разработчиком (С.Голубев)

  • Сергей Кузнецов. Заметка не про Linux

    22 октября

  • Обзор методов описания встраиваемой аппаратуры и построения инструментария кросс-разработки

    CITKIT.ru:

  • Сергей Кузнецов. Почему я равнодушен к Linux

  • Глава из книги А.Федорчука
    Сага о FreeBSD:
  • Что надо иметь
    3. Базовые познания

    CitCity:

  • Управление IT-инфраструктурой на основе продуктов Microsoft

    15 октября

  • Методы бикластеризации для анализа интернет-данных

    CitCity:

  • Разъемы на ноутбуках: что они дают и зачем их так много?
  • AMD Puma и Intel Centrino 2: кто лучше?

    CITKIT.ru:

  • Новый цикл статей С.Голубева
    Железный марш:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:

    8 октября

  • Автоматизация тестирования web-приложений, основанных на скриптовых языках
  • Опыт применения технологии Azov для тестирования библиотеки Qt3

    Обзоры журнала Computer:

  • SOA с гарантией качества
  • Пикоджоуль ватт бережет
  • ICT и всемирное развитие

    CitCity:

  • Пиррова победа корпорации Microsoft

    CITKIT.ru:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:

    Статья из архива:

  • Я живу в FreeBSD (Вадим Колонцов)

    Новые Блогометки:

  • Перекройка шаблона Blogger или N шагов к настоящему
  • Blogger. Comment style
  • Screenie или глянцевый снимок экрана

    2 октября

    CITKIT.ru:

  • Сага о FreeBSD (А. Федорчук)

    Zenwalk: пакет недели

  • Банинг — интеллектуальное развлечение (С.Голубев)

    CitCity:

    25 сентября

  • Клермонтский отчет об исследованиях в области баз данных

    CITKIT.ru:

  • Пользователям просьба не беспокоиться... (В.Попов)

  • Снова про ZFS: диск хорошо, а два лучше
  • Командная оболочка tcsh (А.Федорчук)

    Zenwalk: пакет недели

    17 сентября

  • T2C: технология автоматизированной разработки тестов базовой функциональности программных интерфейсов
  • Технология Azov автоматизации массового создания тестов работоспособности

    CITKIT.ru:

  • FreeBSD: ZFS vs UFS, и обе-две — против всех (А.Федорчук)

    Zenwalk: пакет недели

  • Дачнет — практика без теории (С.Голубев)

    10 сентября

  • За чем следить и чем управлять при работе приложений с Oracle
  • Планировщик заданий в Oracle
    (В.Пржиялковский)

    CITKIT.ru:

  • Microsoft: ответный "боян" (С.Голубев)

  • Причуды симбиоза, или снова "сделай сам" (В.Попов)

  • Файловые системы современного Linux'а: последнее тестирование
  • Zsh. Введение и обзор возможностей
    (А.Федорчук)

    Описания пакетов Zenwalk: Zsh, Thunar, Thunar-bulk-rename, Xfce4-places-plugin, Xfce4-fsguard-plugin

    Блогометки:

  • Google Chrome
  • Лончер для ASUS Eee PC 701

    3 сентября

    CITKIT.ru:

  • Заметки о ядре (А.Федорчук):

    Добавлены описания пакетов Zenwalk: Galculator, Screenshot, Gnumeric, Pidgin

    В дискуссинном клубе:

  • И еще о Википедии и Google Knol

  • Лекция для начинающего линуксоида (С.Голубев)

    26 августа

  • Транзакционная память (Пересказ: С. Кузнецов)

    CITKIT.ru:

  • Открыт новый проект Zenwalk: пакет недели

  • Статья Текстовые процессоры и их быстродействие: конец еще одной легенды?

    21 августа

    CITKIT.ru:

  • Почему школам следует использовать только свободные программы (Ричард Столлман)
  • Беседа Сергея Голубева с учителем В.В.Михайловым

  • Википедия или Гуглезнание? Приглашение к обсуждению (Алексей Федорчук)
  • Народная энциклопедия от Google (StraNNik)

  • Обзор Mandriva 2009.0 Beta 1 Thornicrofti
  • Новичок в Линукс: Оптимизируем Mandriva 2008.1

  • Книга Zenwalk. Приобщение к Linux:

    13 августа

    CitCity:

  • Мирный Atom на службе человеку. Обзор платы Intel D945GCLF с интегрированным процессором
  • Обзор процессоров Intel Atom 230 на ядре Diamondville

  • iPhone - год спустя. Скоро и в России?

    CITKIT.ru:

  • Интермедия 3.4. GRUB: установка и настройка (из книги Zenwalk. Приобщение к Linux)

    6 августа

  • СУБД с хранением данных по столбцами и по строкам: насколько они отличаются в действительности? (Пересказ: С. Кузнецов)

    CITKIT.ru:

  • Интермедия 2.2. Что неплохо знать для начала (из книги Zenwalk. Приобщение к Linux)

  • И снова про шрифты в Иксах (А.Федорчук)

  • 20 самых быстрых и простых оконных менеджеров для Linux

  • Дело о трех миллиардах (С.Голубев)

    30 июля

  • OLTP в Зазеркалье (Пересказ: С. Кузнецов)

    CitCity:

  • Будущее BI в облаках?
  • Тиражные приложения и заказная разработка. Преимущества для заказчика
  • Дискуссия со сторонниками заказной разработки

    CITKIT.ru:

  • Новые главы книги Zenwalk. Приобщение к Linux:
  • Глава 8. Пакеты: средства установки, системы управления, системы построения
  • Глава 9. Zenwalk: репозитории, пакеты, методы установки

    23 июля

    CITKIT.ru:

  • Все против всех. 64 vs 32, Intel vs AMD, tmpfs vs ext3
  • Две головы от Intel

  • Zenwalk: обзор штатных приложений (глава из книги "Zenwalk. Приобщение к Linux")

  • Нормально, Григорий...

    16 июля

    Обзоры журнала Computer:

  • Перспективы и проблемы программной инженерии в XXI веке
  • Большие хлопоты с большими объемами данных
  • Перспективы наноэлектроники

    CITKIT.ru:

  • Интермедия о лицензиях (А.Федорчук. "Zenwalk. Приобщение к Linux")

  • Есть ли будущее у KDE?

  • Linux в школе: альтернативный вариант в задачах

  • Шифр (приключения агента Никодима)

    10 июля

    CITKIT.ru:

  • Новые разделы книги А. Федорчука Zenwalk. Приобщение к Linux:
  • Интермедия вступительная. Linux или GNU/Linux? Как вас теперь называть?
  • Глава 5. Среда Xfce
  • Глава 6. Xfce: приложения и плагины

  • ZUR (Zenwalk User Repository) FAQ

    2 июля

  • Персистентность данных в объектно-ориентированных приложениях (С. Кузнецов)

    CITKIT.ru:

  • Новые разделы книги А. Федорчука Zenwalk. Приобщение к Linux:
  • Интермедия 1.2. Дорога к Zenwalk'у. Период бури и натиска
  • Интермедия 3.3. Немного о Linux'е и "железе"
  • Глава 4. Настройка: инструментами и руками
  • Интермедия 4.1. Zenpanel и конфиги: поиски корреляции

  • Интервью с Жан-Филиппом Гийоменом, создателем дистрибутива Zenwalk

  • Linux в школе: первые итоги (С. Голубев)

    25 июня

    CITKIT.ru:

  • Zenwalk. Приобщение к Linux (А. Федорчук)

  • Логика и риторика (С.Голубев)

  • Технология Tru64 AdvFS

  • Ханс Райзер предлагает отвести полицейских к телу Нины

    18 июня

  • Проекты по управлению данными в Google (Пересказ: С. Кузнецов)

    CITKIT.ru:

  • ОС и поддержка "железа": мифы и реальность (А. Федорчук)

  • Linux в школе: другие дистрибутивы

  • Пинок (С. Голубев)

    4 июня

  • Ландшафт области управления данными: аналитический обзор (С. Кузнецов)

    CITKIT.ru:

  • Linux в школе: слово заинтересованным лицам

  • SlackBuild: пакеты своими руками

  • Linux от компании Novell. Установка и обзор openSUSE Linux

    Все публикации >>>




  • IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

    Информация для рекламодателей PR-акции, размещение рекламы — тел. +7 495 4119920, ICQ 232284597 Пресс-релизы — pr@citcity.ru
    Послать комментарий
    Информация для авторов
    Rambler's Top100 TopList liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня This Web server launched on February 24, 1997
    Copyright © 1997-2000 CIT, © 2001-2007 CIT Forum
    Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...