Початкова сторінка

Микола Жарких (Київ)

Персональний сайт

?

Множини об’єктів

М.І.Жарких, Ю.Б.Кабаков

Модель наслідування

Модель наслідування в пропонованій системі знаходиться під управлінням дерева класів. Як ми вже згадували при описі МетаКласу, кожна декларація класу має рівно один безпосередній суперклас, за винятком ПерсОб’єкту, який не має суперкласу і виступає пращуром (ultimate ancestor) усіх інших класів. Таким чином, множинна спадковість (можливість успадковувати клас від кількох суперкласів) не використовується.

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

Всі методи та події суперкласу також доступні в підкласах; але оскільки ми зосереджуємось на статичній моделі даних, нами не розглядається можливість створення в класах предметної області власних методів та подій.

В силу принципу послідовності об’єктної моделі всі описані вище системні класи (починаючи від ПерсОб’єкта) є екземплярами МетаКласу, для яких значення атрибута “Власник” (суперклас) показано на рис. 1; тому для них є чинними всі правила наслідування.

Множини об’єктів і закладки

МножинаОб’єктів – це невпорядкований набір екземплярів ПерсОб’єкта (тобто екземплярів будь-яких класів бази даних). В силу послідовності об’єктної моделі його теж слід вважати об’єктом, але цей об’єкт існує тільки в пам’яті комп’ютера і тому нема потреби успадковувати його від персистентного об’єкта.

Закладка – це персистентний образ множини об’єктів. В ієрархії системних об’єктів Закладка успадковується від ПротоОб’єкту, наслідуючи від нього ім’я та методи Вибрати і ОбчислитиДекларативнийКлас (цей останній метод завжди повертає ПерсОб’єкт, який є декларативним класом будь-якої закладки). Таким чином, закладка – це іменована множина об’єктів, яка зберігається в базі даних.

Кожен об’єкт може входити до множини не більше одного разу (в SQL такий режим забезпечується опцією DISTINCTROW). Отже, якщо додати до множини об’єкт, який у ній вже міститься, множина не зміниться. Важливо розуміти, що множина не є монопольним власником своїх об’єктів і належність об’єкту до однієї множини не заважає йому належати до іншої множини. Щоб точно зрозуміти цю особливість, можна вважати множину набором вказівників на об’єкти.

МножинаОб’єктів визначає два методи :

Зберегти – утворює закладку з множини;

Ітератор – виконує певну дію, задану як аргумент, над усіма елементами множини, причому порядок обходу множини не визначається (залежить від реалізації).

Сукупність множин об’єктів утворює алгебраїчне кільце відносно операцій “сума” та “перетин” :

множина Х є сумою множин А та В, якщо будь-який об’єкт, що належить до А або до В, одночасно належить і до Х;

множина Х є перетином множин А та В, якщо будь-який об’єкт, що належить одночасно і до А, і до В, одночасно належить до Х;

Визначимо також бінарну операцію “різниця” :

множина Х є різницею множин А та В, якщо будь-який об’єкт, що належить до А і в той же час не належить до В, одночасно належить до Х.

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

Результатом фільтрування множини А під управлінням предиката Р є така множина В, що для будь-якого об’єкту, який належить одночасно і до А, і до В, значення предиката є істинним. В табличних системах цю функцію виконує фраза WHERE оператора SELECT. Алгоритмічно фільтрування можна виразити таким чином :

В := []; {порожня множина}

А.Ітератор(якщо (Р) то В := В + [поточний об’єкт]);

Результатом сортування множини А під управлінням функції сортування F є частково або повністю відсортована множина. В табличних системах цю функцію виконує фраза ORDER BY оператора SELECT.

Функція сортування F(M1, M2) має повертати -1, якщо об’єкт M1 має передувати M2, 0 – якщо їхній відносний порядок неістотний, +1 – якщо M2 має передувати M1, спеціальне значення nil – якщо функція порівняння не може бути обчислена (таке може трапитись, наприклад, якщо порівнюються значення якогось атрибуту і хоча б один з об’єктів не має цього атрибуту).

