|
Программирование >> Проектирование баз данных
Сложности начинаются, когда вместо того, чтобы хранить данные о ценах в напечатанном виде, мы решаем поместить их в таблицу. Вот один из возможных скриптов для создания такой таблицы: create table prices { product code VARCHAR2(10) not null , date from date not null , date to date , price number not null , constraint prices date range check {date from < date to); Обратите внимание на то, что здесь не задано ограничение первичного ключа. Следует отметить, что поиск действительно первичного ключа для такой таблицы - задача не из тривиальных. (Мы рассмотрим ее ниже.) Однако даже без первичного ключа мы в состоянии найти цену конкретного товара по состоянию на определенный момент времени. Как это сделать, показано в следующем фрагменте программы. Поскольку мы регистрируем даты (и время) только тогда, когда цена вступает в силу или перестает действовать, вряд ли найдется строка, содержащая нужную нам дату. Это значит, что в условии поиска данных сравнение на равенство использовать нельзя. Отметим также, что данный SQL-запрос располагается в теле PL/SQL-функции. Никаких извинений по этому поводу мы не приносим! Вы, вероятно, уже поняли, что нам нравится использовать инкапсуляцию. По мере дальнейшего изложения преимущества процедурного подхода будут становиться более очевидными. create or replace function price at date { p code in price.product code%type , p when in date ) returns number is p price number; begin select price into p price from prices where product code = p code and date from <= p when and date to >= nvl{p when, to date{Ol-dec-4712 , dd-mon-yyyy); return p price; exception when no date found then renurn 0; End price at date; По поводу этого фрагмента следует отметить следующее. Во-первых, мы назвали наши столбцы DATE FROM и DATE TO. Не пытайтесь использовать имена FROM DATE и TO DATE, поскольку второе имя совпадает с Именем функции Oracle. Во-вторых, если конечная дата не указана, соответствующий столбец (DATE TO) будет содержать неопределенное значение (см. главу 5). Чтобы сравнение работало, придется с помощью функцрга NVL конвертировать неопределенное значение в очень больщую дату (максимальное значение, которое может быть представлено типом данных.ВАТЕ, - 31-DEC-4712). Временные измерения играют важную роль в хранилищах данных. Как мы увидим в главе 13, интерес к средствам поддержки принятия решений привел к тому, что в хранилище помещаются данные, полученные от разных информационных систем, а затем создаются запросы, позволяющие выявить тенденции изменения этих данных. Полученные результаты применяются для поиска путей повышения производительности и расширения рынка сбыта. Очевидно, что эффект от использования хранилища данных в этом случае определяется возможностью извлекать из него архивные и временные данные. Вопросы проектирования временных баз данных в этом разделе рассматривается ряд проблем, связанных с обеспечением действительности по дате в схеме базы данных Oracle?, и предлагаются различные подходы к обработке временных данных. Точность представлетш даты Столбцы данных Oracle, имеющие тип DATE, содержат и дату, и время (округленное до секунды). Однако нам необходимо определить, достаточна ли эта информация или ее больше, чем нужно? Другими словами, мы должны решить, какой должна быть точность представления этих данных с точки зрения бизнеса - секунда, минута, час, день? Вернемся к нашему примеру с данными о ценах. Могут ли цены изменяться на протяжении рабочего дня? В одних сферах деятельности это допустимо, а в других все изменения цен производятся вечером. Если у нас установлено последнее бизнес-правило (лучше не полениться и проверить, так ли это), то можно отсечь время в столбцах DATE FROM и DATE TO и хранить в них только дату. Рассмотрим теперь действительную по дате таблицу, содержащую биржевые цены или курсы акций. Эти цены все время колеблются. Так, если мы хотим зарегистрировать дату и время биржевой сделки, чтобы затем можно было расцетгть ее, нужно сделать так, чтобы и время заключения сделки, и время кажлого колебания цены регистрировалось с точностью до секунды. Для данной проблемы существует действительно простое решенрге: зарегистрировать текущий курс акций на момент заключения сделки и сохранить эту цену в самой транзакции. Некоторые проектировщики склоняются к сложному, привязанному к дате решению, когда это не нужно. Мы рекомендуем сначала исследовать более простые варианты и ориентироваться на действительность по дате лишь в том случае, если простые пути не дают желаемого результата. В отношении описанного выше примера с биржей следует также отметить, что цена сделки на момент сбора данных может быть неизвестна. Если бы мы проектировали систему управления, работающую в режиме реального времени, или встроенную систему управления, то точность представления, равная секунде, могла бы быть и недостаточной. Не вдаваясь в детали, скажем, что в данном случае можно использовать числовое поле - в нем можно хранить число миллисекунд и даже наносекунд, истекших от некоторого базового времени. Базовое время может быть выбрано совершенно произвольно. Как правило, это момент времени, о котором известно, что он наступил раньше, чем любое событие, которое придется обрабатывать данному приложению. Необходгшы ли две даты? Давайте вновь обратимся к таблице PRICES и подумаем, нужен ли нам столбец DATE TO. Конечно, содержащиеся в нем данные можно получить из столбца DATE FROM следующей строки временного ряда. Однако в действительности это верно лишь в случае, когда временной ряд непрерывен, т.е. между строками в ряду нет разрывов по дате. В таблице PRICES такой разрыв есть, и если исключить из нее столбец DATE FROM, могут возникнуть проблемы. К сожалению, здесь мы сталкиваемся с еще одной особенностью таблиц. Ни реляционная алгебра, ни SQL ничего не говорят нам о последовательности строк таблицы. Поэтому на практике исключать столбец DATE TO не рекомендуется, так как это приведет к необходимости использовать очень сложный и неэффективный SQL-код. (Даже для выполнения базовых операций понадобится коррелированный подзапрос.) Предположим, нам нужно определить цену некоторого товара (.p code) на некоторую дату (-.datejofjnterest). Сравним SQL-запросы в следующих примерах. Запрос в примере 1, где используется столбец DATE TO, проще и может работать во много раз эффективнее, чем эквивалентный запрос в примере 2, который не обращается к этому столбцу. В более сложных запросах, где выполняется соединение таблиц, это различие становится еще более заметным. По этой причине мы рекомендуем всегда создавать пары действительных по дате столбцов. Помимо того что они упрощают поиск. Эти столбцы могут существенно облегчить вам жизнь, когда вы столкнетесь с необходимостью модифицировать граничные даты. Ведь очевидно, что они, так же как и цены, могут изменяться. /* пример 1 - используются два столбца, действительных по дате */ SELECT price from prices
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |