3. Варианти на структури при използване на глобали
Структура като подредено дърво има различни специални случаи. Нека разгледаме тези, които имат практическа стойност при работа с глобали.
3.1 Специален случай 1. Един възел без разклонения
Глобалите могат да се използват не само като масив, но и като обикновени променливи. Например като брояч:
Set ^counter = 0 ; установка счётчика
Set id=$Increment(^counter) ; атомарное инкрементирование
В този случай глобалното, освен значението си, може да има и разклонения. Едното не изключва другото.
3.2 Специален случай 2. Един връх и много разклонения
Като цяло това е класическа база ключ-стойност. И ако запазим кортеж от стойности като стойност, ще получим съвсем обикновена таблица с първичен ключ.
За да имплементираме таблица на глобални стойности, ще трябва сами да генерираме редове от стойностите на колоните и след това да ги запазим в глобалната с помощта на първичния ключ. За да можете отново да разделите низа на колони при четене, можете да използвате:
- разделителни знаци.
Set ^t(id1) = "col11/col21/col31" Set ^t(id2) = "col12/col22/col32"
- твърда схема, в която всяко поле заема предварително определен брой байтове. Както се прави в релационните бази данни.
- специална функция $LB (достъпна в Cache), която създава низ от стойности.
Set ^t(id1) = $LB("col11", "col21", "col31") Set ^t(id2) = $LB("col12", "col22", "col32")
Интересното е, че не е трудно да се използват глобали, за да се направи нещо подобно на вторични индекси в релационни бази данни. Нека наречем такива структури глобални индекси. Глобалът на индекса е спомагателно дърво за бързо търсене на полета, които не са част от първичния ключ на главния глобал. За да го попълните и използвате, трябва да напишете допълнителен код.
Нека създадем глобален индекс на първата колона.
Set ^i("col11", id1) = 1
Set ^i("col12", id2) = 1
Сега, за да търсим бързо информация в първата колона, трябва да погледнем глобално ^i и намерете първичните ключове (id), съответстващи на желаната стойност на първата колона.
Когато вмъкваме стойност, можем незабавно да създадем глобалните стойности и индекси за задължителните полета. И за надеждност, нека обвием всичко в транзакция.
TSTART
Set ^t(id1) = $LB("col11", "col21", "col31")
Set ^i("col11", id1) = 1
TCOMMIT
Подробности за това как да го направите на M
Такива таблици ще работят толкова бързо, колкото в традиционните бази данни (или дори по-бързо), ако функциите за вмъкване/актуализиране/изтриване на редове са написани на COS/M и компилирани.Проверих това твърдение с тестове на групови INSERT и SELECT в една таблица с две колони, включително използване на командите TSTART и TCOMMIT (транзакции).
Не съм тествал по-сложни сценарии с паралелен достъп и паралелни транзакции.
Без използване на транзакции процентът на вмъкване беше 778 361 вмъквания/секунда на милион стойности.
С 300 милиона стойности - 422 141 вмъквания/секунда.
При използване на транзакции - 572 082 вмъквания/секунда за 50M вмъквания. Всички операции бяха извършени от компилиран M код.
Хард дисковете са обикновени, а не SSD. RAID5 с обратно записване. Процесор Phenom II 1100T.
За да тествате SQL база данни по подобен начин, трябва да напишете съхранена процедура, която ще извършва вмъквания в цикъл. При тестване на MySQL 5.5 (InnoDB съхранение), използвайки този метод, получих числа не повече от 11K вмъквания в секунда.
Да, внедряването на таблици в глобални изглежда по-сложно, отколкото в релационни бази данни. Следователно индустриалните бази данни на глобали имат SQL достъп за опростяване на работата с таблични данни.
Като цяло, ако схемата на данните няма да се променя често, скоростта на вмъкване не е критична и цялата база данни може лесно да бъде представена под формата на нормализирани таблици, тогава е по-лесно да се работи със SQL, тъй като осигурява по-високо ниво на абстракция .
В конкретния случай исках да го покажа globals може да действа като конструктор за създаване на други бази данни. Като асемблер, на който могат да бъдат написани други езици. Ето примери за това как можете да създавате аналози на глобали
Ако трябва да създадете някакъв вид нестандартна база данни с минимални усилия, тогава трябва да погледнете към глобалните.
3.3 Специален случай 3. Дърво на две нива, всеки възел от второ ниво има фиксиран брой клонове
Вероятно се досещате: това е алтернативна реализация на таблици в глобални стойности. Нека сравним тази реализация с предишната.
Таблици на дърво на две нива vs. върху дърво на едно ниво.
Против
Професионалисти
- По-бавно за вмъкване, тъй като трябва да зададете броя на възлите, равен на броя на колоните.
- Повече потребление на дисково пространство. Тъй като глобалните индекси (разбирани като индекси на масиви) с имена на колони заемат дисково пространство и се дублират за всеки ред.
- По-бърз достъп до стойностите на отделните колони, тъй като няма нужда да анализирате низа. Според моите тестове е с 11,5% по-бърз на 2 колони и повече на по-голям брой колони.
- По-лесна промяна на схемата на данните
- По-ясен код
Заключение: не е за всеки. Тъй като скоростта е едно от най-ключовите предимства на глобалните данни, няма смисъл да се използва тази реализация, тъй като най-вероятно няма да работи по-бързо от таблиците в релационни бази данни.
3.4 Общ случай. Дървета и подредени дървета
Всяка структура от данни, която може да бъде представена като дърво, пасва идеално на глобалните.
3.4.1 Обекти с подобекти
Това е областта на традиционната употреба на глобали. В областта на медицината има огромен брой заболявания, лекарства, симптоми и методи на лечение. Нерационално е да се създава таблица с милион полета за всеки пациент. Освен това 99% от полетата ще бъдат празни.
Представете си SQL база данни от таблици: “пациент” ~ 100 000 полета, “Медицина” - 100 000 полета, “Терапия” - 100 000 полета, “Усложнения” - 100 000 полета и т.н. и така нататък. Или можете да създадете база данни от много хиляди таблици, всяка за определен тип пациент (и те могат да се припокриват!), лечения, лекарства и още хиляди таблици за връзки между тези таблици.
Глобалните са идеални за медицината, тъй като ви позволяват да създадете за всеки пациент точно описание на неговата медицинска история, различните терапии и действията на лекарствата под формата на дърво, без да губите допълнително дисково пространство в празни колони, както би бъде случаят в релационния случай.
Използвайки глобали е удобно да създадете база данни с данни за хора, когато е важно да се натрупа и систематизира максимум разнообразна информация за клиента. Това се търси в медицината, банкирането, маркетинга, архивирането и други области
.
Разбира се, в SQL можете също да емулирате дърво само с няколко таблици (
Не е тайна, че промяната на схемата за данни на гигантски таблици (ALTER TABLE) може да отнеме доста време. MySQL, например, прави ALTER TABLE ADD|DROP COLUMN чрез пълно копиране на информация от старата таблица в новата таблица (тествани MyISAM, InnoDB машини). Което може да затвори работеща база данни с милиарди записи за дни, ако не и седмици.
Промяната на структурата на данните, ако използваме глобали, не ни струва нищо. По всяко време можем да добавим всякакви нови свойства, от които се нуждаем, към всеки обект, на всяко ниво на йерархията. Промените, свързани с преименуването на клонове, могат да се изпълняват във фонов режим на работеща база данни.
Следователно, когато става въпрос за съхраняване на обекти с огромен брой незадължителни свойства, глобалните са чудесен избор.
Освен това, позволете ми да ви напомня, че достъпът до което и да е от свойствата е незабавен, тъй като в глобалното всички пътища са B-дървета.
Глобалните бази данни като цяло са вид ориентирана към документи база данни с възможност за съхраняване на йерархична информация. Следователно документно-ориентираните бази данни могат да се конкурират с глобалните в областта на съхраняването на медицински досиета. Но пак не е съвсем същотоНека вземем MongoDB за сравнение. В този домейн губи от глобалните поради следните причини:
- Размер на документа. Единицата за съхранение е текст във формат JSON (по-точно BSON) с максимален обем около 16MB. Ограничението беше направено специално, така че JSON базата данни да не се забавя по време на анализиране, ако в нея се съхранява огромен JSON документ и след това се осъществява достъп чрез полета. Този документ трябва да съдържа цялата информация за пациента. Всички знаем колко дебели могат да бъдат досиетата на пациентите. Максималният размер на картата от 16 MB незабавно слага край на пациентите, чиято карта за заболяване включва MRI файлове, рентгенови снимки и други изследвания. В един клон на глобала можете да имате гигабайти и терабайти информация. По принцип можем да сложим край на това, но аз ще продължа.
- Време на съзнание/промяна/изтриване на нови свойства в картата на пациента. Такава база данни трябва да прочете цялата карта в паметта (това е голямо количество!), да анализира BSON, да добави/промени/изтрие нов възел, да актуализира индексите, да го опакова в BSON и да го запише на диск. Глобалът трябва само да има достъп до конкретно свойство и да го манипулира.
- Бърз достъп до отделни имоти. С много свойства в документа и неговата многостепенна структура, достъпът до отделните свойства ще бъде по-бърз поради факта, че всеки път в глобалното е B-дърво. В BSON трябва да анализирате линейно документа, за да намерите желаното свойство.
3.3.2 Асоциативни масиви
Асоциативните масиви (дори с вложени масиви) пасват перфектно на глобалните. Например, такъв масив от PHP ще бъде показан на първата снимка 3.3.1.
$a = array(
"name" => "Vince Medvedev",
"city" => "Moscow",
"threatments" => array(
"surgeries" => array("apedicectomy", "biopsy"),
"radiation" => array("gamma", "x-rays"),
"physiotherapy" => array("knee", "shoulder")
)
);
3.3.3 Йерархични документи: XML, JSON
Също така лесно се съхранява в глобали. Може да се разполага по различни начини за съхранение.
XML
Най-лесният начин за анализиране на XML в глобални е да се съхраняват атрибути на тагове във възли. И ако е необходим бърз достъп до атрибутите на таговете, можем да ги преместим в отделни клонове.
<note id=5>
<to>Вася</to>
<from>Света</from>
<heading>Напоминание</heading>
<body>Позвони мне завтра!</body>
</note>
В COS това ще съответства на кода:
Set ^xml("note")="id=5"
Set ^xml("note","to")="Саша"
Set ^xml("note","from")="Света"
Set ^xml("note","heading")="Напоминание"
Set ^xml("note","body")="Позвони мне завтра!"
коментар: За XML, JSON, асоциативни масиви можете да измислите много различни начини за показване в глобали. В този случай не отразихме реда на подтаговете в тага за бележка. В световен мащаб ^xml подтаговете ще бъдат показани по азбучен ред. За стриктно отразяване на реда можете да използвате например следния дисплей:
JSON.
Първата снимка от раздел 3.3.1 показва отражение на този JSON документ:
var document = {
"name": "Vince Medvedev",
"city": "Moscow",
"threatments": {
"surgeries": ["apedicectomy", "biopsy"],
"radiation": ["gamma", "x-rays"],
"physiotherapy": ["knee", "shoulder"]
},
};
3.3.4 Идентични структури, свързани с йерархични връзки
Примери: структурата на търговските офиси, местоположението на хората в MLM структура, базата данни за отвори в шаха.
База данни за дебюти. Можете да използвате оценката на силата на удара като стойност на индекса на глобалния възел. След това, за да изберете най-силния ход, ще бъде достатъчно да изберете клона с най-голяма тежест. В глобалното всички клонове на всяко ниво ще бъдат сортирани по сила на движение.
Структурата на търговските офиси, структурата на хората в МЛМ. Възлите могат да съхраняват определени кеширащи стойности, които отразяват характеристиките на цялото поддърво. Например обемът на продажбите на дадено поддърво. Във всеки момент можем да получим цифра, отразяваща постиженията на всеки бранш.
4. В какви случаи е най-изгодно да се използват глобални?
Първата колона представя случаи, при които ще получите значително увеличение на скоростта чрез използване на глобални стойности, а втората, когато дизайнът или моделът на данни ще бъде опростен.
Скорост
Лесна обработка/представяне на данни
- Вмъкване [с автоматично сортиране на всяко ниво], [индексиране чрез главен ключ]
- Премахване на поддървета
- Обекти с много вложени свойства, които изискват индивидуален достъп
- Йерархична структура с възможност за заобикаляне на дъщерни клонове от всеки клон, дори и несъществуващи
- Обхождане на поддървета първо в дълбочина
- Обекти/субекти с огромен брой незадължителни [и/или вложени] свойства/субекти
- Данни без схема. Когато често могат да се появят нови имоти и старите да изчезнат.
- Трябва да създадете персонализирана база данни.
- Бази на пътищата и дървета на решенията. Когато е удобно да представите пътеки като дърво.
- Премахване на йерархични структури без използване на рекурсия
Разширение
Отказ от отговорност: Тази статия и моите коментари към нея са мое мнение и не представляват официалната позиция на InterSystems Corporation.
Източник: www.habr.com