- •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. Резюме
22.11. Проектирование базы данных
До сих пор переменные-отношения S_DURING и SP DURING использовались для иллюстрации типов интервалов и определения специальных операторов для обработки данных интервалов, и нам этого было достаточно. Переменные-отношения первоначально были "спроектированы" посредством простого добавления атрибутов интервалов к их эквивалентам в базе данных типа моментального снимка. В настоящем разделе мы попытаемся выяснить, насколько хорош такой подход к проектированию. Здесь будет предложена дополнительная декомпозиция определенных хронологических переменных-отношений (под "дополнительной декомпозицией" здесь понимается декомпозиция, которая не предусматривается требованиями классической нормализации). Фактически в зависимости от обстоятельств предлагается использовать два вида декомпозиции — горизонтальную и вертикальную.
Горизонтальная декомпозиция
В нашем примере подразумевается, и вполне обоснованно, что в базе данных содержатся исторические данные, включающие некоторое представление сведений о времени. Также предполагается, что представление этих сведений о времени записывалось в виде некоторых конкретных дат (например, день 10). Однако последнее предположение никак нельзя признать обоснованным. В частности, при таком подходе подразумевается, что с течением времени база данных некоторым образом обновляется. В нашем примере предполагалось, что каждое вхождение значения dlO заменяется на dll ровно в полночь дня 10. Если бы в примере использовались интервалы более мелкой зернистости, то могли бы потребоваться и более частые обновления, скажем, каждую миллисекунду!
Одни авторы предлагают использовать специальные маркеры (будем называть их маркерами настоящего момента, now), которые допустимы везде, где допустимо точечное значение. Согласно этому подходу, например, интервал [d04,dl0], показанный на рис. 22.4 как значение атрибута DURING для поставщика с номером 'S1' в переменной-отношении S_DURING, должен быть представлен как интервал [d04,now]. Реальное значение такого интервала, конечно, зависит от того, когда именно оно рассматривается; скажем, вдень 14 это был бы интервал [d04,dl4].
Другие авторы считают, что введение маркера настоящего момента— опрометчивое отступление от концепций, на которых базируются реляционные системы. Обратите внимание, что маркер настоящего момента в действительности представляет собой некоторую переменную. Следовательно, предлагается странное — мы бы сказали, логически неоправданное — понятие значений, содержащих переменные. Вот несколько вопросов, возникающих при введении подобного понятия, над которыми полезно поразмышлять.
Что произойдет с интервалом [now, dl4] в полночь дня 14?
Что собой представляет значение END( [d04,now]) на день 14? Это dl4 или now?
Мы считаем, что дать разумный ответ на такого рода вопросы сложно. Поэтому, по нашему мнению, необходимо найти подход, который не противоречит общепринятым понятиям.
Иногда "атрибут DURING" будет использоваться для записи данных относительно будущего и относительно прошлого (или вместо него). Например, пусть требуется записать дату истечения срока договора с поставщиком или дату его возобновления в будущем. В таком случае можно было бы использовать вариант отношения S_DURING, представленный на рис. 22.4. Однако этот подход, очевидно, применим не всегда (в частности, если атрибут DURING интерпретируется как время транзакции (см. раздел 22.2), поскольку время транзакции не может быть будущим).
Основная проблема заключается в том, что имеется существенное различие между историческими данными и данными относительно текущего состояния дел. Для исторических данных известно начальное и конечное время, а для текущих данных обычно известно только начальное время. Отсюда неизбежно следует вывод, что необходимы две различные переменные-отношения: одна — для отражения текущего состояния дел, другая — для исторических данных (в конце концов, они соответствуют двум, определенно, разным предикатам). В случае отношения поставщиков "текущая" переменная-отношение — это S_SINCE, показанная на рис. 22.2, а "историческая" — S_DURING, представленная на рис. 22.4, за исключением кортежей, в значениях атрибута DURING которых конечное время интервала не равно dl 0 (соответствующие данные записываются в переменную-отношение S_SINCE).
Этим примером иллюстрируется горизонтальная декомпозиция: переменная-отношение с точечным значением атрибута "начиная с" для текущего состояния и переменная-отношение с интервальным значением атрибута "на период" для исторических данных. Отметим, кстати, что для пополнения данными исторической переменной-отношения могут использоваться триггерные процедуры. Например, удаление кортежа из переменной-отношения S_SINCE может "автоматически" запускать вставку соответствующего кортежа в переменную-отношение S_DURING.
Для объединения исторических и текущих данных в одном отношении может использоваться реляционный оператор UNION, как, например, показано ниже.
S DURING UNION { EXTEND S SINCE
ADD INTERVAL [ SINCE, TODAY() ] AS DURING ) { ALL BUT SINCE }
Недостатки горизонтальной декомпозиции проявляются, если значения атрибута DURING интерпретируются как допустимое время, а не как время транзакции. В этом случае исторические данные обновляемы! Здесь могли бы использоваться операторы обновления, описанные в разделе 22.10, но может случиться так, что исправления должны вноситься в обе переменные-отношения. Предположим, например, что обнаружена ошибка в последнем изменении статуса некоторого поставщика. Тогда может потребоваться не только удалить кортеж из переменной-отношения S_DURING, но и обновить соответствующий кортеж в переменной-отношении S_SINCE. Или другой пример, когда последнее изменение статуса было корректным, но был указан ошибочный день; и в этом случае необходимо внести обновления в обе переменные-отношения.
Если переменная-отношение SP_DURING подобным образом может быть подвергнута декомпозиции на переменные-отношения SP_SINCE и SP_DURING, то дополнительно необходимо пересмотреть ограничение внешнего ключа. Для переменной-отношения SP_DURING, как мы уже убедились в разделе 22.9, определение может включать следующее предложение.
FOREIGN I_KEY {Si, DURING UNFOLDED } REFERENCES S_DURING ...
Как указывалось в разделе 22.9, это уточнение служит для того, чтобы в случае, когда согласно данным переменной-отношения SP DURING поставщик с номером ' Sx' может поставлять некоторую деталь в течение времени i, в переменной-отношении S DURING отражалось, что с поставщиком с номером ' Sx' заключен договор, действительный и на время i. Там же говорилось, что ключ {Si,DURING} в переменной-отношении SP DURING может рассматриваться как хронологический внешний ключ.
Однако для переменной-отношения SP_SINCE соответствующий внешний ключ является лишь "полухронологическим". Поэтому мы по-прежнему вынуждены использовать громоздкие выражения для формулирования ограничений, как было показано в разделе 22.3.
CONSTRAINT AUG SP ТО S_FK
IS EMPTY ( T (~S SINCE RENAME SINCE AS SS ) JOIN { SP SINCE RENAME SINCE AS SPS ) ) WHERE SPS < SS ) ;
Таким образом, горизонтальная декомпозиция неизбежно приводит к определенным проблемам — к проблеме громоздких ограничений и к необходимости одновременного обновления переменных-отношений с текущими и историческими данными. На время написания этой книги не существовало каких-либо конкретных предложений относительно введения сокращений для решения указанных проблем. Возможно, необходимы дальнейшие исследования. Отметим, что эти проблемы не возникают, если разрешить переменной-отношению типа "на период" включать информацию о будущем, прошлом и настоящем (поскольку переменная-отношение типа "с момента" тогда не нужна). Однако при таком подходе будущее считается конечным промежутком времени. Указанные проблемы также не возникают при использовании подхода, предлагаемого в [22.4].
Вертикальная декомпозиция
Еще до того, как были проведены исследования особенностей хронологических данных (и до того, как для их обработки были разработаны операторы языка SQL), некоторые авторы настаивали на необходимости максимальной декомпозиции переменных-отношений, "насколько она возможна", вместо декомпозиции, предусматриваемой правилами классической нормализации. Некоторые из этих авторов, к сожалению, навредили себе, предлагая проекты баз данных, содержащих лишь бинарные переменные-отношения. Одно из критических замечаний относительно этой идеи состояло в том, что иногда необходимы и унарные переменные-отношения. Суть другого замечания заключалась в следующем: некоторые переменные-отношения степени 3 и более на самом деле невозможно подвергнуть декомпозиции (например, переменная-отношение SPJ из базы данных поставщиков, деталей и проектов).
С другой стороны, наша обычная (не хронологическая) переменная-отношение S, безусловно, может быть подвергнута дополнительной декомпозиции. Если заданы истинные высказывания "Имя поставщика с номером 'SI' — 'Smith'", "Статус поставщика с номером 'S1'— 20", "Поставщик с номером 'S1' находится в городе 'London'", то можно с уверенностью сделать вывод об истинности высказывания, которое следует из значения первого кортежа для поставщика с номером 'S1' в базе данных, представленной на рис. 22.1. Значит, переменную-отношение S можно разбить на три бинарные переменные-отношения, каждая из которых будет иметь в качестве первичного ключа атрибут St.
Идея декомпозиции до максимальных пределов мотивируется желанием получить максимально простые элементы. Возможно, для декомпозиции переменной-отношения S это не очень веская причина, однако ее значение существенно возрастает в случае переменной-отношения S_DURING. Имя поставщика, его статус и город нахождения изменяются во времени независимо друг от друга. Более того, они могут изменяться с разной частотой. Например, вряд ли имя поставщика меняется со временем, тогда как место его нахождения иногда изменяется, а его статус может меняться достаточно часто. Но повторение имени и места нахождения поставщика при каждом изменении его статуса может представлять некоторые неудобства. Кроме того, исторические сведения об изменении имени, статуса и места нахождения поставщика, возможно, более интересны и просты, чем история сочетания "имя — статус — город". Поэтому предлагается выполнить декомпозицию переменной-отношения S_DURING на три исторические переменные-отношения, которые могут быть описаны приблизительно так.
S NAME_DURING { St, SNAME, DURING } S~STATUS DURING { St, STATUS, DURING } S~CITY_DURING { St, CITY, DURING }
К каждому из определений этих трех переменных-отношений можно было бы добавить уточнения I_KEY {St, DURING UNFOLDED} и COALESCED DURING.
Замечание. Можно было бы также добавить "основную" переменную-отношение поставщиков.
St_DURING { St, DURING }
Эта переменная-отношение могла бы показывать, с какими поставщиками подписывались договора и когда это было. К определению также можно было бы добавить уточнения I_KEY {St, DURING UNFOLDED} и COALESCED DURING. Кроме того, ключ {St,DURING} мог бы служить хронологическим внешним ключом в каждой из переменных-отношений S_NAME_DURING, S_STATUS_DURING и S_CITY_DURING (а также SP_DURING), соответствующим хронологическому потенциальному ключу в переменной-отношении S_DURING.
Здесь следует отметить еще одну особенность. Чтобы получить историю изменения статуса поставщика для переменной-отношения S_DURING, как она изначально была определена, необходимо использовать не совсем тривиальное выражение.
S_DURING { St, STATUS, DURING } COALESCED DURING
В то же время, чтобы получить значительно менее интересную комбинированную историю, требуется лишь ссылка на эту переменную-отношение. Поэтому в некотором смысле предлагаемая декомпозиция "выравнивает игровое поле" для запросов, или, скорее, упрощает выражение более интересных запросов, и усложняет выражение менее интересных запросов.
Однако необходимость декомпозиции переменной-отношения S_SINCE не так уж и непреодолима. В частности, отметим, что, поскольку для пополнения трех исторических переменных-отношений могут использоваться триггерные процедуры (например, удаление кортежа из переменной-отношения S_SINCE может "автоматически" активизировать обновление переменных-отношений S#_DURING, S_NAME_DORING, S_STATUS_DURING и S CITY_DURING), нет необходимости в декомпозиции переменной-отношения S SINCE, чтобы достичь тех же результатов.