Книга: Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ

Физические объекты

Физические объекты

Таблицы

Таблица базы данных обычно визуализируется в виде двумерного блока, состоящего из столбцов (вертикальная размерность) и строк (горизонтальная размерность). Хранимые атрибуты индивидуальных элементов данных задаются в столбцах (обычно связанных с или зависящих от другого столбца) и строках. Таблица может иметь любое количество строк (до 232) или совсем ни одной строки. Хотя каждая строка в одной таблице совместно использует спецификации ее столбцов с любой другой строкой, строки не зависят от других строк в той же таблице.

! ! !

СОВЕТ. Firebird поддерживает техники реализации ссылающихся на себя таблиц - структура строк, которая задает зависимости между строками в той же таблице. Подробности см. в разд. "Ссылающиеся на себя отношения" главы 17.

. ! .

Файлы и страницы

Если вы переходите на Firebird с системы баз данных, которая реализует таблицы в виде физических столбцов и строк файловой системы, то Firebird может преподнести вам некоторые сюрпризы. В Firebird все данные одной базы данных хранятся в одном файле или во множестве связанных файлов. В многофайловых базах данных не существует взаимозависимости между любым объектом базы данных и отдельным элементом множества файлов базы данных.

В рамках файла сервер Firebird управляет блоками диска одного размера, называемыми страницами базы данных. Он управляет некоторыми различными "типами" страниц в соответствии с хранимыми типами данных - например, обычные столбцы таблицы, BLOB, индексы. Когда требуется, сервер размещает новый блок в файловой системе хоста. Все страницы независимо от типа имеют одинаковый размер. Размер страницы должен быть указан в операторе CREATE DATABASE. Он может быть изменен только при выполнении резервного копирования и восстановления базы данных с новым размером страницы при использовании утилиты gbak.

В отличие от файловых систем управления данными Firebird совсем не поддерживает данные таблиц в табличном формате. Строки одной таблицы могут не находиться рядом с другими строками той же таблицы. В действительности строки одной таблицы могут размещаться в разных файлах и на разных дисках. Сервер использует разнообразные типы инвентарных страниц для хранения информации о физическом расположении строк, принадлежащих каждой таблице.

Столбцы и поля

Обобщенно, столбец является совокупностью атрибутов, определяющих элемент данных, который может быть сохранен в одной указанной ячейке в структуре строки таблицы слева направо. При этом столбцы фактически не существуют в таблицах базы данных. Каждый раз, когда запрос обращается к серверу, этот запрос задает набор столбцов и одну или более операций, выполняемых над этими столбцами. Столбцы не обязательно должны располагаться в том же порядке слева направо, как они были определены в таблице. Например, оператор SELECT FIELD3, FIELD1, FIELD2 FROM ATABLE;

выведет набор, где порядок столбцов будет соответствовать указанному в запросе. Запрос может указывать столбцы из разных таблиц: соединений, подзапросов, объединений. Он может определять столбцы, вовсе отсутствующие в базе данных, сделав их вычисляемыми или даже просто задавая их как именованные константы.

Некоторые люди используют термин "поле" вместо столбца, например: "У меня есть таблица TABLEI, содержащая три поля". Часто книги по реляционным базам данных не одобряют использование "поле" как замена для "столбец", предпочитая использовать "поле" в смысле "значение в столбце" или "ссылка на столбец".

В этой книге "поле" используется только как термин для обобщения концепции столбца, аргумента и локальной переменной и для ссылок на выходные элементы, создаваемые во время выполнения. "Столбец" используется для ссылок на физические столбцы, определенные для таблиц.

Ключи

Первичный ключ

Основной частью процесса проектирования базы данных является выделение в логической модели базы данных для каждой таблицы одного уникального столбца или структуры из нескольких столбцов, которая отличает каждую строку от любой другой строки в таблице. Такой уникальный столбец или комбинация столбцов является логическим первичным ключом (primary key). Когда вы создаете вашу физическую модель, вы используете ограничение PRIMARY KEY, чтобы сообщить СУБД, какой столбец или столбцы формируют такую уникальную идентификационную структуру. На таблицу вы можете определить только одно ограничение PRIMARY KEY. Синтаксис рассматривается в разд. "Ограничения" главы 16.