Множина А є повністю сортованою відносно F, якщо для будь-якої пари об’єктів M1, M2, що належать до множини А, значення функції не дорівнює nil. Якщо ж значення, для яких F = nil існують, множина є частково сортованою. Nil-значення можна вважати або меншим, або більшим за будь-яке реальне значення (це залежить від реалізації).

На повністю сортованій множині (або на сортованій частині частково сортованої множини) ітератор повинен обходити об’єкти в порядку їх сортування.

Результатом групування множини під управлінням набору функцій групування {G1 … GN} є частково або повністю згрупована множина. В табличних системах цю функцію виконує фраза GROUP BY оператора SELECT.

Для кожного об’єкту М з множини функція Gk(M) повертає якесь значення або nil. Всі об’єкти з однаковим значенням функції групування утворюють часткову множину або групу; об’єкти, для яких функція групування дає nil, утворюють залишкову групу.

Операція групування встановлює над множиною структуру дерева, коренем якого є сама множина, вершинами першого рівня – групи, утворені функцією G1, вершинами другого рівня – групи, утворені функцією G2 всередині груп першого рівня, і т.д.

Повністю згрупованою є множина, в якій немає жодної залишкової групи; формально це така множина, що для кожного її об’єкту значення усіх функцій групування є визначеним. По суті це множина, згрупована виключно на позитивних засадах, без залишкових груп, підстава для утворення яких є чисто негативною – неналежність об’єктів до жодної позитивної групи. Частково згрупована множина містить залишкові групи.

Важливим частинним випадком повністю згрупованої множини є класифікована множина, у якій групи утворені з екземплярів одного класу.

Складнішим варіантом групування є операція упорядкування множини. Упорядкованою будемо називати таку згруповану множину, для якої, по-перше, визначено порядок перебору груп; по-друге, об’єкти всередині груп відсортовано. Оскільки функція сортування вживається для порівняння об’єктів, належних до якоїсь однієї групи, вона може залежати від параметрів групування (тобто набору значень функцій групування, властивих даній групі) і таким чином для різних груп може бути встановлено різний порядок сортування.

Повністю впорядкована множина – це повністю згрупована множина, кожна група якої повністю відсортована; інакше множина є частково впорядкованою.

Множини і вказівники

Об’єкти, як ми вище визначили, можуть мати атрибути типу вказівник, які вказують на інші об’єкти. Ці вказівники відбивають зв’язки між частинами предметної області. Щоб скласти більш повне уявлення про даний об’єкт, необхідно розглянути об’єкти, які є значеннями атрибутів-вказівників; часто дуже корисним є розгляд об’єктів, які посилаються на даний об’єкт (користувачів даного об’єкту).

Тому важливим є процес об’єктного з’єднання (object joining) для збирання інформації, розділеної між кількома об’єктами. Внаслідок особливостей об’єктної архітектури предметної області необхідність з’єднання виникає набагато рідше, ніж при роботі з табличними архітектурами. Якщо в табличній базі даних розщеплення інформації між окремими таблицями (нормалізація) і наступне з’єднання з кількох таблиць є постійною необхідністю, то в об’єктній базі даних порції інформації (атрибути), які відносяться до однієї частини предметної області (об’єкта), зберігаються всередині об’єкта і не потребують з’єднання. Можна сказати, що в об’єктній базі даних всі з’єднання табличного стилю, які мають реальний сенс, уже виконано.

Будемо називати зв’язком атрибут-вказівник або користувачів об’єкта. Властивість “Користувачі” не є атрибутом, але її роль щодо з’єднання така сама, як і в атрибута-вказівника.

Отже, розглянемо зв’язок А. Координаційною сферою множини Х відносно зв’язку А назвемо множину об’єктів, які є значенням зв’язку А для всіх елементів Х, разом із висхідною множиною Х. Операція побудови координаційної сфери є унарною операцією над множиною об’єктів, оскільки результатом її виконання є нова множина об’єктів. Алгоритм побудови координаційною сфери такий :

