Архівування даних з використанням XML-формату, Інші СУБД, Бази даних, статті

Страхова компанія Acme Insurance Company готується до архівування на стрічку даних, термін зберігання яких дорівнює трьом рокам і більше, і видаляє його з промислової бази даних. ІТ-архітектори компанії запропонували стратегію архівування, в якій використовуються переносяться табличні простору, а також акуратне секціонування промислових таблиць по датам виконання транзакцій.

Відповідно до вихідним архітектурним планом секції з застарілими даними перетворюються в окремі таблиці за допомогою відповідних операторів механізму секціонування (partition exchange), потім табличні простору, що містять ці таблиці, можуть бути перенесені на стрічку і видалені з головної бази даних. Якщо видалені дані потрібно відновити, перенесені табличні простору копіюються зі стрічки і знову включаються в головну базу даних. У переносите табличних просторах і перетворених секціях дані не модифікуються, тому не генерується ніяка UNDO-і REDO-інформація, що дозволяє суттєво прискорити переміщення даних в порівнянні з використанням традиційних підходів, таких як використання операторів INSERT і DELETE. І якщо в архівних даних потрібно шукати якусь інформацію, то це також просто, як виконання запитів до окремих таблиць, які були створені під час перетворення секцій.

План можна було б вважати досконалим, але була одна проблема. ІТ-архітектори в інших проектах планують поступове зміна структури промислових таблиць. Будуть додаватися і віддалятися стовпці, змінюватися типи даних, модифікуватися обмеження цілісності і т.д. Після зміни структури таблиць перенесені табличні простору вже не можна буде знову включити в головну базу даних – структури таблиць не збігаються!

Для вирішення цієї проблеми був відкликаний з відпустки Джон, головний адміністратор бази даних компанії.

XML-формат архівних даних

Джон закотив рукави і сформулював п’ять головних вимог до процесу архівування:

1. Дані повинні архівувати в міру їх старіння.
2. Заархівовані дані повинні віддалятися з головної бази даних без великого впливу на продуктивність.
3. Відновлення архівних даних повинне бути швидким і простим.
4. Рішення повинно дозволяти зміна структур таблиць.
5. Повинна бути забезпечена можливість пошуку в архівних даних без включення їх в головну базу даних.

Джон вирішив використовувати для зберігання архівних даних XML-формат.

Адміністратори бази даних і програмісти компанії Acme відреагували на пропозицію Джона, висловивши міркування, що їх застосування розроблені з урахуванням використання реляційної моделі і звичайних таблиць, що ці додатки (і таблиці) не можуть обробляти XML-дані, що для досконального аналізу впливу цих змін немає часу.

Джон відповів, що програми будуть бачити дані як якщо б вони були реляційними, хоча насправді вони будуть зберігатися у зовнішній пам’яті в XML-форматі.

Архівна таблиця

Джон запропонував усім зацікавленим програмістам і адміністраторам бази даних пояснити своє рішення про створення резервної копії в XML-форматі на прикладі типової в їхній базі даних таблиці угод з клієнтами (транзакцій) TRANS, починаючи з моменту її створення і заповнення (див. лістинг 1). Ця таблиця секціонірована по стовпцю TRANS_DATE (дата транзакції), маючи на увазі, що через три роки найстаріша секція може бути заархівований і повністю видалена з таблиці (drop partition). Таке видалення секції фактично не робить ніякого впливу на продуктивність сервера бази даних і генерує дуже мало REDO-і UNDO-інформації; це найшвидший спосіб очищення даних у порівнянні з такими методами, як порядкове видалення даних і усікання таблиці (truncation).






Лістинг 1: створення і заповнення таблиці TRANS.

create table trans
(
trans_date date,
trans_id number(10),
trans_type varchar2(1),
trans_amount number(12,2)
)
partition by range (trans_date)
(
partition Jan2003 values less than (to_date(“01/02/2003”, “dd/mm/yyyy”)),
partition Feb2003 values less than (to_date(“01/03/2003”, “dd/mm/yyyy”)),
.
.
.
);
begin
for ctr in 1..100 loop
insert into trans values
(
sysdate – dbms_random.value(1,300),
ctr,
decode (round(dbms_random.value(1,2)),1,”C”,”D”),
dbms_random.value(1,10000)
);
end loop;
end;
/

Однак, оскільки структура промислової таблиці буде змінюватися, в базі даних компанії Acme потрібно, пояснив Джон, створити ще одну таблицю – спеціально для цілей архівування. Стовпці цієї таблиці ARCH_TRANS не будуть збігатися з стовпцями промислової таблиці; більшість значень яких буде розміщуватися в архівній таблиці в одному стовпці TRANS_DETAILS, тип даних якого – XMLTYPE:

create table arch_trans
(
arch_date date,
trans_date date,
trans_details xmltype
)
partition by range (trans_date)
(
partition Jan2003 values less than (to_date(“01/02/2003”, “dd/mm/yyyy”)),
partition Feb2003 values less than (to_date(“01/03/2003”, “dd/mm/yyyy”)),
.
.
.
)
/

Джон відзначив два важливих моменти:


Архівування

Для перетворення даних з реляційного формату в XML-формат Джон використовує дві SQL-функції: XMLFOREST і XMLELEMENT. Функція XMLFOREST перетворює реляційні дані в XML-формат. Значення перетворюваних стовпців полягають в теги, імена яких збігаються з іменами стовпців. Для демонстрації Джон вибрав два стовпці таблиці TRANS, модифікованих функцією XMLFOREST:

select xmlforest(trans_id,trans_type)
from trans;
XMLFOREST(TRANS_ID,TRANS_TYPE)
—————————————————————-
<TRANS_ID>1</TRANS_ID><TRANS_TYPE>D</TRANS_TYPE>
<TRANS_ID>2</TRAN_ID><TRANS_TYPE>C</TRANS_TYPE>
.
.
.

Функція XMLELEMENT формує з елементів, виданих функцією XMLFOREST, записи. Для обрамлення записів Джон використовує тег :

select xmlelement(“TransRec”,xmlforest(
trans_id,trans_type)) from trans;
XMLELEMENT(“TRANSREC”,XMLFOREST(
TRANS_ID,TRANS_TYPE))
——————————————————————————
<TransRec><TRANS_ID>1</TRANS_ID>
<TRANS_TYPE>D</TRANS_TYPE>
</TransRec>
<TransRec><TRANS_ID>2</TRANS_ID>
<TRANS_TYPE>C</TRANS_TYPE>
</TransRec>
.
.
.

Використовуючи ці дві функції, Джон демонструє SQL-скрипт, показаний на лістингу 2, який перетворює дані таблиці TRANS і вставляє їх у таблицю ARCH_TRANS.






Лістинг 2: архівування даних в XML-форматі.

	1	insert into arch_trans
2 (
3 arch_date,
4 trans_date,
5 trans_details
6 )
7 select
8 sysdate,
9 trans_date,
10 xmlelement(“TransRec”,
11 xmlforest(
12 trans_id,
13 trans_type,
14 trans_amount
15 )
16 )
17 from trans

Перетворені стовпці таблиці TRANS, зберігаються в XML-форматі в стовпці TRANS_DETAILS таблиці ARCH_TRANS. Після вставки даних в таблицю ARCH_TRANS Джон вибирає їх, як це показано на лістингу 3, щоб продемонструвати, як ці дані зберігаються. Зверніть увагу, щоб виводити довгі рядки даних, Джон використовує команду SET LONG (за умовчанням виводяться тільки перші 80 символів).






Лістинг 3: перегляд таблиці ARCH_TRANS.

SQL> set long 999999999
SQL> select * from ARCH_TRANS;
ARCH_DATE TRANS_DAT TRANS_DETAILS
—————- ——————– ——————————
07-JAN-06 27-DEC-05 <TransRec>
<TRANS_ID>80</TRANS_ID>
<TRANS_TYPE>D</TRANS_TYPE>
<TRANS_AMOUNT>4142.68</TRANS_AMOUNT>
</TransRec>

Коли настає час архівування застарілої секції, Джон перетворює цю секцію таблиці ARCH_TRANS в окрему таблицю:

alter table arch_trans
exchange partition jan2003
with table arch_trans_jan2003
/

Створюється таблиця ARCH_TRANS_JAN2003 в тому ж самому табличному просторі, в якому знаходиться секція JAN2003. Джон може дізнатися його ім’я, використовуючи цей запит:

select tablespace_name
from dba_tab_partitions
where table_name = “TRANS”
and partition_name = “JAN2003″;
TABLESPACE_NAME
<11p class=”bodycopy”>———————————

JAN2003

Джон переносить табличний простір JAN2003, в якому знаходиться таблиця ARCH_TRANS_JAN2003.

expdp “/ as sysdba”
transport_tablespaces=jan2003 dumpfile=jan2003.dmp

І нарешті, Джон видаляє перетворену таблицю (ARCH_TRANS_JAN2003) і відповідну секцію як з промислової таблиці (TRANS), так і з архівної таблиці (ARCH_TRANS):

drop table arch_trans_jan2003;
alter table trans
drop partition jan2003;
alter table arch_trans
drop partition jan2003;

Відновлення даних

Джон демонструє програмістам і адміністраторам бази даних компанії Acme, як легко архівувати і витягувати таблицю; простота відновлення таблиці – інше важлива вимога до процесу архівування. Щоб показати це, Джон накидав кроки “реверсування” дій, виконаних під час архівування.

