Глобали - мечі-кладенцы для зберігання даних. Дерева. Частина 1

Глобали - мечі-кладенцы для зберігання даних. Дерева. Частина 1 Справжні мечі-кладенцы баз даних — глобали — давно відомі, але досі мало хто вміє ефективно ними користуватися або зовсім не володіє цією суперзброєю.

Якщо використовувати глобали у вирішенні тих завдань, у яких вони дійсно хороші, то можна досягти визначних результатів. Або у продуктивності, або у спрощенні розв'язання задачі (1, 2).

Глобали - це спеціальний спосіб зберігання та обробки даних, зовсім інший, ніж таблиці SQL. Вони з'явилися 1966 року у мові M(UMPS) (еволюційний розвиток - Caché ObjectScript, далі COS) у медичних БД і досі там активно використовуються, а також проникли в деякі інші області, де потрібна надійність та висока продуктивність: фінанси, трейдинг і т.д.

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

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

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

2. Як працюють глобали

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

Спрощеного, глобал — це персистентний масив. Масив, який автоматично зберігається на диск.
Важко уявити щось простіше для зберігання даних. У коді (мовами COS/M) від звичайного асоціативного масиву він відрізняється лише символом ^ перед іменем.

Для збереження даних у глобалі не потрібно вивчати мову запитів SQL, команди для роботи з ними дуже прості. Їх можна вивчити за годину.

Почнемо з найпростішого прикладу. Однорівневе дерево з двома гілками. Приклади написані COS.

Глобали - мечі-кладенцы для зберігання даних. Дерева. Частина 1

Set ^a("+7926X") = "John Sidorov"
Set ^a("+7916Y") = "Sergey Smith"



При вставці інформації в глобал (команда Set) автоматично відбуваються 3 речі:

  1. Збереження даних на диск.
  2. Індексація. Те, що в дужках виступає ключем (в англомовній літературі — «subscript»), а праворуч — значенням («node value»).
  3. Сортування. Дані сортуються за ключом. Надалі при обході масиву першим елементом стане "Sergey Smith", а другим "John Sidorov". При отриманні списку користувачів із глобалу база не витрачає часу на сортування. Причому можна запросити висновок відсортованого списку, починаючи з будь-якого ключа, навіть неіснуючого (висновок почнеться з першого реального ключа, який слідує за неіснуючим).

Усі ці операції відбуваються неймовірно швидко. На домашньому комп'ютері я отримував значення до 750 000 вставок/сек в одному процесі. На багатоядерних процесорах значення можуть досягати десятків мільйонів вставок/сек.

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

Глобали - мечі-кладенцы для зберігання даних. Дерева. Частина 1

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

Додамо в глобал ще кілька гілок другого та третього рівня.

Set ^a("+7926X", "city") = "Moscow"
Set ^a("+7926X", "city", "street") = "Req Square"
Set ^a("+7926X", "age") = 25
Set ^a("+7916Y", "city") = "London"
Set ^a("+7916Y", "city", "street") = "Baker Street"
Set ^a("+7916Y", "age") = 36

Глобали - мечі-кладенцы для зберігання даних. Дерева. Частина 1

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

Як видно, інформацію можна зберігати як у ключі, так і в значенні. Загальна довжина ключа (сума довжин всіх індексів) може досягати 511 байт, а значення 3.6 МБ для Caché. Число рівнів у дереві (кількість вимірів) - 31.

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

Глобали - мечі-кладенцы для зберігання даних. Дерева. Частина 1

Set ^b("a", "b", "c", "d") = 1
Set ^b("a", "b", "c", "e") = 2
Set ^b("a", "b", "f", "g") = 3

Порожні гуртки - це вузли, яким не надано значення.

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

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

Глобали - мечі-кладенцы для зберігання даних. Дерева. Частина 1

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

А ось структура даних глобалу.

Глобали - мечі-кладенцы для зберігання даних. Дерева. Частина 1відмінності:

  1. Внутрішні вузли: інформація у глобалі може зберігатися у кожному вузлі, а чи не лише кінцях гілок.
  2. Зовнішні вузли: у глобалу обов'язково мають бути визначені значення на кінцях гілок, дерев ФС і садових — немає.



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

У загальному випадку глобал є впорядковане дерево з можливістю зберігання даних у кожному вузлі.

Щоб краще зрозуміти роботу глобалів, уявимо, що було б, якщо творці файлових систем використовували для зберігання інформації підхід аналогічний глобалам?

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

    Глобали - мечі-кладенцы для зберігання даних. Дерева. Частина 1

  3. Такі речі, як файли README.txt, можливо, відпали б. Все, що потрібно було сказати про вміст директорії, можна було записати в сам файл директорії. У просторі шляхів ім'я файлу не відрізняється від імені директорії, тому можна було обійтися одними файлами.
  4. Швидкість видалення директорій із вкладеними піддиректоріями та файлами різко збільшилася б. Багато разів на хабрі проскакували статті про те, як довго і важко видаляти мільйони дрібних файлів (1, 2). Однак, якщо зробити псевдофайлову систему на глобалі, це буде займати секунди або їх частки. Коли я тестував видалення піддерев на домашньому комп'ютері, то за 1 секунду видалялося 96-341 мільйонів вузлів з дерев'яного дерева на HDD (не SSD). Причому йдеться про видалення частини дерева, а не просто файлу з глобалами.

Глобали - мечі-кладенцы для зберігання даних. Дерева. Частина 1
Видалення піддерев — ще одна сильна сторона глобалів. Для цього не потрібна рекурсія. Це відбувається неймовірно швидко.

У нашому дереві це можна було б зробити командою вбити.

Kill ^a("+7926X")

Глобали - мечі-кладенцы для зберігання даних. Дерева. Частина 1

Для кращого розуміння, які дії нам доступні над глобалами, наведу коротку таблицю.

Основні команди та функції по роботі з глобалами у COS

Установка
Встановлення гілок до вузла (якщо ще не визначено) та значення вузла

Злиття
Копіювання піддерева

вбити
Видалення піддерева

ZKill
Видалення значення конкретного вузла. Поддерево що виходить із вузла не рушає

$Query
Повний обхід дерева із заходом углиб

$Order
Обхід гілок конкретного вузла

$Data
Перевірка чи визначено вузол

$Increment
Атомарне інкрементування значення вузла. Щоб не робити зчитування та записи, для ACID. Останнім часом рекомендується міняти на $Sequence

Дякуємо за увагу готові відповісти на ваші запитання.

відмова: Ця стаття та мої коментарі до неї є моєю думкою і не мають відношення до офіційної позиції корпорації InterSystems.

Продовження Глобали - мечі-кладенцы для зберігання даних. Дерева. Частина 2. Ви дізнаєтеся, які типи даних можна відобразити на глобалах і на яких завданнях вони дають максимальний виграш.

Джерело: habr.com

Додати коментар або відгук