- •20.7. Средства sql
- •20.8. Резюме
- •21.1. Введение
- •21.2. Некоторые аспекты технологам поддержки принятия решений
- •21.3. Проектирование базы данных поддержки принятия решений
- •21.5. Хранилища данных и магазины данных
- •21.6. Оперативная аналитическая обработка
- •21.7. Разработка данных
- •21.8. Резюме
- •22.1. Введение
- •22.2. Хронологические данные
- •22.3. Основная проблема хронологических баз данных
- •22.4. Интервалы
- •22.5. Интервальные типы
- •22.6. Скалярные операторы для интервалов
- •22.7. Операторы обобщения для интервалов
- •22.8. Реляционные операторы для обработки интервалов
- •22.9. Ограничения, включающие интервалы
- •22.10. Операторы обновления, включающие интервалы
- •22.11. Проектирование базы данных
- •22.12. Резюме
- •23.1. Введение
- •23.2. Обзор основных концепций
- •23.3. Исчисление высказываний
- •23.4. Исчисление предикатов
- •23.5. Базы данных с точки зрения доказательно-теоретического подхода
- •23.6. Дедуктивные субд
- •23.7. Обработка рекурсивных запросов
- •23.8. Резюме
- •Часть VI
- •24.1. Введение
- •24.2. Объекты, классы, методы и сообщения
- •24.3. Еще раз об объектах и объектных классах
- •Cdo для класса set (ref(emp))
- •24.4. Простой пример
- •1 | Course с001 , с001 0ffs , с001 ny offs |
- •24.5. Дополнительные аспекты
- •24.6. Резюме
- •25.1. Введение
- •X2 rational, y2 rational ) ... ;
- •25.2. Первая грубейшая ошибка
- •25.3. Вторая грубейшая ошибка
- •25.4. Вопросы реализации
- •25.5. Преимущества реального сближения двух технологий
- •25.6. Резюме
21.3. Проектирование базы данных поддержки принятия решений
Как утверждалось ранее, в частности во введении к части III, по нашему мнению, проект базы данных всегда должен быть выполнен на двух уровнях: логическом и физическом.
Прежде всего должен быть выполнен логический проект. На этом уровне основное внимание уделяется реляционной корректности. Таблицы должны представлять правильные отношения, гарантируя таким образом, что реляционные операции будут выполняться так, как им надлежит выполняться, и не будет никаких непредсказуемых результатов. Далее должны быть описаны домены (типы), на основе доменов определены столбцы и указаны зависимости между столбцами (функциональные и др.). На основании этих данных может быть выполнена нормализация и определены ограничения целостности.
Затем создается физический проект, который должен быть производным от логического проекта. На этом уровне, конечно, основное внимание уделяется эффективности хранения данных и производительности. В принципе, допустимо любое расположение данных при условии, что между логической и физической схемами имеется сохраняющее информацию преобразование, поддающееся выражению с помощью реляционной алгебры [2.5]. Отметим, в частности, что из наличия такого преобразования следует, что существуют реляционные представления физической схемы, которые отображают ее подобно логической схеме, и наоборот.
Особенно
виновны в этом специалисты по хранилищам
данных и оперативной аналитической
обработке (OLAP).
Они
часто утверждают, что реляционный
проект просто "непригоден" для
систем поддержки принятия решений, а
реляционная модель не способна
обеспечить выборку данных и ее нужно
обойти. Такие аргументы почти всегда
основываются на неверном понимании
различий между собственно реляционной
моделью и ее физическим представлением.
SP и P на физическом уровне, сократив таким образом количество операций ввода-вывода и расходы на соединения этих таблиц. Но логическая схема должна оставаться неизменной, если достигнута физическая независимость данных. (Конечно, оптимизатор запросов должен знать о существовании хранимого "предварительного соединения" и действовать соответственно, чтобы получить желаемое повышение производительности.) Кроме того, если модель доступа затем изменится на преобладающий доступ к отдельным таблицам вместо их соединения, должна существовать возможность вновь изменить физическую схему, чтобы физически разъединить таблицы SP и Р, опять же, без какого-либо влияния на логический уровень.
Из сказанного выше должно быть ясно, что проблема обеспечения независимости физических данных — это, в основном, проблема обновления представления поддержки (исключая проблему обновления фрагментов, которая обсуждалась в главе 20 и имеет совсем другой смысл во всей архитектуре системы). Как мы убедились в главе 9, теоретически все реляционные представления обновляемы. Следовательно, теоретически, если физическая схема является производной от логической схемы в смысле, который имелся в виду выше, будет достигнута максимальная физическая независимость данных. Любое обновление, выраженное в терминах логической схемы, будет автоматически транслируемым в обновление, выраженное в терминах физической схемы, и наоборот, а сами изменения физической схемы не будут требовать изменений в логической схеме.
Замечание. Отметим, что единственной причиной подобных изменений в физической схеме должно быть обеспечение эффективности хранения данных и повышение общей производительности системы.
Однако, к сожалению, современные SQL-продукты не поддерживают в необходимой мере обновление представлений. Поэтому набор допустимых физических схем в этих продуктах очень (и совершенно излишне) ограничен. Говоря конкретнее, если мы на логическом уровне рассматриваем базовые таблицы как представления, а хранимые версии этих "представлений" на физическом уровне — как базовые таблицы, физическая схема должна быть такой, чтобы рассматриваемый продукт мог реализовать все логически возможные обновления таких "представлений" в терминах этих "базовых таблиц".
Замечание. На практике это возможно благодаря моделированию подходящего механизма обновления представления средствами хранимых процедур, триггерных процедур, промежуточного программного обеспечения или различных их сочетаний. Однако обсуждение этих методов выходит за рамки данной главы.
Логическое проектирование
Правила логического проектирования не зависят от предполагаемого использования базы данных. То же самое относится ко всем без исключения видам приложений. Следовательно, в частности, должно быть все равно, какими являются эти приложения: оперативными (OLTP) или приложениями поддержки принятия решений. В любом случае должна использоваться одна и та же процедура. Еще раз рассмотрим три логические характеристики баз данных поддержки принятия решений, определенные в начале раздела 21.2, а также рассмотрим их следствия для логического проектирования.
■ Использование сочетаний столбцов и уменьшение количества зависимостей
В запросах поддержки принятия решений, а также в обновлениях, если они применимы, сочетания столбцов часто рассматриваются как единое целое. Имеется в виду, что к входящим в состав подобных сочетаний столбцам никогда не обращаются по отдельности (наглядным примером может служить адрес ADDRESS). Условимся называть такие сочетания столбцов составными столбцами. Но с логической точки зрения подобные составные столбцы ведут себя так, как будто на самом деле они не составные. Предположим, что СС — это составной столбец и С — какой-либо иной столбец в той же таблице. Тогда зависимости между столбцом С и компонентами столбца СС сводятся к одной зависимости между столбцом С и составным столбцом СС как единым целым. Более того, зависимости, включающие компоненты составного столбца СС и не включающие никакие другие столбцы, излишни и могут просто игнорироваться. В результате общее число зависимостей сокращается и логический проект становится проще, с меньшим количеством столбцов и, возможно, даже с меньшим числом таблиц.
Замечание. Стоит еще упомянуть о том, что полная и эффективная поддержка составных столбцов— задача нетривиальная и зависит от типов, определенных пользователем. Дополнительный материал по этому вопросу можно найти в [21.11], а также в главах 5 и 25.
■ Общие ограничения целостности
Как уже объяснялось, базы данных поддержки принятия решений, главным образом, только читаются и ограничения целостности проверяются при загрузке (или обновлении) базы данных. Поэтому часто полагают, что нет никакого смысла в объявлении ограничений целостности в логической схеме. Однако это звучит неубедительно. Если база данных действительно лишь читается, такие ограничения на самом деле не могут быть нарушены. Но нельзя недооценивать семантическое значение этих ограничений. Как уже отмечалось в разделе 8.10 главы 8, ограничения служат для определения смысла таблиц и всей базы данных в целом. Определение ограничений предоставляет способ передачи пользователям смысла данных, а значит, помогает им в формулировании запросов. Кроме того, объявление ограничений может предоставлять критически важную информацию для оптимизатора (см. обсуждение семантической оптимизации в разделе 17.4 главы 17).
Замечание. В некоторых SQL-продуктах объявление определенных ограничений приводит к автоматическому созданию соответствующих индексов и других механизмов обеспечения, что может существенно увеличить стоимость загрузки и пополнения базы данных. В свою очередь, для проектировщиков это может послужить поводом для отказа от объявлений ограничений. И снова повторим, что эта проблема возникает из-за путаницы между логическими и физическими аспектами проектирования. Должна существовать возможность определить ограничения целостности декларативно, на логическом уровне, и независимо указать соответствующий механизм их обеспечения на физическом уровне. К сожалению, современные SQL-продукты неудовлетворительно проводят разграничение между логическим и физическим уровнями (более того, разработчики этих продуктов вряд ли осознают семантическое значение ограничений вообще).
■ Временные ключи
Оперативные базы данных обычно содержат только текущие данные. Базы данных поддержки принятия решений, наоборот, обычно содержат архивы исторически накопленных данных, и поэтому большая часть или даже все данные включают временной штамп или временную отметку. Ключи в таких базах данных часто содержат столбец с подобной отметкой. Например, вновь обратимся к нашей базе данных поставщиков и деталей. Предположим, что необходимо расширить ее так, чтобы для каждой поставки был известен конкретный месяц (от 1 до 12), когда поставка производилась. В этом случае таблица поставок SP может выглядеть, как показано на рис. 21.1. Обратите внимание, что дополнительный столбец MID (идентификатор месяца) входит в состав ключа расширенной версии таблицы SP. Теперь при формулировке запросов, включающих таблицу SP, нужно будет учитывать, что данные имеют различные временные отметки (кроме тех случаев, конечно, когда в запросе этого специально не нужно учитывать). Мы уже коснулись данного вопроса в разделе 21.2, а в главе 22 рассмотрим его более детально.
Замечание. В результате добавления столбцов с временными метками может возникнуть необходимость в корректировке проекта базы данных. Предположим, например, хотя это и несколько надуманно, что количество деталей в каждой поставке зависит от месяца, когда эта поставка производилась (на рис. 21.1 данные соответствуют этому ограничению). Тогда пересмотренная версия таблицы SP будет удовлетворять функциональной зависимости MID —> QTY, но не будет удовлетворять условиям пятой нормальной формы и даже третьей нормальной формы. Поэтому она должна быть нормализована, как показано на рис. 21.2. К сожалению, проектировщики баз данных поддержки принятия решений редко беспокоятся о том, чтобы учитывать такие включаемые зависимости.
s# |
Р# |
MID |
QTY |
S1 |
Р1 |
3 |
300 |
S1 |
Р1 |
5 |
100 |
S1 |
Р2 |
1 |
200 |
S1 |
РЗ |
7 |
400 |
S1 |
Р4 |
1 |
200 |
S1 |
Р5 |
5 |
100 |
со |
Р6 |
4 |
100 |
S2 |
Р1 |
3 |
300 |
S2 |
Р2 |
9 |
400 |
S3 |
Р2 |
6 |
200 |
S3 |
Р2 |
8 |
200 |
S4 |
Р2 |
1 |
200 |
S4 |
Р4 |
8 |
200 |
S4 |
Р5 |
7 |
400 |
S4 |
Р5 |
11 |
400 |
Рис. 21.1. Пример таблицы SP, включающей поле идентификатора месяца
Физическое проектирование
В разделе 21.2 было отмечено, что базы данных поддержки принятия решений, как правило, большие и чрезмерно индексированные, а также часто включают различные виды контролируемой избыточности. В этом подразделе кратко рассматриваются вопросы, касающиеся физического проектирования.
Сначала разберемся в разбиении таблиц на разделы, что иначе называется фрагментацией. Фрагментация представляет собой возможный подход к решению проблемы "больших баз данных". Каждая таблица делится на группу непересекающихся разделов или фрагментов, предназначенных для независимого физического хранения (см. обсуждение вопроса о фрагментации в главе 20). Такое разделение может существенно расширить возможности управления и доступа к данной таблице. Обычно за каждым разделом закрепляются определенные выделенные (в той или иной степени) ресурсы, например диск или процессор, вследствие чего конкуренция между разделами за такие ресурсы минимизируется. Таблицы разделяются горизонтально4 с помощью функции разделения, которая использует значения выбранных столбцов, составляющих ключ раздела, в качестве аргументов, а возвращает номер раздела или его адрес. Такие функции обычно поддерживают разделение по диапазонам (range), кэшированное (hash) разделение, круговое (round-robin) разделение и прочие виды разделения (см. аннотацию к [17.58] в главе 17).
Теперь обратимся к индексированию. Известно, что, используя подходящий индекс, можно резко сократить количество физических операций чтения. В ранних SQL-продуктах предоставлялся лишь один вид индексов, а именно — индексы, представленные в виде В-деревьев. Позже, через несколько лет, стали применяться и некоторые другие виды индексов, особенно в связи с использованием баз данных поддержки принятия решений. Среди них наибольшее распространение получили битовые отображения, кэш-индексы, муль-титабличные индексы, булевы индексы, функциональные индексы, а также уже известные нам индексы в виде В-деревьев. Рассмотрим каждый из этих видов индексов.
4 Хотя вертикальное разделение также может иметь определенные преимущества, здесь оно не рассматривается, поскольку большинство продуктов его не поддерживает.
■ Индексы в виде В-деревьев. Индексы в виде В-деревьев предоставляют эффективный доступ для запросов диапазонов значений, за исключением случаев, когда количество подходящих строк становится слишком большим. Обновление В-деревьев относительно эффективно.
Индексы в виде битовых отображений. Предположим, что в индексированной таблице Т содержится п строк. Тогда индекс в виде битового отображения для столбца С таблицы Т будет содержать вектор из п бит для каждого значения в домене столбца С и установленный бит будет соответствовать строке R, если в ее столбце С будет содержаться соответствующее значение. Такие индексы эффективны для запросов, содержащих набор значений, однако их эффективность снижается, когда этот набор становится слишком большим. Обратите внимание, что несколько реляционных операций (соединение, объединение, ограничение равенства и т.п.) могут быть выполнены исключительно с индексами посредством булевых операций (AND, OR, NOT) над битовыми векторами. Доступ к реальным данным не требуется совсем, если не нужен конечный результирующий набор. Обновление индексов битовых отображений относительно неэффективно.
Кэш-индексы (они также называются кэш-адресацией или просто кэшированием). Кэш-индексы эффективны для доступа к конкретным строкам, а не к диапазонам. Вычислительная стоимость линейно зависит от количества строк, поскольку для кэш-функции не требуется расширение, чтобы разместить дополнительные ключевые значения. Кэширование может также использоваться для эффективной реализации соединений, как описано в главе 17.
Мультитабличные индексы (иногда они называются индексами соединений). По существу, элемент мультитабличного индекса содержит указатели на строки в нескольких таблицах вместо простых указателей на строки в одной таблице. Такие индексы позволяют повысить производительность операций соединения и ускорить проверку ограничений целостности для нескольких таблиц (т.е. для базы данных).
Булевы индексы (более известные как индексы выражений). Булев индекс указывает, для каких строк определенной таблицы определенное логическое выражение (включающее столбцы рассматриваемой таблицы) будет истинным. Такие индексы чрезвычайно полезны, если соответствующее логическое выражение является обычным компонентом условия выборки.
Функциональные индексы. Функциональные индексы индексируют строки таблицы не на основе значений в этих строках, а на основе результата применения к этим значениям некоторой функции.
В дополнение к сказанному следует отметить, что предлагаются еще и различные виды смешанных или гибридных индексов, представляющих собой сочетание перечисленных выше индексов. Смысл таких гибридов трудно изложить в общих словах. Также предлагается множество специализированных видов индексов, таких как R-деревья, которые предназначены для обработки геометрических данных. В этой книге мы не будем пытаться решить такую устрашающую задачу, как описание всех видов индексов; заинтересованным читателям можем предложить обратиться к [25.27], где содержится исчерпывающее изложение этой темы.
И наконец рассмотрим вопрос контролируемой избыточности. Контролируемая избыточность — это важный инструмент сокращения количества операций ввода-вывода и минимизации конкурентного доступа к данным в базе. Как пояснялось в главе 1, избыточность контролируема, если она управляется СУБД и скрыта от пользователей. (Отметим, что по определению избыточность, которая должным образом контролируется на физическом уровне, не видима на логическом уровне и поэтому не влияет на корректность на логическом уровне.) Существует два общих вида такой избыточности.
■ Первый вид включает обслуживание точных копий или реплик базы данных.
Замечание. Управление копированием, которое может рассматриваться как менее амбициозная форма репликации, также широко поддерживается (см. ниже).
■ Второй вид включает обслуживание производных данных в дополнение к базе данных. Наиболее часто используется в форме итоговых таблиц и расчетных (или вычисленных, или производных) столбцов.
Рассмотрим каждый из этих видов по порядку.
Основные понятия репликации были рассмотрены в разделах 20.3 и 20.4 главы 20 (см., в частности, подраздел "Распространение обновлений" в разделе 20.4). Здесь мы просто повторим несколько основных пунктов из этих разделов и выскажем некоторые дополнительные замечания. Прежде всего напомним, что репликация может быть синхронной и асинхронной.
В случае синхронной репликации, если данный дубликат обновлен, все другие дубликаты того же элемента данных также должны быть обновлены в той же транзакции. Логически это означает, что существует лишь одна версия данных. В большинстве продуктов синхронная репликация реализуется с помощью триггерных процедур (возможно, скрытых и системно управляемых). Однако синхронная репликация имеет тот недостаток, что она создает дополнительную нагрузку при выполнении всех транзакций, в которых обновляются какие-либо реплики (кроме того, могут возникать проблемы, связанные с доступностью данных).
В случае асинхронной репликации обновление одного дубликата распространяется на другие спустя некоторое время, а не в той же транзакции. Таким образом, при асинхронной репликации вводится задержка или время ожидания, в течение которого отдельные реплики могут быть фактически не идентичными (т.е. термин "реплики" оказывается не совсем верным, поскольку мы имеем дело не с точными копиями). В большинстве продуктов асинхронная репликация реализуется посредством чтения журнала транзакций или постоянной очереди обновлений, которые подлежат распространению.
5 Следует отметить, что может возникнуть такая ситуация, когда будет трудно избежать или предупредить возможную несовместимость отдельных реплик. В частности, конфликт может возникнуть из-за порядка, в котором выполняются обновления. Пусть, например, в транзакции Т1 выполняется вставка строки в реплику RX, а затем в транзакции Т2 эта строка удаляется, и пусть RY— это реплика таблицы RX, Если обновления будут распространены на таблицу RY, но поступят к таблице RY в обратном порядке (например, из-за задержек в маршрутизации), то транзакции Т2 нечего будет удалять, а позже в транзакции Т1 будет вставлена подлежащая удалению строка. В конечном счете реплика RY будет содержать данную строку, а реплика RX— нет. Разрешение конфликтов и достижение совместимости между репликами — это сложная проблема, которая в этой книге не обсуждается.
Преимущество асинхронной репликации состоит в том, что дополнительная нагрузка от репликации разъединена с транзакциями обновлений, которые могут быть критичны ко времени выполнения и весьма чувствительны к требуемому уровню производительности. К недостаткам этой схемы относится то, что данные могут оказаться несовместимыми (т.е. несовместимыми с точки зрения пользователя). Например, избыточность может проявляться на логическом уровне, а это, строго говоря, означает, что термин "контролируемая избыточность" в таком случае неприемлем5.
Следует отметить, что по крайней мере в коммерческом мире термин "репликация" стал означать преимущественно (или даже исключительно) асинхронную репликацию (как уже отмечалось в главе 20).
Основное различие между репликацией и управлением копированием заключается в следующем. Если используется репликация, то обновление одной реплики в конечном счете распространяется на все остальные "автоматически". В режиме управления копированием, напротив, не существует такого автоматического распространения обновлений. Копии данных создаются и управляются с помощью группового или фонового процесса, который разделен по времени от обновляющих транзакций. Управление копированием, в общем, более эффективно по сравнению с репликацией, поскольку за один раз могут копироваться большие объемы данных. К недостаткам можно отнести то, что большую часть времени копии данных не будут идентичны данным базы, поэтому пользователи должны знать, когда эти данные синхронизированы. Обычно управление копированием упрощается благодаря требованию, чтобы обновления применялись в соответствии со схемой "первичной копии" того или иного вида (см. главу 20).
Теперь рассмотрим другой вид избыточности — расчетные столбцы и итоговые таблицы. Эти конструкции особенно важны в контексте систем поддержки принятия решений. В них содержатся предварительно подсчитанные значения данных — значения, которые вычисляются на основе других данных, хранящихся где-то в базе данных. Ясно, что такие конструкции позволяют избежать необходимости каждый раз повторно вычислять эти значения, когда они понадобятся в каком-то запросе. Расчетный столбец — это такой столбец, значение которого в данной строке является производным от других значений в той же строке6. Итоговая таблица — это таблица, в которой содержатся совокупные или обобщенные значения (сумма, среднее значение, количество строк и т.п.), вычисленные на основе значений в других таблицах. Такие итоги часто предварительно вычисляются для нескольких различных групп одних и тех же детальных данных (см. раздел 21.6).
Замечание. Если расчетные столбцы и итоговые таблицы действительно являются экземплярами контролируемой избыточности, то они должны быть полностью скрыты от пользователей, хотя в современных продуктах это правило обычно не соблюдается.
6
Возможен и другой подход, при котором
вычисленное значение является
производным от значений в нескольких
строках той же таблицы или даже в других
таблицах. Однако в этом случае
обновление одной строки может повлечь
обновление многих других строк, в
частности может очень негативно
отразиться на операциях загрузки и
обновления базы данных.
Распространенные ошибки проектирования
В этом подразделе мы вкратце прокомментируем ошибки проектирования в среде поддержки принятия решений, которые широко распространены на практике.
■ Дублирование строк. Проектировщики систем поддержки принятия решений часто утверждают, что их данные просто не имеют уникальных идентификаторов, и поэтому допускается дублирование строк. В [5.3] и [5.6] подробно объясняется, почему разрешение дубликатов является ошибкой. Здесь же мы просто отметим, что эта "необходимость" возникает из-за того, что физическая схема не является производной от логической схемы, которая, возможно, никогда и не создавалась. Также заметим, что в таком проекте строки часто имеют неоднородное значение, в особенности если в них присутствуют NULL-значения. Иначе говоря, не все строки являются экземплярами одного и того же предиката (см. раздел 3.4 главы 3, а также главу 18).
Замечание. Иногда дубликаты допускаются преднамеренно, особенно если проектировщик использует объектно-ориентированную среду (см. последний абзац в разделе 24.2 главы 24).
Денормализация и связанные с ней действия. При необоснованном стремлении исключить соединения и тем самым сократить количество операций ввода-вывода проектировщики часто выполняют предварительные соединения таблиц, вводят различного рода производные столбцы и т.д. Такая практика может быть приемлемой на физическом уровне, но только не тогда, когда все это проявляется на логическом уровне.
Схемы типа "звезда". Схемы типа "звезда", или так называемые многомерные схемы, чаще всего возникают в результате попытки "предельно упростить" корректные методы проектирования. Однако от таких упрощений нельзя ожидать какого-либо выигрыша. В результате при росте базы данных часто снижается производительность и теряется гибкость, а разрешение возникающих трудностей посредством физического перепроектирования требует внесения изменений и в приложения, поскольку схемы типа "звезда" — это в действительности чисто физические схемы, хотя они и открыты для приложений. В общем случае проблема заключается в произвольной и необоснованной природе созданного проекта.
Замечание. Схемы типа "звезда" будут подробно рассматриваться в разделе 21.5.
NULL-значения. Проектировщики часто пытаются сберечь пространство, допуская наличие в столбцах NULL-значений. Этот прием может сработать, если столбец имеет тип данных переменной длины, а NULL-значения на физическом уровне представляются пустыми строками. Однако в общем случае такие попытки будут неправильными. Не только просто возможно (и желательно) проектировать так, чтобы избежать появления NULL-значений [18.20], но это часто и существенно выгоднее, поскольку в результате память используется более эффективно и достигается более высокая производительность операций ввода-вывода.
Проектирование итоговых таблиц. Логическое проектирование итоговых таблиц нередко игнорируется, вследствие чего возникают неконтролируемая избыточность и трудности с поддержанием согласованности данных в базе. В результате пользователи сталкиваются с затруднениями при интерпретации суммарных значений и формулировке запросов с их участием. Чтобы избежать подобных проблем, все итоговые таблицы, относящиеся к одному и тому же уровню обобщения (раздел 21.6), необходимо спроектировать так, как если бы они составляли отдельную базу данных. В этом случае определенные проблемы циклического обновления могут быть решены посредством запрещения обновлений на уровне обобщенных данных и организации синхронизации итоговых таблиц исключительно на основе данных детального уровня.
■ Множественные пути доступа. Проектировщики систем поддержки принятия решений и их пользователи часто ошибочно говорят о "множественности путей доступа" к некоторым необходимым им данным, подразумевая, что одни и те же данные могут быть получены несколькими разными реляционными выражениями. Иногда такие выражения действительно равносильны, как в случае, например, A JOIN (В JOIN С) и (A JOIN В) JOIN С (см. главу 17). Иногда они равносильны благодаря действию некоторого ограничения целостности (снова см. главу 17), а иногда на самом деле они оказываются вовсе не равносильными. Для иллюстрации последнего случая предположим, что таблицы А, В и С имеют общий столбец К. Тогда "путь следования по значениям в столбце К от А к В, а оттуда к С", определенно, не то же самое, что "путь следования по значениям в столбце К напрямую от А к С". Ясно, что в таких ситуациях пользователи могут быть поставлены в тупик. Они не знают, какое именно выражение необходимо применять и будут ли одинаковыми полученные результаты. Конечно, частично эта проблема может быть решена за счет дополнительного обучения пользователей. Еще часть проблемы можно решить за счет обеспечения правильной работы оптимизатора. Однако часть проблемы возлагается и на проектировщиков, которые разрешают избыточность в логической схеме и/или предоставляют пользователям непосредственный доступ к физической схеме. Следует отметить, что эта часть проблемы может быть решена только за счет правильного проектирования.
В заключение отметим, что, по нашему мнению, многие затруднения при проектировании, якобы возникающие из-за специфических требований систем поддержки принятия решений, могут быть успешно преодолены в результате строгого следования правильному подходу. В действительности большинство подобных проблем вызвано именно отказом от строгого следования правильному подходу, но, по правде говоря, эти затруднения часто усугубляются еще и проблемами, свойственными самому языку SQL.
21.4. Подготовка данных
7
Отметим, между прочим, что в этих
операциях часто могли бы использоваться
преимущества обработки на уровне
множеств, свойственные реляционным
системам, хотя на практике это происходит
редко.
Извлечение данных
Извлечение данных — это процесс выборки данных из оперативных баз данных и других источников. Для извлечения данных существует множество инструментов, включая утилиты, предоставляемые системой, пользовательские программы извлечения и коммерческие продукты извлечения данных (общего назначения). В процессе извлечения обычно интенсивно используется система ввода-вывода, что может послужить помехой для выполнения критически важных операций. Поэтому извлечение данных часто осуществляется в параллельном режиме (т.е. как множество параллельно выполняемых подпроцессов) и на физическом уровне. Однако такое "физическое извлечение" может вызвать проблемы при последующей обработке, поскольку они могут сопровождаться потерей информации (особенно — данных о связях), которая представляется каким-либо физическим способом, например с помощью указателей или физической смежности. По этой причине программы извлечения иногда предоставляют средства защиты такой информации с помощью полей последовательных номеров записей и замены указателей значениями внешнего ключа.
Очистка данных
Лишь немногие источники данных обеспечивают удовлетворительный контроль информации. Вследствие этого, прежде чем данные будут введены в базу данных поддержки принятия решений, обычно требуется выполнить их очистку (как правило, это пакетная операция). Обычно очистка предусматривает заполнение отсутствующих значений, корректировку опечаток и других допущенных при вводе данных ошибок, определение стандартных сокращений и форматов, замену синонимов стандартными идентификаторами и т.д. Данные, которые определяются как ошибочные и не могут быть исправлены, отбрасываются.
Замечание, Полученная при выполнении очистки информация иногда используется для выявления ошибок в источниках данных и последующего повышения качества содержащейся в них информации.
Преобразование и консолидация данных
После очистки данных полученная информация, скорее всего, еще не будет отвечать требованиям системы поддержки принятия решений и, следовательно, будет нуждаться в соответствующем преобразовании. Обычно данные подготавливаются в виде набора файлов, по одному файлу для каждой таблицы, определенной в физической схеме. Поэтому процедура преобразования данных будет предусматривать построчное разбиение или объединение исходных записей, как объяснялось в разделе 1.5 главы 1.
Замечание. Ошибки, которые не были исправлены во время очистки, иногда всплывают в процессе преобразования данных. Как и при очистке, любая некорректная запись в общем случае отбрасывается. Аналогичным образом информация об ошибках, полученная в ходе преобразования данных, может использоваться для повышения качества источников данных.
Процедура преобразования приобретает особую важность, когда необходимо слить данные, поступившие из нескольких разных источников. Этот процесс называется консолидацией. В таком случае любая неявная связь между данными из отдельных источников должна быть преобразована в явную путем введения явных значений. Кроме того, если значения дат и времени связаны и имеют определенный деловой смысл, они должны быть проконтролированы и приведены в соответствие между отдельными источниками. Этот процесс называется синхронизацией времени.
По соображениям производительности операции преобразования часто выполняются параллельно. Они могут интенсивно использовать как систему ввода-вывода, так и центральный процессор.
Замечание. Синхронизация времени может оказаться довольно сложной задачей. Предположим, например, что необходимо найти средний доход от заказчика на одного продавца за квартал. Предположим также, что данные о доходах от заказчиков ведутся по финансовым кварталам в базе данных бухгалтерии, а данные о продавцах, обслуживающих каждого заказчика, ведутся по календарным кварталам в базе данных отдела сбыта. Очевидно, что необходимо слить данные двух указанных баз. Консолидация данных о заказчиках не сложна — она предусматривает простую проверку соответствия идентификаторов заказчиков. Однако вопрос синхронизации времени значительно сложнее. Мы можем вычислить доходы заказчика за финансовый квартал (из базы данных бухгалтерии), но мы не можем сказать, какие продавцы обслуживали каждого из заказчиков в конкретное время, как не можем определить доходы от заказчика за календарный квартал.
Загрузка данных
Разработчики СУБД придают большое значение эффективности операций загрузки данных. В нашем случае "операцию загрузки данных" разобьем на следующие этапы: а) пересылка преобразованных и консолидированных данных в базу данных поддержки принятия решений; б) проверка согласованности данных (т.е. проверка их целостности); в) построение всех необходимых индексов. Кратко прокомментируем каждый из этих этапов.
Пересылка данных. Современные СУБД обычно предоставляют утилиты параллельной загрузки данных. Иногда, прежде чем будет выполнена настоящая загрузка, данные преобразуются во внутренний физический формат, требуемый целевой СУБД. (Альтернативный и более эффективный метод предусматривает загрузку в рабочие таблицы, состав которых отражает структуру целевой схемы. На этих рабочих таблицах может быть выполнена необходимая проверка целостности, а затем для пересылки данных из рабочих таблиц в целевые таблицы может использоваться операция INSERT, выполняемая на уровне множеств.
Проверка целостности. Большая часть процесса проверки целостности загружаемых данных может быть выполнена еще до реальной загрузки, без обращения к данным, уже находящимся в базе. Однако некоторые ограничения все же не могут быть проверены без обращения к существующей базе данных. Например, ограничение, контролирующее уникальность значений, в общем случае должно проверяться во время реальной загрузки (или, если загрузка выполняется в пакетном режиме, после ее завершения).
Построение индексов. Наличие индексов может резко замедлить процесс загрузки данных, поскольку большинство продуктов выполняет обновление индексов при вставке в таблицу каждой строки. Поэтому иногда выгодно удалить индексы перед загрузкой данных, а затем, после ее завершения, создать их заново. Однако такой подход не будет целесообразным, если количество новых данных по отношению к уже существующим данным мало; в этом случае затраты на создание индексов для всей таблицы будут существенно больше затрат на обновление индексов. Кроме того, создание индексов для большой таблицы может быть причиной неустранимых ошибок выделения памяти, причем вероятность их возникновения увеличивается по мере увеличения объема таблицы.
Замечание. Большинство СУБД поддерживает режим параллельного создания индексов, призванный ускорить процессы загрузки данных и построения индексов.
Обновление данных
В большинстве баз данных поддержки принятия решений (но не во всех) требуется периодическое обновление данных для поддержания их актуальности. Обновление обычно предусматривает частичную загрузку, хотя для некоторых систем поддержки принятия решений требуется удаление всех данных и их полная перезагрузка. При обновлении возникают те же проблемы, что и при загрузке, и, кроме того, может потребоваться, чтобы обновление выполнялось в то время, когда пользователи обращаются к базе данных. (См. раздел 9.5 главы 9, а также [9.2] и [9.6].)
Банки оперативных данных
Банки оперативных данных представляют собой "предметно-ориентированные, интегрированные, изменчивые, т.е. обновляемые, текущие, или почти текущие, коллекции данных" [21.19]. Другими словами, банки оперативных данных — это специализированные базы данных. Термин предметно-ориентированные означает, что рассматриваемые данные представляют некоторую конкретную предметную область, например заказчиков, продукты и т.п. Банки оперативных данных могут использоваться для разных целей: как область накопления для физической реорганизации извлеченных оперативных данных, для выдачи оперативных отчетов, а также для поддержки оперативных решений. Кроме того, банки оперативных данных могут служить местом консолидации данных, если оперативные данные поступают из нескольких источников. Поэтому они могут быть предназначены для многих целей.
Замечание. Поскольку банки оперативных данных не накапливают исторические данные, обычно они не разрастаются до слишком больших объемов. С другой стороны, банки оперативных данных обычно достаточно часто или даже непрерывно обновляются информацией из источников оперативных данных8. Проблемы синхронизации времени (см. подраздел "Преобразование и консолидация данных") в операционных хранилищах данных могут успешно преодолеваться, если обновление выполняется достаточно часто.