3. Варыянты структур пры выкарыстанні глабалаў
Такая структура як спарадкаванае дрэва мае розныя прыватныя выпадкі. Разгледзім тыя, якія маюць практычную каштоўнасць пры рабоце з глабаламі.
3.1 Прыватны выпадак 1. Адзін вузел без галін
Глобалы можна выкарыстоўваць не толькі падобна масіву, але і як звычайныя зменныя. Напрыклад як лічыльнік:
Set ^counter = 0 ; установка счётчика
Set id=$Increment(^counter) ; атомарное инкрементирование
Пры гэтым глабал, акрамя значэння, можа яшчэ мець яшчэ і галіны. Адно не выключае другога.
3.2 Прыватны выпадак 2. Адна вяршыня і мноства галін
Наогул - гэта класічная key-value база. А калі ў якасці значэння мы будзем захоўваць картэж значэнняў, то атрымаем самую звычайную табліцу з першасным ключом.
Для рэалізацыі табліцы на глабалах нам давядзецца самім фармаваць радкі са значэнняў калонак, а потым захоўваць іх у глабал па першасным ключы. Каб пры счытванні было магчыма падзяліць радок зноў на калонкі можна выкарыстоўваць:
- сімвалы-падзельнікі.
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 уставак / секунду.
Пры выкарыстанні транзакцый - 572 уставак / секунду на 082М уставак. Усе аперацыі праводзіліся са скампіляванага M-кода.
Жорсткія дыскі звычайныя, ня SSD. RAID5 з Write-back. Працэсар Phenom II 1100T.
Для аналагічнага тэсціравання SQL-базы трэба напісаць захоўваемую працэдуру, якая ў цыкле будзе рабіць устаўкі. Пры тэставанні MySQL 5.5 (сховішча InnoDB) па такой методыцы атрымліваў лічбы не больш, чым 11К уставак у секунду.
Так, рэалізацыя табліц на глабалах выглядае больш складанай, чым у рэляцыйных БД. Таму прамысловыя БД на глабалах маюць SQL-доступ для спрашчэння працы з таблічнымі дадзенымі.
Наогул, калі схема дадзеных не будзе часта мяняцца, хуткасць устаўкі некрытычная і ўсю базу можна лёгка прадставіць у выглядзе нармалізаваных табліц, то прасцей працаваць менавіта з SQL, бо ён забяспечвае больш высокі ўзровень абстракцыі.
У гэтым прыватным выпадку я хацеў паказаць, што глабалы могуць выступаць як канструктар для стварэння іншых БД. Як асэмблер, на якім можна напісаць іншыя мовы. А вось прыклады, як можна стварыць на глабалах аналагі.
Калі трэба стварыць нейкую нестандартную БД мінімальнымі намаганнямі, то варта зірнуць у бок глабалаў.
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-tree.
Базы дадзеных на глабалах, увогуле, гэта разнавіднасць дакументна-арыентаваных БД, з магчымасцю захоўвання іерархічнай інфармацыі. Таму ў сферы захоўвання медыцынскіх карт з глабаламі могуць канкураваць дакументна-арыентаваныя БД. Але ўсё роўна гэта не зусім тоеВозьмем для параўнання, напрыклад, MongoDB. У гэтай сферы яна прайграе глабалам па прычынах:
- Памер дакумента. Адзінкай захоўвання з'яўляецца тэкст у фармаце JSON (дакладней BSON) максімальнага аб'ёму каля 16МБ. Абмежаванне зроблена адмыслова, каб JSON-база не тармазіла пры парсінгу, калі ў ёй захаваюць велізарны JSON-дакумент, а потым будуць звяртацца да яго па палях. У гэтым дакуменце павінна быць засяроджана ўся інфармацыя аб пацыенце. Мы ўсе ведаем якімі тоўстымі могуць быць карты пацыентаў. Максімальны памер карты ў 16МБ адразу ставіць крыж на пацыентах, у карту хвароб якіх уключаны файлы МРТ, сканы рэнгенаграфіі і іншых даследаванняў. У адной галіны глобала ж можна мець інфармацыю на гігабайты і тэрабайты. У прынцыпе на гэтым можна паставіць кропку, але я працягну.
- Час свядомасці / змены / выдаленні новых уласцівасцяў у карце пацыента. Такая БД павінна лічыць у памяць усю карту цалкам (гэта вялікі аб'ём!), распарыць BSON, унесці/змяніць/выдаліць новы вузел, абнавіць індэксы, запакаваць у BSON, захаваць на дыск. Глобалу ж дастаткова толькі звярнуцца да канкрэтнай уласцівасці і зрабіць з ім маніпуляцыі.
- Шпаркасць доступу да асобных уласцівасцяў. Пры мностве ўласцівасцей у дакуменце і яго шматузроўневай структуры доступ да асобных уласцівасцей будзе хутчэйшы за кошт таго, што кожны шлях у глабале гэта B-tree. У 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, асацыятыўных масіваў можна прыдумаць шмат розных спосабаў адлюстравання на глабалах. У дадзеным выпадку мы не адбілі парадак укладзеных тэгаў у тэгу note. У глабале ^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 Аднолькавыя структуры, звязаныя з іерархічнымі адносінамі
Прыклады: структура офісаў продажаў, размяшчэнне людзей у МЛМ-структуры, база дэбютаў у шахматах.
База дэбютаў. Можна ў якасці значэння азначніка вузла глобала выкарыстаць адзнаку сілы ходу. Тады, каб выбраць самы моцны ход дастаткова будзе выбраць галіна з найбольшай вагай. У глабале ўсе галіны на кожным узроўні будуць адсартаваны па сіле ходу.
Структура офісаў продажаў, структура людзей у МЛМ. У вузлах можна захоўваць некаторыя якія кешыруюць значэнні якія адлюстроўваюць характарыстыкі ўсяго поддерева. Напрыклад, аб'ём продажаў дадзенага поддерева. У любы момант мы можам атрымаць лічбу, якая адлюстроўвае дасягненні любой галіны.
4. У якіх выпадках найбольш выгадна выкарыстоўваць глабалы.
У першай калонцы прадстаўлены выпадкі, калі вы атрымаеце істотны выйгрыш у хуткасці пры выкарыстанні глабалаў, а ў другой калі спросціцца распрацоўка ці мадэль дадзеных.
Хуткасць
Выгода апрацоўкі / прадстаўлення даных
- Устаўка [з аўтаматычнай сартаваннем на кожным узроўні], [індэксаваннем па галоўным ключы]
- Выдаленне паддрэўяў
- Аб'екты з масай укладзены ўласцівасцяў, да якіх патрэбен індывідуальны доступ
- Іерархічная структура з магчымасцю абыходу даччыных галін з любой, нават не існуючай
- Абыход паддрэў у глыбіню
- Аб'екты/сутнасці з вялікай колькасцю неабавязковых [і/ці ўкладзеных] уласцівасцяў/сутнасцяў
- Бязсхемныя дадзеныя (schema-less). Калі часта могуць з'яўляцца новыя ўласцівасці і знікаць старыя.
- Трэба стварыць нестандартную БД.
- Базы шляхоў і дрэвы рашэнняў. Калі шляхі зручна прадстаўляць у выглядзе дрэва.
- Выдаленне іерархічных структур без выкарыстання рэкурсіі
Працяг
адмова: дадзены артыкул і мае каментары да яе з'яўляецца маім меркаваннем і не маюць дачынення да афіцыйнай пазіцыі карпарацыі InterSystems.
Крыніца: habr.com