Другие уникальные ключи

В процессе вашего моделирования может случиться так, что по разным причинам вам будет нужно более одного уникального столбца или структуры столбцов в таблице. Для поддержания требуемой уникальности таких столбцов или структур Firebird предоставляет ключ-ограничение UNIQUE. Это является альтернативой первичному ключу и при необходимости иногда может быть использовано вместо первичного ключа.

Внешние ключи

"Кабелями", которые делают реляционную базу данных "реляционной", являются внешние ключи (foreign key). Это столбец или структура столбцов, которая в вашей модели данных является стороной "многие" в отношении один-ко-многим. При физическом проектировании внешний ключ соответствует столбцу или структуре столбцов первичного ключа таблицы стороны "один" в этом отношении.

В следующей простой модели для примера детальные строки заказа связаны с заголовком заказа через ключ ORDER_NUMBER.


Рис. 14.1. Простая связь

Такая модель требует, чтобы каждая строка заголовка имела уникальный ORDER_NUMBER и существовала, по меньшей мере, одна детальная строка заказа для каждой заголовочной строки заказа. Другие правила могут применяться к факту существования и к связи. Firebird предоставляет мощные процедуры триггеров для установки, согласования и применения правил к отношениям. Дополнительно он может автоматизировать множество типичных правил управления отношениями, включая ограничение FOREIGN KEY С дополнительными аргументами действий. Основой для такого ограничения являются сгенерированные системой триггеры ссылочной целостности. Поддержка ссылочной целостности в Firebird вкратце обсуждалась ранее в разд. "Ссылочная целостность" и будет детально рассмотрена в главе 17.

Суррогатные ключи

Столбец, который в вашем анализе был определен как первичный ключ, или элемент первичного ключа почти всегда хранит элемент данных, имеющий некоторое значение. Возьмем, к примеру, таблицу, хранящую данные о человеке:

CREATE TABLE PERSON {

FIRST_NAME VARCHAR(30) NOT NULL,

LAST NAME VARCHAR(50) NOT NULL,

PHONE_NUMBER VARCHAR(18) NOT NULL,

ADDRESS_1 VARCHAR(50),

. . . );

Проектировщик принимает решение, что комбинация (FIRST_NAME, LAST_NAME, PHONE NUMBER) является хорошим кандидатом для первичного ключа. Люди могут использовать один и тот же телефонный номер, но весьма маловероятно, что два человека с одинаковыми именем и фамилией будут использовать один и тот же номер телефона, верно? Таким образом, проектировщик делает следующее:

ALTER TABLE PERSON

ADD CONSTRAINT PK_PERSON PRIMARY KEY

(LAST_NAME, FIRST_NAME, PHONE_NUMBER) ;

Первая проблема с этим первичным ключом в том, что каждый элемент имеет смысл. Каждый элемент поддерживается человеком и может быть изменен или записан с ошибками. Два ключа ('Smith', 'Mary', '43889474') и ('SMITH', 'Mary', '43889474') Не являются одинаковыми и оба могут быть помещены в эту таблицу. Какая запись будет изменена, если магу выйдет замуж или изменит номер телефона?

Вторая проблема заключается в том, что этот сложный ключ будет распространяться в качестве внешнего ключа в любых таблицах, зависящих от PERSON. Подвергается риску не только целостность этого отношения при изменениях или ошибках в данных, но это также требует большого объема памяти - потенциально 98 символов - при реализации отношения внешнего ключа.

Реальные накладки могут появиться, если эти столбцы используют многобайтовые наборы символов или не двоичные порядки сортировки. Размеры индексов ограничены 252 байтами. Для ключей обязательно создаются индексы. Такой ключ будет невозможен просто по причине слишком большого размера.

Создание атомарного ключа

Важным принципом для хорошего проектирования реляционной базы данных является атомарность. В контексте первичных и внешних ключей атомарность означает, что никакой ключ как элемент данных не должен иметь смысл; он не должен иметь никакой другой роли или функции, кроме как быть ключом.

