Скачиваний:
77
Добавлен:
02.05.2014
Размер:
2.54 Mб
Скачать

21.3. Проектирование базы данных поддержки принятия решений

Как утверждалось ранее, в частности во введении к части III, по нашему мнению, про­ект базы данных всегда должен быть выполнен на двух уровнях: логическом и физическом.

  1. Прежде всего должен быть выполнен логический проект. На этом уровне основное внимание уделяется реляционной корректности. Таблицы должны представлять пра­вильные отношения, гарантируя таким образом, что реляционные операции будут выполняться так, как им надлежит выполняться, и не будет никаких непредсказуемых результатов. Далее должны быть описаны домены (типы), на основе доменов опреде­лены столбцы и указаны зависимости между столбцами (функциональные и др.). На основании этих данных может быть выполнена нормализация и определены ограни­чения целостности.

  2. Затем создается физический проект, который должен быть производным от логиче­ского проекта. На этом уровне, конечно, основное внимание уделяется эффектив­ности хранения данных и производительности. В принципе, допустимо любое расположение данных при условии, что между логической и физической схемами имеется сохраняющее информацию преобразование, поддающееся выражению с помощью реляционной алгебры [2.5]. Отметим, в частности, что из наличия такого преобразования следует, что существуют реляционные представления физической схемы, которые отображают ее подобно логической схеме, и наоборот.

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

Безусловно, логическая схема может впоследствии изменяться, например с целью включения новых видов данных и новых или только что обнаруженных зависимостей. Внесенные изменения, естественно, потребуют также соответствующих изменений в фи­зической схеме. Но этот вопрос нас здесь не беспокоит. Нас больше волнует то, что фи­зическая схема может измениться, в то время как логическая схема будет оставаться прежней. Например, предположим, что операция соединения таблиц SP (Поставки) и Р (Детали) в значительной степени преобладает по сравнению с другими схемами доступа к данным. Тогда у нас мог бы возникнуть соблазн "предварительно соединить" таблицы

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 Отметим, между прочим, что в этих операциях часто могли бы использоваться преимуще­ства обработки на уровне множеств, свойственные реляционным системам, хотя на практике это происходит редко.

Многие из вопросов, связанных с системами поддержки принятия решений, в первую очередь, касаются задач получения и подготовки данных. Эти данные следует извлечь из разных источников, очистить, преобразовать и консолидировать, после чего загрузить в базу данных поддержки принятия решений. Впоследствии загруженные данные долж­ны периодически обновляться. Каждая операция заслуживает отдельного обсуждения7. Рассмотрим каждую из них поочередно, а затем завершим раздел кратким обсуждением банков оперативных данных.

Извлечение данных

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

Очистка данных

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

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

Преобразование и консолидация данных

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

Замечание. Ошибки, которые не были исправлены во время очистки, иногда всплы­вают в процессе преобразования данных. Как и при очистке, любая некорректная запись в общем случае отбрасывается. Аналогичным образом информация об ошибках, полу­ченная в ходе преобразования данных, может использоваться для повышения качества источников данных.

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

По соображениям производительности операции преобразования часто выполняются параллельно. Они могут интенсивно использовать как систему ввода-вывода, так и цен­тральный процессор.

Замечание. Синхронизация времени может оказаться довольно сложной задачей. Пред­положим, например, что необходимо найти средний доход от заказчика на одного продавца за квартал. Предположим также, что данные о доходах от заказчиков ведутся по финансо­вым кварталам в базе данных бухгалтерии, а данные о продавцах, обслуживающих каждого заказчика, ведутся по календарным кварталам в базе данных отдела сбыта. Очевидно, что необходимо слить данные двух указанных баз. Консолидация данных о заказчиках не сложна — она предусматривает простую проверку соответствия идентификаторов заказчи­ков. Однако вопрос синхронизации времени значительно сложнее. Мы можем вычислить доходы заказчика за финансовый квартал (из базы данных бухгалтерии), но мы не можем сказать, какие продавцы обслуживали каждого из заказчиков в конкретное время, как не можем определить доходы от заказчика за календарный квартал.