Спочатку він переніс табличний простір назад в базу даних:
impdp dump_file=jan2003.dmp
transport_datafiles=”/u01/jan2003.dbf”

Це негайно робить таблицю ARCH_TRANS_JAN2003 доступною в середовищі бази даних. Тепер можна виконувати запити до цієї таблиці або ж об’єднати її з головною таблицею (ARCH_TRANS) у вигляді секції, а потім виконувати запити. Для об’єднання таблиць Джон виконав:

alter table arch_trans
exchange partition jan2003
with table arch_trans_jan2003
/

Тепер в таблиці ARCH_TRANS містяться також і дані за січень 2003. Відновлення завершено.

Виконання запитів до архівних даних

Програмісти і адміністратори бази даних компанії Acme як і раніше були стурбовані. Вони нагадали Джону, що дані в таблиці ARCH_TRANS зберігаються в XML-форматі, а не в реляційному.

Для перетворення XML-даних в реляційний формат Джон написав запит, показаний на лістингу 4. У цьому запиті для вилучення всіх стовпців з XML-представлення даних використовується нотація мови шляхів XPath. Програми компанії Acm будуть бачити архівні дані такими, як якщо б вони були реляційними, і ці програми не потрібно змінювати. Присутні розробники були задоволені представленим рішенням.






Лістинг 4: перетворення XML-даних в реляційний формат.

col Trans_ID format a5

col Trans_Type format a1
col Trans_Amount format 999999.99
select arch_date, trans_date,
extractvalue(trans_details,”/TransRec/TRANS_ID”) Trans_ID,
extractvalue(trans_details,”/TransRec/TRANS_TYPE”) Trans_Type,
to_number(extractvalue(trans_details,”/TransRec/TRANS_AMOUNT”)) Trans_Amount
from arch_trans;

Ключовий елемент цього запиту – функція EXTRACTVALUE, яка витягує значення елемента з XML-документа або XML-даних. Джон нагадав всім, що в дані стовпця TRANS_DETAILS включені XML-теги, які показують походження даних. Наприклад, дані в одній із записів виглядають так:

<TransRec>
<TRANS_ID>80</TRANS_ID>
<TRANS_TYPE>D</TRANS_TYPE>
<TRANS_AMOUNT>4142.68
</TRANS_AMOUNT>
</TransRec>

Для отримання значення елемента TRANS_TYPE Джон починає з елемента вищого рівня – TransRec, а потім використовує нотацію мови Xpath для переходу до потрібного рівня:

extractvalue(trans_details,”/TransRec/TRANS_TYPE”)

Тут Джон звертає увагу на важливий момент: на відміну від мови SQL імена в мові XML залежать від регістра, так що імена TransRec і transRec – різні імена.




Більш докладно про тип даних XMLType

Ви можете використовувати тип даних XMLType і в багатьох інших випадках. Розглянемо сценарій, в якому атрибути сутності заздалегідь не відомі і з часом будуть змінюватися. Наприклад, у автомобіля можуть бути такі атрибути, як марка, модель, рівень обробки салону, рік виробництва і колір. Пізніше, для деяких спеціально вироблених автомобілів може бути доведеться додати інші деталі, такі як назви складальних і двигунобудівних заводів. Якщо у вас використовується реляційний формат, ви можете додати нові стовпи, але в цьому випадку потрібно буде модифікувати всі оператори INSERT, навіть якщо ці нові атрибути не будуть вставлятися. Якщо ж для зберігання атрибутів обраний тип даних XMLType, ви повинні будете додати ці нові атрибути (як теги) тільки до конкретних записів. Потрібно буде змінювати тільки ті SQL-оператори, які безпосередньо мають доступ до цих нових атрибутам.

Інша перевага типу даних XMLType – вільний пошук даних, використовуючи опцію Context; в цьому випадку ви можете створити індекс типу CTXSYS.CONTEXT і шукати в даних типу XMLType конкретні строки. Цей метод дуже корисний, коли ви не знаєте, який стовпець таблиці містить конкретне, потрібне вам, значення; наприклад, ви шукаєте значення “ARUP”, але не знаєте, чи є воно частиною імені клієнта, його другого імені, прізвища, вуличного адреси, міста, округи, імені партнера і т.д. Контекстний пошук дозволяє виявити запис з цим значенням і визначити, в якій тег вона включена.

Для прискорення отримання даних Джон вирішує створити індекс за таблицею ARCH_TRANS. Більшість запитів вибирають дані по стовпцю TRANS_TYPE, тому він – кращий кандидат для цього індексу. Джон створює індекс:

create index
in_arch_trans_type
on arch_trans (
extractvalue (
TRANS_DETAILS,
“/TransRec/TRANS_TYPE”));

Джон пояснює, що цей SQL-оператор створює індекс, схожий на індекс по ключу-функції, але насправді цей індекс заснований на нотації мови XPath.

