Мир InterBase. Архитектура, администрирование и разработка приложений баз данных в InterBase/FireBird/Yaffil
Шрифт:
Довольно забавно в первый раз узнать, что все метаданные, - как пользовательские таблицы, триггеры, представления, так и все системные объекты, - хранятся в таких же точно таблицах, из которых можно читать и писать данные с помощью обычных SQL-запросов. Эти таблицы "визуально" отличаются только тем, что их имена начинаются с RDB$. Эти 4 символа зарезервированы для имен системных объектов, ни одна пользовательская таблица, столбец или другой объект не имеют права обладать именами, начинающимися с этих символов. Формально ничто не мешает создать вам таблицу, название которой начинается с зарезервированных символов, однако документация InterBase настойчиво не рекомендует этого делать.
Возникает вопрос: если данные о структуре таблиц базы данных хранятся в точно таких же таблицах, как и пользовательские, то где хранится информация о самих этих таблицах, которые описывают
Мы уже говорили о таблице RDB$Pages, которая ставит в соответствие физические страницы в файлах базы данных определенным объектам этой базы данных. Структура этой таблицы приведена в табл. 4.24:
Табл 4.24. Системная таблица RDB$Pages
Column name (имя поля) | Datatype (тип данных) | Description (описание) |
RDB$PAGE_NUMBER | INTEGER | Номер физической страницы |
RDB$RELATION_ID | SMALLINT | Идентификатор таблицы, для которой распределена страница |
RDB$PAGE_SEQUENCE | INTEGER | Порядковый номер этой страницы |
RDB$PAGE_TYPE | SMALLINT | Тип страницы - см. таблицу 4.22 |
Каждая страница данных в базе данных поставлена в соответствие какой- либо таблице, т. е. RELATION. Эту связь поддерживает поле RDB$RE- LATION_ID, в котором хранится ссылка на таблицу. Как было описано выше, в процессе построения внутреннего образа базы, сервер по определенному жестко "зашитому" в него алгоритму строит эту таблицу и наполняет ее данными. Если быть точным, то в момент построения образа базы данных RDB$Pages является не таблицей, а просто массивом данных определенного формата, известного InterBase. На основании определенного алгоритма сервер считывает данные из этого массива и строит следующую критическую для всей базы таблицу - RDB$Relations. Эта таблица описывает все таблицы базы. Если мы сделаем SQL-запрос: SELECT " from RDB$Relations с целью выяснить, ссылки на какие таблицы содержит RDBSRELATIONS, гочви шм. что она содержит и RDBSPages, и саму себя. Очевидно, что в данном случае сервер слегка "хитрит", "задним числом" подставляя эти и остальные системные таблицы в RDB$Relations, таким образом, "легализуя" их. Сервер регистрирует их как "нормальные" таблицы, в которые можно добавить записи или удалить, т. е. предоставляет стандартный SQL-интерфейс для работы с метаданными.
Может возникнуть вполне резонный вопрос: зачем бы разработчикам InterBase "подстраивать" свои системные данные под пользовательский интерфейс? Ведь внутренние механизмы доступа и чтения были бы быстрее. Разумеется, есть большой резон в том, чтобы предоставить универсальный механизм работы с таблицами, описывающими метаданные.
Дело в том. что логическая структура базы данных состоит не только из таблиц, но и из других объектов. В InterBase существуют следующие объекты:
* Table (таблица);
* View (представление);
* Trigger (триггер);
* Computed_field (вычисляемое поле);
* Validation (проверка);
* Procedure (процедура);
* Epression_index (вычисляемый индекс);
* Exception (исключение);
* User (польюватель),
* Field (поле);
* Index (индекс);
* Usei-Defined Function (UDF) - функция, определяемая пользователем.
Пока, может быть, не совсем очевидно назначение некоторых из этих объектов, но ясно, что их необходимо описывать и хранить в некотором виде, удобном как для пользователя, так и для доступа из ядра InterBase. Лучше всего это сделать, сохранив все эти объекты в системных таблицах. Их добавление и модификация производятся с помощью SQL-запросов. Не правда ли, элегантное решение9 Реализация сервера полностью отделена от
Итак, все объекты сервера хранятся в таблицах. Для каждого вида объектов существует таблица, описывающая все экземпляры, описанные в базе данных. Например, для триггеров есть таблица RDB$Triggers, для процедур - RDBSProcedures, а представления описываются в таблице RDBSRelations.
Рассмотрим подробнее структуру последней таблицы, описывающей все таблицы и представления в базе данных. Структура таблицы RDBSRELATIONS вта из Language Reference for InterBase 6 и приведена в Табл 4 25
Табл 4.25. Системная таблица RDB$Relations
Колонка | Тип данных | Длина | Описание |
RDB$VIEW_BLR | BLOB | 80 | BLR: Для представлений (view), содержит BLR (Binary Language Representation) запроса, который InterBase осуществляет каждый раз, когда идет обращение к представлению |
RDB$VIEW SO URGE | BLOB | 80 | Текст: Для представлений содержит код SQL-запроса, который реализует это представление |
RDB$ DESCRIP TION | и | 80 | Пользовательское описание таблицы или представления |
RDBSRELATIO NJD | SMALLINT | Содержит внутренний идентификатор таблицы/представления | |
RDB$SYSTEM FLAG | II | Определяет тип содержимого таблицы: Пользовательские данные - 0; Системная информация > 0 | |
RDB$DBKEY LE NGTH | N | Длина db$key | |
RDB$FORMAT | II | Зарезервировано для внутреннего использования InterBase Содержит счетчик изменений метаданных для данной таблицы | |
RDB$FIELD_ID | u | Число полей в таблице | |
RDB$RELATIO N_NAME | CHAR | 31 | Уникальное имя таблицы |
В описании этой системной таблицы встречается аббревиатура BLR Чтобы понять, что это такое, придется сделать небольшой экскурс в SQL. Как известно, представления, триггеры и хранимые процедуры - это код, написанный на расширении языка SQL (для каждого сервера СУБД существуют свои расширения. Он приближен к человеческому языку, что позволяет легко составлять на нем запросы Но InterBase, очевидно, преобразовывает его во что-то более "машинное", а именно в BLR (Binary Language Representation), "твоичное" представление языка (SQL, очевидно). Любой запрос, триггер, представление, хранимая процедура обязательно транслируются в BLR, а уж затем передаются для исполнения ядру InterBase.
BLR
BLR - это специальный язык, используемый в качестве промежуточного звена между SQL-кодом, который пишет программист, и машинным кодом, который "воспринимает" сервер. Никто не пишет непосредственно на BLR - это было бы весьма затруднительно, так как для максимального быстродействия в этом языке используется так называемая обратная польская запись. Вот маленький пример: blr_begin,
bir_assignment,
blr_field, 0, 7, 'D1 , 'А', "I" , 'Е1 , 'I', 'Z', 'М1 ,