КС := X;

X.Ітератор(КС := КС + [поточний об’єкт].А);

Потужність координаційної сфери завжди більша за потужність висхідної множини. Неможливість побудови координаційної сфери свідчить про порушення цілісності бази даних, про наявність посилань на неіснуючі об’єкти. Перше застосування операції КоординаційнаСфера дає першу координаційну сферу; друге..N застосування – відповідно 2..N-у координаційну сферу. Оскільки число об’єктів в базі даних скінчене, рано чи пізно чергове застосування цієї операції не змінить множини :

КС(КСN) = КСN+1 ≡ КСN

(в крайньому разі ця сфера КСN може охопити всі об’єкти бази). Будемо називати таку множину замкненою відносно зв’язку А або А-галактикою. Взагалі таких галактик у базі даних можу бути декілька. Наприклад, в БД з генеалогії династії Рюриковичів та Гедиміновичів є галактиками відносно зв’язку “батько особи”.

По аналогії з поняттями координаційної сфери та галактики відносно одного зв’язку можна розглядати ці поняття відносно сукупності зв’язків {А1 … АK} або відносно повної сукупності усіх зв’язків, властивих множині Х. Побудова повної координаційної сфери є процесом з позитивним зворотнім зв’язком, оскільки включення до множини нових об’єктів може збільшити набір зв’язків множини, що відповідно розширяє наступну координаційну сферу.

Повна галактика найчастіше буде містити всі об’єкти бази даних. Адже якщо в БД є об’єкти, які не посилаються на інші об’єкти і не є предметами посилань, постає питання, що вони взагалі роблять у базі і яким частинам предметної області відповідають.

Операції над множинами об’єктів

Результатом усіх перелічених унарних та бінарних операцій над множинами об’єктів також є множина об’єктів, тому цей результат може виступати операндом іншої операції. Таким чином, можна будувати вирази множинного типу, які використовуються, зокрема, як значення атрибута ГенеруючийВираз для генераторів.

З використанням бекусівської нормальної форми синтаксис генеруючого виразу можна записати так :

БінОперація : := + | – | *

Операнд : := ПротоОб’єкт.Вибрати | фільтрування(Операнд) | КоординаційнаСфера(Операнд) | (Операнд БінОперація Операнд)

ГенеруючийВираз : := Операнд | структурування(Операнд)

Унарні операції пріоритетніші за бінарні. Серед унарних операцій над множинами операція фільтрування є найпріоритетнішою. Оскільки операція фільтрування комутативна

F1(F2(X)) ≡ F2(F1(X))

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

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

