Бази даних і файлові системи p>
Файлові системи
Історичним кроком був перехід до використання централізованих систем управління
файлами. З точки зору прикладної програми файл - це іменована область зовнішньої пам'яті, в яку можна записувати і з якої можна зчитувати дані.
Правила найменування файлів, спосіб доступу до даних, що зберігаються у файлі, і структура цих даних залежать від конкретної системи управління файлами і,
можливо, від типу файлу. Система управління файлами бере на себе розподіл зовнішньої пам'яті, відображення імен файлів у відповідні адреси в зовнішній
пам'яті та забезпечення доступу до даних. p>
Перша розвинена файлова система була розроблена фірмою IBM для її серії 360. До теперішнього
часу вона дуже застаріла, і ми не будемо розглядати її докладно. Зауважимо лише, що в цій системі підтримувалися як чисто послідовні, так і
індексного-послідовні файли, а реалізація багато в чому спиралася на можливості тільки що з'явилися до цього часу контролерів керування
дисковими пристроями. Якщо врахувати до того ж, що поняття файлу в OS/360 було обрано як основне абстрактне поняття, якому відповідав будь-який зовнішній
об'єкт, включаючи зовнішні пристрої, то працювати з файлами на рівні користувача було дуже незручно. Був потрібен цілий ряд громіздких і
перевантажених деталями конструкцій. Все це добре знайоме програмістам середнього та старшого покоління, які пройшли через використання вітчизняних
аналогів комп'ютерів IBM. p>
1.1.1.
Структури файлів
Далі ми будемо говорити про більш сучасних організаціях файлових систем. Почнемо з
структур файлів. Перш за все, практично у всіх сучасних комп'ютерах основними пристроями зовнішньої пам'яті є магнітні диски з рухомими
головками, і саме вони служать для зберігання файлів. Такі магнітні диски представляють собою пакети магнітних пластин (поверхонь), між якими на
одному важелі рухається пакет магнітних головок. Крок руху пакета головок є дискретним, і кожному положенню пакету головок логічно відповідає
циліндр магнітного диска. На кожній поверхні циліндр "висікає" доріжку, так що кожна поверхню містить число доріжок, яка дорівнює кількості
циліндрів. При розмітці магнітного диска (спеціальному дії, що передує використання диска) кожна доріжка розмічається на одну й ту ж кількість
блоків таким чином, що в кожен блок можна записати по максимуму одне й те саме число байтів. Таким чином, для твори обміну з магнітним диском на
рівні апаратури потрібно вказати номер циліндра, номер поверхні, номер блоку на відповідній доріжці і число байтів, що треба записати або прочитати
від початку цього блоку. p>
Однак ця можливість обмінюватися з магнітними дисками порціями менше обсягу блоку
в даний час не використовується в файлових системах. Це пов'язано з двома обставинами. По-перше, при виконанні обміну з диском апаратура
виконує три основні дії: підведення головок до потрібного циліндра, пошук на доріжці потрібного блоку та власне обмін з цим блоком. З усіх цих дій у
середньому найбільший час займає перше. Тому істотний виграш в сумарному часу обміну за рахунок зчитування або запису тільки частини блоку
отримати практично неможливо. По-друге, для того, щоб працювати з частинами блоків, файлова система повинна забезпечити відповідного розміру буфера
оперативної пам'яті, що істотно ускладнює розподіл оперативної пам'яті. p>
Тому у всіх файлових системах явно чи неявно виділяється деякий базовий рівень,
забезпечує роботу з файлами, що представляють набір прямо адресуються в адресному просторі файлу блоків. Розмір цих логічних блоків файлу
збігається або кратний розміру фізичного блоку диска і зазвичай вибирається рівним розміру сторінки віртуальної пам'яті, яку підтримує апаратурою комп'ютера
разом з операційною системою. p>
У деяких файлових системах базовий рівень доступний користувачеві, але більш
часто прикривається деякими більш високим рівнем, стандартним для користувачів. Поширені два основні підходи. При першому підході, властивому,
наприклад, файлових систем операційних систем фірми DEC RSX і VMS, користувачі представляють файл як послідовність записів. Кожен запис --
це послідовність байтів постійного або змінного розміру. Записи можна читати або записувати послідовно або позиціонувати файл на запис з
вказаним номером. Деякі файлові системи дозволяють структурувати запису на поля і оголошувати деякі поля ключами запису. У таких файлових системах
можна зажадати вибірку запису з файлу за її заданому ключу. Природно, що в цьому випадку файлова система підтримує в тому ж (або іншому,
службовому) базовому файлі додаткові, невидимі користувачеві, службові структури даних. Поширені способи організації ключових файлів грунтуються на
техніці хешування і B-дерев (ми будемо говорити про ці прийоми більш докладно в наступних лекціях). Існують і многоключевие способи організації
файлів. p>
Другий підхід, який став поширеним разом з операційною системою UNIX, полягає в
те, що будь-який файл представляється як послідовність байтів. З файлу можна прочитати зазначене число байтів або починаючи з його початку, або
попередньо зробивши його позиціонування на байт з вказаним номером. Аналогічно, можна записати вказане число байтів в кінець файлу, або
попередньо зробивши позиціонування файлу. Зауважимо, що тим не менш прихованим від користувача, але існуючим у всіх різновидах файлових систем
ОС UNIX, є базове блочне подання файлу. p>
Звичайно, для обох підходів можна забезпечити набір перетворюють функцій, що призводять
подання файлу до деякого іншого виду. Прикладом тому служить підтримання стандартної файлової середовища системи програмування мовою Сі в середовищі
операційних систем фірми DEC. p>
1.1.2.
Іменування файлів
Зупинимося коротко на способах найменування файлів. Всі сучасні файлові системи
підтримують багаторівневе іменування файлів за рахунок підтримки у зовнішній пам'яті додаткових файлів зі спеціальною структурою - каталогів. Кожен
каталог містить імена каталогів та/або файлів, що містяться в даному каталозі. Таким чином, повне ім'я файлу складається зі списку імен каталогів плюс назва файлу
в каталозі, безпосередньо містить цей файл. Різниця між способами найменування файлів в різних файлових системах полягає в тому, з чого починається
цей ланцюжок імен. p>
У цьому відношенні є два крайніх варіанти. У багатьох системах управління файлами потрібно, щоб кожен архів файлів (повне дерево довідників)
цілком розташовувався на одному дисковому пакеті (або логічному диску, у розділі фізичного дискового пакета, що надається за допомогою засобів операційної
системи як окремий диск). У цьому випадку повне ім'я файлу починається з імені дискового пристрою, на якому встановлений відповідний диск. Такий спосіб
іменування використовується в файлових системах фірми DEC, дуже близько до цього знаходяться і файлові системи персональних комп'ютерів. Можна назвати цю
організацію підтриманням ізольованих файлових систем. p>
Інший крайній варіант був реалізований в файлових системах операційної системи
Multics. Ця система заслуговує окремої великої розмови, в ній був реалізований цілий ряд оригінальних ідей, але ми зупинимося лише на
особливості організації архіву файлів. У файловій системі Miltics користувачі представляли всю сукупність каталогів і файлів, як єдине дерево. Повне ім'я
файлу починалося з імені кореневого каталогу, і користувач не зобов'язаний був піклуватися про встановлення на дисковий пристрій будь-яких конкретних дисків.
Сама система, виконуючи пошук файлу по його імені, запрошувала установку необхідних дисків. Таку файлову систему можна назвати повністю
централізованою. p>
Звичайно, багато в чому централізовані файлові системи зручніше ізольованих: система
управління файлами бере на себе більше рутинної роботи. Але в таких системах виникають суттєві проблеми, якщо комусь потрібно перенести
піддерево файлової системи на іншу обчислювальну установку. Компромісне рішення застосоване в файлових системах ОС UNIX. На базовому рівні в цих
файлових системах підтримуються ізольовані архіви файлів. Один з цих архівів оголошується кореневою файловою системою. Після запуску системи можна "змонтувати"
кореневу файлову систему і ряд ізольованих файлових систем в одну загальну файлову систему. Технічно це здійснюється за допомогою заклади в кореневий
файловій системі спеціальних порожніх каталогів. Спеціальний системний виклик кур'єр ОС UNIX дозволяє підключити до одного з цих порожніх каталогів кореневої
каталог зазначеного архіву файлів. Після монтування загальної файлової системи іменування файлів проводиться так само, як якщо б вона з самого початку була
централізованою. Якщо врахувати, що зазвичай монтування файлової системи здійснюється при розкручуванні системи, то користувачі ОС UNIX зазвичай і не
замислюються про вихідний походження загальної файлової системи. p>
1.1.3. Захист
файлів
Оскільки файлові системи є загальним сховищем файлів, що належать, взагалі
кажучи, різним користувачам, системи управління файлами повинні забезпечувати авторизацію доступу до файлів. У загальному вигляді підхід полягає в тому, що за
відношенню до кожному зареєстрованому користувачеві даної обчислювальної системи для кожного існуючого файлу вказуються дії, які дозволені
або заборонені даному користувачеві. Існували спроби реалізувати цей підхід у повному обсязі. Але це викликало дуже великі накладні витрати як
зі зберігання надлишкової інформації, так і з використання цієї інформації для контролю правомочності доступу. p>
Тому в більшості сучасних систем управління файлами застосовується підхід до захисту
файлів, вперше реалізований в ОС UNIX. У цій системі кожному зареєстрованому користувачеві відповідає пара цілочисельних
ідентифікаторів: ідентифікатор групи, до якої належить ця особа, і його власний ідентифікатор в групі. Відповідно, при кожному файлі
зберігається повний ідентифікатор користувача, який створив цей файл, і зазначається, які дії з файлом може виробляти він сам, які дії з
файлом доступні для інших користувачів тієї ж групи, і що можуть робити з файлом користувачі інших груп. Ця інформація дуже компактна, при перевірці
потрібна невелика кількість дій, і цей спосіб контролю доступу задовільний в більшості випадків. p>
1.1.4. Режим
багатокористувацького доступу
Останнє, на чому ми зупинимося у зв'язку з файлами, - це способи їх використання в
багатокористувацької середовищі. Якщо операційна система підтримує багатокористувацький режим, цілком реальна ситуація, коли дві або більше
користувачів одночасно намагаються працювати з одним і тим же файлом. Якщо всі ці користувачі збираються тільки читати файл, нічого страшного не станеться.
Але якщо хоча б одна з них буде змінювати файл, для коректної роботи цієї групи потрібна взаємна синхронізація. p>
Історично в файлових системах застосовувався наступний підхід. В операції відкриття файлу
(перша та обов'язкової операції, з якою повинен починатися сеанс роботи з файлом) крім інших параметрів вказувався режим роботи (читання або
зміна). Якщо до моменту виконання цієї операції від імені певної програми A файл вже знаходився у відкритому стані від імені деякої іншої програми
B (правильніше говорити "процесу", але ми не будемо вдаватися в термінологічні тонкощі), причому існуючий режим відкриття був
несумісним з бажаним режимом (сумісні тільки режими читання), то в залежності від особливостей системи програмі A або повідомлялося про неможливість
відкриття файлу в бажаному режимі, або вона блокувалася до тих пір, поки програма B не виконає операцію закриття файлу. p>
Зауважимо, що в ранніх версіях файлової системи ОС UNIX взагалі не були реалізовані які
Хай там як засоби синхронізації паралельного доступу до файлів. Операція відкриття файлу виконувалася завжди для будь-якого існуючого файлу, якщо даний
користувач мав відповідні права доступу. При спільній роботі синхронізацію слід було проводити поза файлової системи (і особливих засобів для
цього ОС UNIX не надавала). У сучасних реалізаціях файлових систем ОС UNIX за бажанням користувача підтримується синхронізація при відкритті файлів.
Крім того, існує можливість синхронізації декількох процесів, паралельно модифікуючих один і той же файл. Для цього введено спеціальний
механізм синхронізаційних захоплень діапазонів адрес відкритого файлу. p>
Області застосування файлів
Після цього короткого екскурсу в історію файлових систем розглянемо можливі області
їх застосування. Перш за все, звичайно, файли застосовуються для зберігання текстових даних: документів, текстів програм і т.д. Такі файли зазвичай утворюються і
модифікуються за допомогою різних текстових редакторів. Структура текстових файлів зазвичай дуже проста: це або послідовність записів, що містять
рядки тексту, або послідовність байтів, серед яких зустрічаються спеціальні символи (наприклад, символи кінця рядка). p>
Файли з текстами програм використовуються як вхідні тексти компіляторів, які в
свою чергу формують файли, що містять об'єктні модулі. З точки зору файлової системи, об'єктні файли також мають дуже проста структура --
послідовність записів або байтів. Система програмування накладає на цю структуру більш складну й специфічну для цієї системи структуру об'єктного
модуля. Підкреслимо, що логічна структура об'єктного модуля невідома файловій системі, ця структура підтримується програмами системи
програмування. p>
Аналогічно іде справа з файлами, формованими редакторами зв'язків та містять образи
виконуваних програм. Логічна структура таких файлів залишається відомою лише редактору зв'язків та завантажувачу - програму операційної системи. Приблизно
така ж ситуація з файлами, що містять графічну та звукову інформацію. p>
Одним словом, файлові системи зазвичай забезпечують зберігання слабо структурованої
інформації, залишаючи подальшу структуризацію прикладним програмам. У перерахованих вище випадках використання файлів це навіть добре, тому що при
розробці будь-якої нової прикладної системи спираючись на прості, стандартні і порівняно дешеві засоби файлової системи можна реалізувати ті структури
зберігання, які найбільш природно відповідають специфіці даної прикладної області. p>
Потреби інформаційних
систем
Однак ситуація докорінно відрізняється для згадуваних на початку лекції
інформаційних систем. Ці системи головним чином орієнтовані на зберігання, вибір і модифікацію постійно існуючої інформації. Структура інформації
найчастіше дуже складна, і хоча структури даних різні в різних інформаційних системах, між ними часто буває багато спільного. На початковому етапі
використання обчислювальної техніки для управління інформацією проблеми структуризації даних вирішувалися індивідуально в кожній інформаційній системі.
Проводилися необхідні надбудови над файловими системами (бібліотеки програм), подібно до того, як це робиться в компіляторах, редакторів і т.д. p>
Але оскільки інформаційні системи вимагають складних структур даних, ці додаткові індивідуальні засоби керування даними були істотною
частиною інформаційних систем і практично повторювалися від однієї системи до іншої. Прагнення виділити і узагальнити загальну частина інформаційних систем,
відповідальну за управління складно структурованими даними, стало, на наш погляд, перша спонукальної причиною створення СУБД. Дуже скоро стало зрозуміло,
що неможливо обійтися загальною бібліотекою програм, що реалізує над стандартної базової файловою системою більш складні методи зберігання даних. p>
Покажемо це на прикладі. Припустимо, що ми хочемо реалізувати просту інформаційну
систему, яка підтримує облік співробітників деякої організації. Система повинна виконувати наступні дії: видавати списки співробітниківв по відділах,
підтримувати можливість переведення працівника з одного відділу в інший, прийому на роботу нових співробітників і звільнення працюючих. Для кожного відділу має
підтримуватися можливість отримання імені керівника цього відділу, загальної чисельності відділу, загальної суми виплаченої в останній раз зарплати і т.д. Для
кожного співробітника повинна підтримуватися можливість видачі номера посвідчення по повному імені співробітника, видачі повного імені за номером
посвідчення, отримання інформації про поточний відповідність займаній посаді співробітника і про розмір його зарплати. p>
Припустимо, що ми вирішили засновувати цю інформаційну систему на файловій системі і
користуватися при цьому одним файлом, розширивши базові можливості файлової системи за рахунок спеціальної бібліотеки функцій. Оскільки мінімальної інформаційної
одиницею у нашому випадку є співробітник, природно вимагати, щоб в цьому файлі містилася одна запис для кожного співробітника. Які поля повинна
містити такий запис? Повне ім'я співробітника (СОТР_ІМЯ), номер його посвідчення (СОТР_НОМЕР), інформацію про його відповідність займаній посаді
(для простоти, "так" або "ні") (СОТР_СТАТ), розмір зарплати (СОТР_ЗАРП), номер відділу (СОТР_ОТД_НОМЕР). Оскільки ми хочемо обмежитися
одним файлом, та ж запис має містити ім'я керівника відділу (СОТР_ОТД_РУК). p>
Опції нашої інформаційної системи вимагають, щоб забезпечувалась можливість
многоключевого доступу до цього файлу за унікальними ключами (недубліруемим в різних записах) СОТР_ІМЯ і СОТР_НОМЕР. Крім того, повинна забезпечуватися
можливість вибору всіх записів з Загалом значенням СОТР_ОТД_НОМЕР, тобто доступ по неунікальному ключу. Для того, щоб отримати чисельність відділу або
загальний розмір зарплати, кожного разу при виконанні такої функції інформаційна система повинна буде вибрати всі записи про співробітників відділу і порахувати
відповідні загальні значення. p>
Таким чином ми бачимо, що навіть для такої простої системи її реалізація на базі
файлової системи, по-перше, вимагає створення досить складної надбудови для многоключевого доступу до файлів, і, по-друге, викликає вимога істотної
надмірності зберігання (для кожного співробітника одного відділу повторюється ім'я керівника) і виконання масової вибірки і обчислень для одержання
сумарної інформації про відділи. Крім того, якщо в ході експлуатації системи нам захочеться, наприклад, видавати списки співробітників, що одержують задану
зарплату, то доведеться або повністю переглядати файл, або реструктурізовивать його, оголошуючи ключовим поле СОТР_ЗАРП. p>
Перше, що спадає на думку, - це підтримувати два многоключевих файлу: СПІВРОБІТНИКИ і
ВІДДІЛИ. Перший файл повинен містити поля СОТР_ІМЯ, СОТР_НОМЕР, СОТР_СТАТ, СОТР_ЗАРП і СОТР_ОТД_НОМЕР, а другий - ОТД_НОМЕР, ОТД_РУК, ОТД_СОТР_ЗАРП (загальний
розмір зарплати) і ОТД_РАЗМЕР (загальна кількість співробітників у відділі). Більшість незручностей, перелічених у попередньому абзаці, будуть подолані. Кожен з
файлів буде містити тільки недубліруемую інформацію, потреби в динамічних обчисленнях сумарної інформації не виникає. Але зауважимо, що при
такий перехід наша інформаційна система повинна володіти деякими новими особливостями, що зближують її з СУБД. p>
Перш за все, система повинна тепер знати, що вона працює з двома інформаційно
пов'язаними файлами (це крок у бік схеми бази даних), повинна знати структуру та зміст кожного поля (наприклад, що СОТР_ОТД_НОМЕР у файлі СПІВРОБІТНИКИ
і ОТД_НОМЕР у файлі ВІДДІЛИ означають одне й те саме), а також розуміти, що в ряді випадків зміна інформації в одному файлі має автоматично викликати
модифікацію в другому файлі, щоб їх загальний вміст було узгодженим. Наприклад, якщо на роботу приймається новий працівник, то необхідно додати
запис у файл СПІВРОБІТНИКИ, а також відповідним чином змінити поля ОТД_ЗАРП і ОТД_РАЗМЕР у записі файла ВІДДІЛИ, яка описує відділ цього
співробітника. p>
Поняття узгодженості даних є ключовим поняттям баз даних. Фактично, якщо інформаційна система (навіть така проста, як у нашому прикладі)
підтримує узгоджене зберігання інформації в декількох файлах, можна говорити про те, що вона підтримує базу даних. Якщо ж деяка
Допоміжна система керування даними дозволяє працювати з декількома файлами, забезпечуючи їх узгодженість, можна назвати її системою управління
базами даних. Вже тільки вимога підтримки узгодженості даних в декількох файлах не дозволяє обійтися бібліотекою функцій: така система
повинна мати деякі власні дані (метадані) і навіть знання, що визначають цілісність даних. p>
Але це ще не все, що зазвичай вимагають від СУБД. По-перше, навіть у нашому прикладі
незручно реалізовувати такі запити як "видати загальну чисельність відділу, в якому працює Петро Іванович Сидоров". Було б набагато простіше, якби
СУБД дозволяла сформулювати такий запит на близькій користувачам мовою. Такі мови називаються мовами запитів до баз даних. Наприклад, на
мовою SQL наш запит можна було б виразити у формі: p>
SELECT ОТД_РАЗМЕР p>
FROM СПІВРОБІТНИКИ, ВІДДІЛИ p>
WHERE СОТР_ІМЯ = "ПЕТРО ІВАНОВИЧ СИДОРОВ" p>
AND СОТР_ОТД_НОМЕР = ОТД_НОМЕР p>
Таким чином, при формулюванні запиту СУБД дозволить не замислюватися про те, як
буде виконуватися цей запит. Серед її метаданих буде міститися інформація про те, що поле СОТР_ІМЯ є ключовим для файлу СПІВРОБІТНИКИ, а ОТД_НОМЕР --
для файла ВІДДІЛИ, і система сама скористається цим. Якщо ж виникне потреба в отриманні списку співробітників, які не відповідають займаній
посади, то достатньо пред'явити системі запит p>
SELECT СОТР_ІМЯ, СОТР_НОМЕР p>
FROM СПІВРОБІТНИКИ p>
WHERE СОТР_СТАТ = "НІ", p>
і система сама виконає необхідний повний перегляд файлу СПІВРОБІТНИКИ, оскільки
поле СОТР_СТАТ не є ключовим. p>
Далі, уявіть собі, що в нашій первісної реалізації інформаційної системи,
заснованої на використанні бібліотек розширених методів доступу до файлів, обробляється операція реєстрації нового співробітника. Слідуючи вимогам
узгодженої зміни файлів, інформаційна система вставила новий запис у файл СПІВРОБІТНИКИ і збиралася модифіковані запис файла ВІДДІЛИ, але саме в
цей момент відбулося аварійне вимикання живлення. Очевидно, що після перезапуску системи її база даних буде знаходитися в рассогласованном
стані. Буде потрібно з'ясувати це (а для цього потрібно явно перевірити відповідність інформації з файлах СПІВРОБІТНИКИ і ВІДДІЛИ) і привести інформацію в
узгоджене стан. Справжні СУБД беруть таку роботу на себе. Прикладна система не зобов'язана піклуватися про коректність стану бази даних. p>
Нарешті, уявимо собі, що ми хочемо забезпечити паралельну (наприклад, багатотермінальних) роботу з базою даних співробітників. Якщо спиратися лише на
використання файлів, то для забезпечення коректності на весь час модифікації будь-якого з двох файлів доступ інших користувачів до цього файлу буде
блокований (згадайте можливості файлових систем для синхронізації паралельного доступу). Таким чином, зарахування на роботу Петра Івановича
Сидорова істотно загальмує отримання інформації про співробітника Іван Сидорович Петрове, навіть якщо вони будуть працювати в різних відділах. Справжні
СУБД забезпечують набагато більш тонку синхронізацію паралельного доступу до даних. p>
Таким чином, СУБД вирішують безліч проблем, які важко або взагалі
неможливо вирішити при використанні файлових систем. При цьому існують програми, для яких цілком достатньо файлів; додатки, для яких
необхідно вирішувати, який рівень роботи з даними у зовнішній пам'яті для них потрібна, і додатки, для яких безумовно потрібні бази даних. p>