Решение заключается в добавлении дополнительного столбца в таблицы для использования в качестве искусственного или суррогатного первичного ключа - уникальный, ограниченного размера столбец, желательно генерируемый системой, который заменяет (замещает) функцию теоретического первичного ключа. Firebird предоставляет объекты GENERATOR, которые могут быть использованы для создания требуемых уникальных серий чисел BIGINT для первичного ключа размером 8 байт или меньше.

Общую технику реализации автоинкрементного первичного ключа (при отсутствии ручной работы) см. в разд. "Генераторы" главы 9 ив главе 31.

! ! !

ВНИМАНИЕ! Атомарность ключа должна поддерживаться в приложениях сокрытием его от пользователя или хотя бы его свойством только для чтения.

. ! .

Итог - суррогатные ключи против естественных ключей

Разработчики баз данных обычно занимают четкую позицию "за" или "против" использования суррогатных ключей. Позиция автора по использованию атомарности очевидна. Несмотря на это, в интересах справедливости аргументы за и против представлены в табл. 14.1.

Таблица 14.1. Суррогатные (искусственные) ключи в сравнении с естественными

Особенность

За

Против

Атомарность

Суррогатные ключи не воспринимаются как данные и никогда не изменяются

Естественные ключи по своей сути нестабильны, потому что они являются предметом человеческих ошибок и внешних изменений

Удобство

Естественные ключи несут информацию, сокращающую необходимость выполнения соединений или дополнительных чтений для поиска данных в контексте.

Естественные ключи более удобны при использовании в интерактивных инструментах запросов

Суррогатные ключи не несут никакой информации помимо их функции связи, требования соединений или подзапросов поиска связанных "осмысленных" данных

Размер ключа

Суррогатные ключи компактны

Естественные ключи имеют больший размер и часто усложняют составные ключи, которые усложняют запросы и схему

Навигация

Суррогатные ключи обеспечивают чистую, быструю навигацию по коду

Естественные ключи обычно не являются подходящими при навигации в стиле кода по причине порядка сортировки, денормализации и размера

Нормализация

Суррогатные ключи могут быть нормализованы в базе данных

Естественные ключи имеют тенденцию к усложнению, распространению денормализации данных внешних ключей

Должны ли вы проектировать базу данных, смешивая естественные и искусственные ключи? Крайней точкой зрения является последовательный подход в проектировании - выберите естественные или искусственные ключи и применяйте это правило без исключений. Однако более умеренный подход может предоставить лучшее из обоих миров. Практичным является использование естественных ключей для стабильных "управляющих" таблиц соответствия, ключей, которые редко изменяются, никогда не участвуют в составных ключах и часто появляются в выходных данных.

! ! !

ВНИМАНИЕ! При проектировании ключей для базы данных Firebird помните, что ключи порождают индексы, а индексы в Firebird ограничены в размере до 252 байт. Сложные последовательности сортировки и многобайтовые международные наборы символов уменьшают количество символов в данных, которые могут быть использованы в качестве индексов.

. ! .

Ключи не являются индексами

Индексы не являются ключами. Ключи- ограничения на уровне таблицы. Сервер базы данных реагирует на объявление ограничений созданием множества объектов базы данных для их поддержки. Для ограничений первичных и уникальных ключей он создает уникальный индекс из столбца (столбцов), указанных в ограничениях. Для внешних ключей он создает неуникальный индекс из указанных столбцов, сохраняет записи для отношения и создает триггеры для выполнения нужных действий.

* Ключи являются ограничениями.

* Индексы требуются для поддержания ограничений.

! ! !

ВНИМАНИЕ! Вы не должны создавать свои собственные индексы, которые дублируют создаваемые системой индексы для поддержания ограничений. Это является важной мерой предосторожности в отношении производительности, о чем неоднократно повторяется в разных местах книги. Разд. "Темы оптимизации" главы 18 объясняет, почему дублирование таких индексов может ухудшить производительность запросов.

. ! .

Ссылочная целостность данных

Случайное изменение или удаление строк, имеющих зависимости, разрушает целостность ваших данных. Обычно ссылочная целостность данных является выражением, описывающим уровень, на котором зависимости базы данных защищены от разрушения. В контексте настоящего руководства мы ссылаемся на встроенные механизмы поддержки отношений внешних ключей и выполнения желаемых действий при изменении значения первичного ключа в главной таблице или при удалении строки этой таблицы.