S1(S2(…SN(X)…) ≡ S1(X)

Слід пам’ятати, що коли стурктурована множина виступає операндом бінарної операції, її структура втрачається. Наприклад,

S1(X) + S2(Y) ≡ X + Y

так що операції S1 і S2 можуть просто не виконуватись. Це враховано в синтаксисі, де операція структурування, якщо вона є, завжди є останньою (найбільш зовнішньою) операцією.

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

Порівняння множин

Операції порівняння множин є бінарними операціями над множинами об’єктів, результатом яких є логічне значення.

Множина В менше або дорівнює множині А, якщо А + В ≡ А.

Множина В менша за множину А, якщо А ≤ В і при цьому А – В ≠ [] (не є порожньою множиною).

Множини А та В є рівними, якщо А – В = [] або А * В = [].

Множини А та В не є рівними, якщо не має місце рівність.

Статистичні процедури над множинами

Ці статистичні процедури (в SQL вони звуться domain functions) є надзвичайно цікавими і корисними, якщо застосовуються для згрупованої (впорядкованої) множини об’єктів. Для незгрупованої множини вони діють так само, як для згрупованої множини, що складається з однієї групи.

Всі процедури повертають результат у вигляді дерева, структурно подібного до дерева груп, у вершинах якого записано результати процедури для окремої групи. Якщо група має підгрупи, результат дії процедури повинен бути таким, якби всі об’єкти підгруп безпосередньо належали даній групі. Таким чином, у множині з багаторівневим групуванням один виклик процедури одночасно обчислює інформацію для всіх рівнів групування.

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

Аналогічно працюють процедури обчислення суми, середнього значення, середньоквадратичного відхилення. Аргументом цих процедур є числове Значення, для якого треба виконати обчислення. При потребі за допомогою цієї системи можна реалізувати складніші статистичні операції, такі як дисперсійний аналіз чи порівняння функцій розподілу.

Об’єкти прав доступу

Для регулювання доступу користувачів інформації до об’єктів бази даних можна спроектувати спеціальні системні об’єкти. Один ескізний варіант цих об’єктів гранично стисло описано нижче.

Перш за все, необхідно реалізувати об’єкт КористувачІнформації, задачами якого є ідентифікація користувача та зв’язування його з ГрупоюКористувачів.

ГрупаКористувачів володіє набором об’єктів ПравДоступу до класів. Кожен об’єкт ПравДоступу вказує на клас, для якого визначаються права, та набір логічних значень, які дозволяють або забороняють виконання певних методів для даного класу (наприклад, створення нових екземплярів, чи запису об’єктів, чи вибирання екземплярів).

Права доступу успадковуються, тобто поширюються на всі підкласи даного класу, якщо для якихось підкласів дана ГрупаКористувачів не визначає окремого об’єкта ПравДоступу. Таким чином, для задання прав адміністратора бази даних досить створити один об’єкт ПравДоступу, який визначає повний доступ для класу ПерсОб’єкт; аналогічно для реалізації права “тільки читання будь-якої інформації” треба створити один об’єкт ПравДоступу, який визначає право відкривати екземпляри для класу ПерсОб’єкт (зауважимо, що в табличній базі даних для реалізації такого права треба виконати процедуру надання права читання для кожної таблиці бази).

При необхідності об’єкти ГрупаКористувачів можна зв’язати в дерево для організації успадкування прав доступу від групи-господаря.

При такій системі права перевіряються під час виконання кожного із захищених методів. Тому якщо генератор створює множину з 10 об’єктів, для яких даний користувач має право читання для 8 і ніяких прав – для 2 об’єктів, то генерація множини пройде успішно, бо включення об’єкту до множини не передбачає відкриття об’єкту; але під час перегляду цієї множини користувач зможе побачити тільки ті 8 об’єктів, переглядати які він має право.

Обмін інформацією з табличними базами даних

Алгоритм перетворення об’єктної інформації у табличний вигляд можна використовувати для експорту даних або для підтримки таблично-орієнтованих інтерфейсів (таких як Open database connectivity). В загальних рисах він може виглядати так : для кожного класу об’єктів на підставі метаінформації створюється окрема таблиця, колонки якої відповідають скалярним атрибутам класу. Для кожного векторного атрибута створюється окрема таблиця, яка місить ід об’єкта як поле зв’язку з головною таблицею (тобто під час експорту відбувається автоматична нормалізація інформації).

Процедуру експорту можна реалізувати як метод МетаКласу.

Імпорт даних є значно складнішим, по-перше, через необхідність встановлювати відповідність між структурою імпортованої інформації та структурою класів об’єктної бази даних, по-друге, необхідно встановлювати відповідність між головною таблицею об’єктів та додатковими таблицями, які треба розглядати як джерело векторних атрибутів, по-третє, необхідно розпізнати, в яких ієрархічних відношеннях знаходяться між собою головні таблиці об’єктів (тобто яка таблиця містить об’єкти суперкласу, а яка – об’єкти підкласу). Це вимагає аналізу схеми даних у табличній базі даних і, можливо, додаткових алгоритмічних та інструментальних засобів.

В цілому обмін інформацією з табличними базами даних не є простою задачею, і головним чином через те, що набір засобів моделювання предметної області в табличних та об’єктних базах даних є кардинально різним.

Доступ до атрибутів в базі даних

Розглядаючи об’єкт Вираз, ми не зупинялись детально на синтаксисі формул, за якими обчислюється значення Виразу. Очевидно, що кожна формула може містити в якості операндів будь-які Значення, доступні у контексті ДекларативногоКласу того екземпляру ПротоОб’єкту, який є власником Виразу. При обчисленні Виразу в контексті певного екземпляра класа предметної області, формула використовує Значення, притаманні даному екземпляру (або безпосередні значення атрибутів, або значення обчислених виразів). Але формула може містити також Значення, притаманні іншим екземплярам (не тим, у контексті якого обчислюється Вираз).

Щоб видобути певне Значення для певного екземпляру, слід вживати такі операції :

знаходження конкретного Значення для конкретного екземпляра, яка повертає величину Значення;

індексація векторного атрибута, яка повертає скалярну величину певного компонента вектора;

розіменування атрибута-вказівника, яка повертає об’єкт, що є значенням вказівника;

типізація, яка дозволяє розглядати об’єкт суперкласу як об’єкт певного підкласу для того, щоб отримати доступ до специфічних Значень підкласу.

При будь-якій помилці ці операції повертають порожнє значення (nil) : наприклад, якщо даний об’єкт не має шуканого атрибута, або індекс вектора є невірним, або розіменовується атрибут, який не є вказівником. Операція типізації викликає помилку, якщо об’єкт не належить до потрібного підкласу.

За допомогою ланцюжків цих операцій можна видобути будь-яке Значення будь-якого екземпляру для подальшого використання.

Об’єктні трансакції

Трансакції дуже широко використовується в табличних базах даних, але не стандартизуються засобами SQL – кожна таблична СУБД реалізує їх на свій розсуд. Ми вважаємо, що об’єктна СУБД мусить підтримувати об’єктні трансакції.

Об’єктна трансакція – сукупність послідовних операцій з одним або кількома об’єктами бази даних, яку слід розглядати як атомарну цілісність : або всі операції трансакції є успішними і тоді трансакція в цілому є успішною, або якась операція є невдалою, і тоді всі операції трансакції скасовуються, а база даних повертається у такий стан, неначе трансакція не розпочиналась.

Найпростішим прикладом застосування об’єктної трансакції є реалізація операції зміни значення атрибута. В табличній системі зміна значення поля в одному записі є елементарною операцією, але в об’єктній системі, як ми вже зазначали, це не так. Для зміни значення атрибута треба виконати дві операції : відкрити потрібний об’єкт і потім записати змінений об’єкт в базу даних. Кожна з цих операцій може викликати помилку, тому доцільно об’єднати їх в одну трансакцію. Більше того, для забезпечення стійкого читання (repeatedly reading) необхідно заблокувати цей об’єкт не тільки для запису, але і для читання на весь час трансакції.

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

Блокування, які необхідні для реалізації трансакцій, можна розділити на блокування на рівні екземпляру та блокування на рівні класу. Блокування мусить встановлюватись окремо для кожного методу. Якщо застосування блокування читання та запису на рівні екземпляру є самоочевидними, то блокування запису на рівні класу необхідне, наприклад, під час обчислення середнього значення атрибута для класу, якщо вимагається високий рівень ізоляції трансакцій та, відповідно, висока надійність результатів обчислень. Аналогічно, операція створення нового екземпляру мусить блокуватись під час підрахунку числа екземплярів класу, і т.д.

Можна розрізняти оптимістичну стратегію блокування – вона може вживатись, коли трансакція заздалегідь знає всю множину об’єктів, що будуть охоплені трансакцією. Тоді достатньо заблокувати тільки ці екземпляри (наприклад, під час розглянутої вище операції викреслення). Песимістична стратегія блокування мусить вживатись, якщо трансакція заздалегідь не знає тієї множини об’єктів, яку вона має охопити, скажімо, якщо визначення цієї множини є метою трансакції. Тоді необхідно встановлювати блокування на рівні класів (прикладом може бути застосування методу Вибрати при високих вимогах до ізоляції трансакцій, коли є небажаним, щоб під час вибирання екземпляри додавались або знищувались).