Індекси h2>
Євген Каратаєв p>
Мова
піде про алгоритми і структурах даних, їх організації та підтримки. Термін
індекс далі використовується строго з метою позначення додаткових пошукових
або оптимізують структур. Основною мовою прикладів вибрана мова МUMPS. За
можливості застосовується страндартний синтаксис, в окремих виняткових
випадках для більшої читання застосовуються Cache Object Script - розширення. Їх
застосування обмежене і допускає альтернативну заміну на еквівалентні
вираження в інших діалектах МUMPS. p>
Індекси
- Це структури даних, які розміщуються паралельно і підтримувані синхронно
основним структурам даних і мають основним призначенням підтримку структур
даних, орієнтованих на прискорення пошуку або оптимізацію зберігання основних
даних. Тут під основними даними розуміються дані, зберігання і робота з
якими є основним призначенням системи бази даних. p>
При
використанні основних даних система бази даних виконує операції вставки,
пошуку, видалення або зміни в масиві основних даних. При використанні
додаткових індексних структур система паралельно оновлює індексні
структури при зміні (вставці, зміну і видалення) основних даних і в
деяких випадках отримує можливість використовувати індексні структури,
орієнтовані на пошук даних. Наявність такої можливості визначається
характеристиками індексу. p>
Як
випливає з вищенаведеного, введення індексів в систему бази даних утяжеляет
операції пов'язані зі зміною даних але прискорює операції пов'язані з пошуком
і, як завжди, як наслідок, вибіркою даних. p>
Індексні
структури самі по собі звичайно не є необхідними для роботи системи бази
даних. І їх застосування визначається програмістом або адміністратором системи.
p>
В
більшості загальнопоширених систем баз даних підтримка індексних структур
та їх використання виконується автоматичними засобами. У цій роботі ми
будемо складати структури і алгоритми, які можна використовувати поза
автоматики і користуватися всіма можливостями безвідносно обмежень
системи бази даних. Приблизно як якби по частинах реалізували внутрішні
механізми великої системи, але в дещо спрощеному варіанті. p>
Узагальнений механізм підтримки індексу. h2>
Індексний
структура за своїм станом має відповідати стану індексованих
даних. Тому операції оновлення індексів звичайно ділять на дві групи --
динамічне оновлення індексних структур при оновленні одного запису і
масові операції видалення/побудови індексів. p>
Далі
будемо розглядати рядка даних, влаштовані для простоти в такий спосіб: p>
ідентифікатор
запису отримуємо інкремент ноду ^ Data p>
значення
запису зберігається у вузлі ^ Data (id) p>
запис
складається з полів з роздільником ~ (тильда) p>
індексні
запису зберігаємо з глобальний ^ Index p>
в
запису припускаємо поля - фігура, колір, кількість p>
загальне
будова запису: ^ Data (id) = Figure ~ Color ~ Count p>
Операції
динамічного оновлення індексів можуть бути вбудовані у вигляді дзвінка з операції
оновлення запису і або передувати власне збереження основної записи,
або наслідувати йому, або обрамляти. Наприклад: p>
;
просто збереження об'єкта p>
SaveObject (id, ObjVal)
p>
i
'+ $ g (id) s id = $ i (^ Data) p>
s
^ Data (id) = ObjVal p>
q
p>
;
оновлення індексів перед збереженням p>
SaveObject (id, ObjVal) p>
n OldValue p>
i '+ $ g (id) s id = $ i (^ Data) p>
s OldValue = $ g (^ Data (id)) p>
d DeleteIndices (id, OldValue) p>
d InsertIndices (id, ObjVal) p>
s
^ Data (id) = ObjVal p>
q
p>
;
оновлення індексів після збереження p>
SaveObject (id, ObjVal) p>
n OldValue p>
i '+ $ g (id) s id = $ i (^ Data) p>
s OldValue = $ g (^ Data (id)) p>
s ^ Data (id) = ObjVal p>
d DeleteIndices (id, OldValue) p>
d
InsertIndices (id, ObjVal) p>
q
p>
;
обрамлення оновлення індексів при збереженні p>
SaveObject (id, ObjVal) p>
i '+ $ g (id) s id = $ i (^ Data) p>
d DeleteIndices (id, $ g (^ Data (id))) p>
s ^ Data (id) = ObjVal p>
d InsertIndices (id, ObjVal) p>
q p>
Тут
DeletIndices видаляє індексні записи по цьому об'єкту, а InsertIndices їх
створює. У даному випадку мається на увазі простий формат зберігання запису - однієї
рядком, що трактується або як рядок з роздільниками або як список.
Незважаючи на те, що три методи у результаті дають однаковий результат, між ними
є різниця в тому, наскільки правильно буде працювати конкурентний
(одночасний для кількох процесів) доступ до даних і індексах. У разі
зберігання тільки даних це питання практично не варто, оскільки операція set
атомарна. У разі застосування паралельних структур індексів існує момент
між станами, коли записи немає, але індекс є, або індекс є але записи
немає. Це питання вирішується звичайно за допомогою застосування блокувань. Операція set
нового значення запису обрамляється командами p>
l + ^ Data (id) p>
s ^ Data (id) = ObjVal p>
l - ^ Data (id) p>
І
всередині функцій видалення/вставки індексних записів також вставляються
обрамляють блокування. Наявність блокувань особливо критично в разі
виконання коду в контексті транзакції і можливості виконання операції
trollback. p>
Різниця
в режимі перестроювання індексу, а саме що раніше з'явиться в базі - індексний
запис або запис з даними, дозволяє побудувати в деякому розумінні
самовідновлювальні систему, яка буде мати можливість восстановітсья
у разі збою при записі рядка даних. Якщо індекс побудований раніше, то при
вибірці за індексом функція вибірки даних може визначити що індексний запис
існує але їй не відповідає рядок даних. У разі застосування блокувань
в операції оновлення запису ми у функції вибірки можемо також спробувати
заблокувати цей же запис і якщо блокування виявилася успішною але запису немає,
або її стан не відповідає індексним значень, то значить що операція
запису самої рядка даних була неуспішною і слід просто видалити індексний
запис. Механізм досить громіздкий, але в ситуації коли з міркувань
ефективності не хочеться застосовувати транзакції, може виявитися корисним. Питання
вибору стратегії оновлення індексу при оновленні запису залишимо програмісту.
p>
Операція
перестроювання індексу зводиться до видалення всіх індексних записів і перебору всіх
наявних записів з даними і побудови індексних записів з кожної наявної
запису даних. Вважаємо, що є функції DeleteIndex щоб видалити всі
індексних записів по одному індексу. Тоді перестроювання індексу може виглядати
як p>
UpdateIndex (IndexName) p>
d DeleteIndex (IndexName) p>
n id, ObjValue p>
s id = "" f s
id = $ o (^ Data (id), ObjValue) q: id = "" d p>
. d InsertIndex (IndexName, id, ObjVal)
p>
Q p>
Список літератури h2>
Для
підготовки даної роботи були використані матеріали з сайту http://karataev.nm.ru/
p>