Синтаксис ограничений формальной ссылочной целостности данных Firebird подробно обсуждается в главе 17.

Индексы и планы запросов

Если внешние ключи являются "кабелями", делающими базу данных реляционной, то индексы могут рассматриваться как поставщики "полосы частот". Хорошее индексирование повышает скорость; отсутствие индексов или плохие индексы замедляют поиск, соединение и сортировку.

Как средство управления реляционной базой данных, Firebird может связать почти любой объект столбца с почти любым другим объектом столбца (за исключением различных типов BLOB, включая массивы) с использованием ссылок на их идентификаторы. Однако при увеличении количества строк, связанных столбцов и таблиц в запросах производительность падает.

Когда столбцы, которые отыскиваются, соединяются и сортируются, индексированы удобным образом, производительность (время выполнения и использования ресурсов) может резко улучшиться. Необходимо также сказать, что слабое индексирование может резко ухудшить производительность!

Firebird использует алгоритмы оптимизации, которые в большой мере основаны на оценке затрат (cost-based). При подготовке запроса оптимизатор вычисляет относительные стоимости использования или игнорирования доступных индексов и возвращает клиенту план запроса, сообщая о своем выборе. Хотя можно разработать и передать оптимизатору ваш собственный план запроса- важное средство серверов реляционных СУБД, которые используют оптимизацию, основанную на правилах, - чаще всего оптимизатор Firebird знает лучше. Планы Firebird являются более полезными в выявлении и устранении проблем с индексами.

Проектирование и создание индексов рассматривается в главе 18.

Просмотры

Firebird предоставляет возможность создания и сохранения предварительно определенных спецификаций запросов, называемых просмотрами (view), которые в большинстве случаев могут рассматриваться просто как если бы они были таблицами. Просмотр является классом наследуемой таблицы, которая хранит данные. Для многих задач - особенно для тех, когда доступ к отдельным столбцам таблиц нужно запретить или когда спецификация отдельного запроса не может предоставить требуемый уровень абстракции - просмотры решают сложные проблемы.

Просмотры и другие наследуемые таблицы обсуждаются в главе 24 и должны изучаться вместе с другими главами части V.

Хранимые процедуры и триггеры

Хранимые процедуры и триггеры являются модулями компилированных, выполняемых кодов, которые выполняются на сервере. Исходный код пишется на расширении языка SQL, называемом процедурным SQL, или PSQL.

Хранимые процедуры могут быть выполняемыми процедурами и селективными процедурами. Они могут получать входные аргументы и возвращать выходные наборы. Выполняемые процедуры выполняются полностью на сервере и могут возвращать набор констант из одной строки (одиночный набор) по завершении выполнения. Селективные процедуры генерируют многострочные наборы из нуля или более строк, которые могут использоваться клиентскими приложениями различными способами, как и любой другой выходной набор.

Триггеры являются специализированным видом модулей PSQL, которые могут быть объявлены для выполнения в одном или более из шести состояний/фаз операции (до и после добавления, изменения и удаления) в процессе операций манипулирования данными (DML) таблицы, которая владеет этими триггерами. Группы триггеров могут быть объявлены для каждой фазы для выполнения в определенной последовательности. Начиная с релиза 1.5, поведение любой или всех операций DML могут быть объединены с условиями выполнения в один модуль триггера "до" или "после". Триггеры не принимают входных аргументов и не возвращают выходных наборов.

Хранимые процедуры могут вызывать другие хранимые процедуры. Триггеры могут вызывать хранимые процедуры, которые, в свою очередь, могут вызывать другие хранимые процедуры. Триггеры не могут быть вызваны ни из клиентских приложений, ни из хранимых процедур.

PSQL имеет механизмы обработки исключений и внешних событий. Любое количество сообщений об исключениях может быть определено в качестве объектов базы данных с использованием операторов CREATE EXCEPTION. Внешние события создаются внутри модуля PSQL, а приложения могут устанавливать структуры для их "прослушивания".

Подробное обсуждение написания и использования модулей PSQL, исключений и событий см. в части VII.

Оглавление книги


Генерация: 0.094. Запросов К БД/Cache: 0 / 0
поделиться
Вверх Вниз