Загрузка данных

Разработчики СУБД придают большое значение эффективности операций загрузки данных. В нашем случае "операцию загрузки данных" разобьем на следующие этапы: а) пересылка преобразованных и консолидированных данных в базу данных поддержки при­нятия решений; б) проверка согласованности данных (т.е. проверка их целостности); в) по­строение всех необходимых индексов. Кратко прокомментируем каждый из этих этапов.

  • Пересылка данных. Современные СУБД обычно предоставляют утилиты парал­лельной загрузки данных. Иногда, прежде чем будет выполнена настоящая загруз­ка, данные преобразуются во внутренний физический формат, требуемый целевой СУБД. (Альтернативный и более эффективный метод предусматривает загрузку в рабочие таблицы, состав которых отражает структуру целевой схемы. На этих ра­бочих таблицах может быть выполнена необходимая проверка целостности, а за­тем для пересылки данных из рабочих таблиц в целевые таблицы может использо­ваться операция INSERT, выполняемая на уровне множеств.

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

  • Построение индексов. Наличие индексов может резко замедлить процесс загрузки данных, поскольку большинство продуктов выполняет обновление индексов при вставке в таблицу каждой строки. Поэтому иногда выгодно удалить индексы перед загрузкой данных, а затем, после ее завершения, создать их заново. Однако такой подход не будет целесообразным, если количество новых данных по отношению к уже существующим данным мало; в этом случае затраты на создание индексов для всей таблицы будут существенно больше затрат на обновление индексов. Кроме того, создание индексов для большой таблицы может быть причиной неустрани­мых ошибок выделения памяти, причем вероятность их возникновения увеличива­ется по мере увеличения объема таблицы.

Замечание. Большинство СУБД поддерживает режим параллельного создания ин­дексов, призванный ускорить процессы загрузки данных и построения индексов.

Обновление данных

В большинстве баз данных поддержки принятия решений (но не во всех) требуется периодическое обновление данных для поддержания их актуальности. Обновление обычно предусматривает частичную загрузку, хотя для некоторых систем поддержки принятия решений требуется удаление всех данных и их полная перезагрузка. При об­новлении возникают те же проблемы, что и при загрузке, и, кроме того, может потребо­ваться, чтобы обновление выполнялось в то время, когда пользователи обращаются к ба­зе данных. (См. раздел 9.5 главы 9, а также [9.2] и [9.6].)

Банки оперативных данных

Банки оперативных данных представляют собой "предметно-ориентированные, ин­тегрированные, изменчивые, т.е. обновляемые, текущие, или почти текущие, коллекции данных" [21.19]. Другими словами, банки оперативных данных — это специализирован­ные базы данных. Термин предметно-ориентированные означает, что рассматриваемые данные представляют некоторую конкретную предметную область, например заказчи­ков, продукты и т.п. Банки оперативных данных могут использоваться для разных целей: как область накопления для физической реорганизации извлеченных оперативных дан­ных, для выдачи оперативных отчетов, а также для поддержки оперативных решений. Кроме того, банки оперативных данных могут служить местом консолидации данных, если оперативные данные поступают из нескольких источников. Поэтому они могут быть предназначены для многих целей.

Замечание. Поскольку банки оперативных данных не накапливают исторические дан­ные, обычно они не разрастаются до слишком больших объемов. С другой стороны, бан­ки оперативных данных обычно достаточно часто или даже непрерывно обновляются информацией из источников оперативных данных8. Проблемы синхронизации времени (см. подраздел "Преобразование и консолидация данных") в операционных хранилищах данных могут успешно преодолеваться, если обновление выполняется достаточно часто.

Соседние файлы в папке Дейт К. Дж. Введение в системы баз данных [7 издание]