Зміни структури

Тепер залишилося тільки одне критичне вимогу: можливість зміни структури промислової таблиці. Джон показує приклад додавання до таблиці TRANS стовпця ACC_NO (до цього часу застарілі дані вже були архівовані і видалені з таблиці):

alter table trans add (acc_no varchar2(10))

Тепер в таблиці TRANS з’явився новий стовпець ACC_NO, але в стовпці TRANS_DETAILS таблиці ARCH_TRANS такий елемент відсутній. Джон запевняє, що вставка даних з стовпця TRANS_DETAILS в таблицю TRANS буде виконуватися успішно.

Коли додається новий стовпець, потрібно тільки модифікувати скрипт вставки даних, щоб він відображав наявність цього нового стовпця. Новий скрипт показаний на лістингу 5. Він ідентичний скрипту на лістингу 2, виключаючи рядок 15, в якій задається вибірка нового стовпця ACC_NO.






Лістинг 5: модифікований скрипт архівування даних.

1  	insert into arch_trans
2 (
3 arch_date,
4 trans_date,
5 trans_details
6 )
7 select
8 sysdate,
9 trans_date,
10 xmlelement(“TransRec”,
11 xmlforest(
12 trans_id,
13 trans_type,
14 trans_amount
15 acc_no
16 )
17 )
18 from trans;

Щоб показувати цей новий стовпець, Джон також модифікував і скрипт вилучення даних (див. лістинг 6).






Лістинг 6: модифікований скрипт вилучення даних.

select arch_date, trans_date,
extractvalue(trans_details,”/TransRec/TRANS_ID”) Trans_ID,
extractvalue(trans_details,”/TransRec/TRANS_TYPE”) Trans_Type,
to_number(extractvalue(trans_details,”/TransRec/TRANS_AMOUNT”)) Trans_Amount,
extractvalue(trans_details,”/TransRec/ACC_NO”) Acc_No
from arch_trans;

І знову цей скрипт ідентичний скрипту на лістингу 4, виключаючи поява імені нового стовпця ACC_NO.

 

Деякі адміністратори бази даних і розробники компанії Acme звернули увагу, що в більш старих записах в стовпці TRANS_DETAILS відсутні значення ACC_NO, вони з’являються лише в новіших записах. Вони запитали, як же будуть виконуватися оператори SELECT?

Джон відповів, що гнучкість засобів XML дозволяє посилатися на відсутні елементи. В такому випадку функція EXTRACTVALUES поверне невизначене значення NULL. Джон виконав запит, показаний на лістингу 6, і виділив з виведення два записи, які показані на лістингу 7. Для першого запису видається значення стовпця ACC_NO як NULL, оскільки в ній немає цього значення стовпця. Для другої ж записи показується значення стовпця ACC_NO таким, яким воно було введено






Лістинг 7: дві демонстраційні записи.

ARCH_DATE TRANS_DAT TRANS T TRANS_AMOUNT ACC_NO
——— ——— —– – ———— ———
01-JAN-06 20-OCT-05 100 C 5740.29
01-FEB-06 07-JAN-06 101 X 100.03 M101

Аналогічним чином, з таблиці можуть також вилучатися стовпці, в такому випадку XML-функція буде повертати їх фактичні значення, якщо вони присутні в архівного запису і NULL, в іншому випадку. Це дозволяє модифікувати структуру головної таблиці, тоді як архівування даних та їх відновлення будуть залишатися “легкою справою”. Фактично, з часом можуть зникнути всі стовпці (замінені на нові), але архівування даних з використанням XML-формату буде гарантувати їх доступність для тих же самих SQL-операторів. За аудиторією прокотився схвальний шумок.

Висновок

В кінці Джон знову повернувся до вихідних вимогам до процесу архівування і показав, як вони задовольняються запропонованими рішення (див. таблицю 1). Ніяких запитань і занепокоєння більше не було.




















Вимога

Рішення

Дані повинні архівувати в міру їх старіння

Таблиця ARCH_TRANS секціонувальних точно також як і головна табліцаTRANS. Отже, можна перетворювати цілі секції таблиці, а потім їх переносити.

Мінімальний вплив на продуктивність під час очищення даних

Очищення даних тут означає видалення секції, у якій фактично немає накладних витрат.

Відновлення архівних даних повинне бути швидким і простим

Відновлення видалених даних – це просто перенесення табличного простору назад в базу даних, фактично немає жодних накладних витрат

Гнучкість при зміні структури таблиць

Дані архівуються в XML-форматі, що дозволяє усунути обмеження при зміні структури таблиць.

Можливість пошуку в архівних даних

XML-дані показуються в реляційному форматі, що дозволяє виконувати запити до них, використовуючи звичний SQL-інтерфейс.

 

 

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*