Сообщения

Сообщения за 2013

Балансировка потоков в Oracle

При параллельной загрузке данных в хранилище, чтобы уменьшить время общей загрузки таблиц часто применяется динамическая балансировка по потокам. То есть, разные задачи группируются в какое то количество потоков (обычно константа, но может также меняться в зависимости от разных условий). Выходит что на основании веса разбиваем задачи на несколько потоков, желательно чтобы  максимальный суммарный вес одного потока был минимальным. Итак получается:  Задача о ранце (рюкзаке)  ( англ.   Knapsack problem )  .  Но приведу более простой алгоритм, может и не самый эффективный, но простой и удобный в реализации. Весом могут быть разные параметры,  например: время загрузки в прошлый раз количество строк размер таблицы статистике Балансировку можно делать каждый раз, или в какой то период, и каждый раз задача может попадать в разные потоки. Реализация алгоритма на Oracle: WITH --элементы с весом или продолжительностью ITEMS AS ...

Динамическое получение диапазона дат партиций Oracle

Получить динамический диапазон дат в партициях можно из поля  HIGH_VALUE  в таблице  USER_TAB_PARTITIONS.   Но тут возникают проблемы что поле  HIGH_VALUE имеет тип LONG и не совсем удобно с ним работать не прибегая к помощи PLSQL. Но данную проблему легко решить воспользовавшись функцией  DBMS_XMLGEN.GETXMLTYPE                  Реализация алгоритма на Oracle: SELECT TABLE_NAME, PARTITION_NAME, PARTITION_POSITION, CASE WHEN PARTITION_NAME='PMAX' THEN TO_DATE('2999-12-31 00:00:00', 'yyyy-mm-dd hh24:mi:ss')+1 ELSE TO_DATE(TRIM('''' FROM REGEXP_SUBSTR(EXTRACTVALUE(DBMS_XMLGEN. GETXMLTYPE('select high_value from user_tab_partitions where table_name=''' || TABLE_NAME || ''' and partition_name = ''' || PARTITION_NAME || ...

Олимпиадная задача по Oracle

Вчера упала интересная задача, которая сводится до элементарной, которая аналогичная олимпиадной задаче Oracle. Хочу ее вынести сюда, и показать ее решение на базе алгоритма "схлопывания". Итак, есть таблица: EFF_DTTM EXP_DTTM 01.01.2013 05.01.2013 05.01.2013 08.01.2013 08.01.2013 09.01.2013 11.01.2013 15.01.2013 15.01.2013 25.01.2013 28.01.2013 30.01.2013 Нужно склеить подряд идущие даты и вывести их границы. То есть ожидаемый результат: EFF_DTTM EXP_DTTM 28.01.2013 30.01.2013 11.01.2013 25.01.2013 01.01.2013 09.01.2013 Алгоритм более сложный чем необходимо для такого упрощенного случая, но при реальном использовании появятся еще и бизнес поля, тогда алгоритм подойдет очень хорошо. Так как для схлопывания с учетом дырок в истории понадобится еще учет изменения бизнес полей. Реализация алгоритма на Oracle: WITH --исходные данные T0 AS ( SELECT TO_DATE('01.01.2013', 'DD.MM.YYYY')EFF_DTTM, TO_DATE('05.01.2013', 'DD.MM.Y...

Алгоритм "Схлопывание" (Сollapse)

Встречается ситуация когда история создается но не несет какой либо полезной информации, или может даже мешать. Например у сущности  с определенным ключом есть поле которое часто меняется но нам не нужно грузить его в хранилище. Например мы строим в хранилище связку [Абонент]-> [ФИО] (которое может менятся), а в таблице источника есть например поле [Город] изменения которого влияют на историю. Реализация алгоритма на Oracle: WITH --таблица с историей и ключом из двух полей hist_table AS (SELECT 1 AS KEY, 'Иванов' fio,'Москва' city, DATE '2010-01-01' AS eff_dttm, DATE '2011-01-01' AS exp_dttm FROM dual UNION SELECT 1 AS KEY, 'Иванов' fio,'Киев' city, DATE '2011-01-01' AS eff_dttm, DATE '2014-01-01' AS exp_dttm FROM dual UNION SELECT 1 AS KEY, 'Петров' fio, 'Киев' city, DATE '2014-01-01' AS eff_dttm, DATE '2999-12-31' AS exp_dttm FRO...

DWH

Хранилище данных  ( англ.   Data Warehouse ) — предметно-ориентированная информационная  база данных , специально разработанная и предназначенная для подготовки отчётов и бизнес-анализа с целью поддержки принятия решений в организации. Строится на базе  систем управления базами данных  и  систем поддержки принятия решений . Данные, поступающие в хранилище данных, как правило, доступны только для чтения. Данные из  OLTP -системы копируются в хранилище данных таким образом, чтобы построение отчётов и  OLAP -анализ не использовал ресурсы транзакционной системы и не нарушал её стабильность. Как правило, данные загружаются в хранилище с определённой периодичностью, поэтому актуальность данных может несколько отставать от OLTP-системы.

Алгоритм "Натягивание" (Pull Story)

      Часто встречает ситуация когда надо от истории по 2 и более ключам перейти к истории по меньшему количеству ключей. Для получения новой истории используется так называемый метод "натягивания"  (pull story). Смысл в том что мы сначало строим временную шкалу в нашем примере hist_table_time по нужному ключу. Потом соединяем временную шкалу с таблицей на момент времени (т.е. на  eff_dttm из шкалы времени) и получаем нужные нам  поля различными аггрегирующими функциями (в нашем примере это MAX)       Данный алгоритм может применяться и для натягивания нескольких таблиц на общую временную шкалу которую можно получить через UNION.  WITH --таблица с историей и ключом из двух полей hist_table AS (SELECT 1 AS key1, 1 key2, DATE '2010-01-01' AS eff_dttm, DATE '2011-01-01' AS exp_dttm FROM dual UNION SELECT 1 AS key1, 1 key2, DATE '2011-01-01' AS eff_dttm, DATE '2999-12-31' AS exp_dttm FROM dual UNION...

Алгоритм "Выбор актуальных"

В хранилищах данных для таблиц содержащих историю (историческая таблица) используется две даты EFF_DTTM (VALID_FROM_DTTM) - дата начала действия записи EXP_DTTM (VALID_TO_DTTM) - дата окончания действия записи, для последней записи в истории равна максимальной дате которая задана константой, например MAX_DATE='31.12.2999' Обычно EFF_DTTM является включительной в интервал действия, а EXP_DTTM не включительной в интервал действия. Для выборки из исторических таблиц есть способа 1. Выбор актуальной записи (т.е. где EXP_DTTM=MAX_DATE) 2. Выбор записей действующих в заданный интервал Реализация алгоритма на Oracle: WITH hist_table AS (SELECT 1 AS key, 1 val, DATE '2010-01-01' AS eff_dttm, DATE '2011-01-01' AS exp_dttm FROM dual UNION SELECT 1 AS key, 2 val, DATE '2011-01-01' AS eff_dttm, DATE '2012-01-01' AS exp_dttm FROM dual UNION SELECT 1 AS key, 3 val, DATE '2012-01-01' AS eff_dttm,...