Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Воспрос по струкуре БД с поддержкой версионности записей / 24 сообщений из 24, страница 1 из 1
22.10.2007, 08:50
    #34883720
jason29
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Воспрос по струкуре БД с поддержкой версионности записей
Добрый день! Хотелось бы услышать Вашу критику и комментарии относительно структуры базы данных.

Есть задача построения надстройки (далее DSS) над существующей OLTP базой данных. DSS будет использоваться только для целей репортинга. Одно из основных требований к данной DSS - обеспечить возможность сохранения снимка данных на любой момент времени в прошлом. Если с 2006-01-01 по 2007-01-01 23:59:59 у клиента был один вид деятельности, а с 2007-01-02 0:00:00 по 2008-01-01 другой, то это должно быть отражено в DSS. Причем, согласно ТЗ, ВСЕ свойства объекта, кроме уникального идентификатора, нужно теоретически считать изменяемыми. Например, если в OLTP клиент был заведен с неправильной датой рождения, а через месяц это выяснилось, и оператор сделал исправление, это должно быть отражено в DSS. Также это относится и к таким маловероятным случаям, как привязка кредита к некорректному клиенту и т.п. Т.о. любой отчет с одинаковыми параметрами, сформированный в 2006 и 2007 году, должен показать одинаковые результаты.

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

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

Комменты по поводу колонок. StartDate - дата начала действия данной версии строки, Stop Date - дата окончания действия данной версии строки. По сути своей, свойство избыточное, но значительно упрощает структуру запросов выборки данных. IsDeleted - битовый флаг, указывающий на то, была ли запись удалена в OLTP.

У кого какие мысли, критика? Всем заранее огромное спасибо!
...
Рейтинг: 0 / 0
22.10.2007, 10:39
    #34883991
ModelR
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Воспрос по струкуре БД с поддержкой версионности записей
Самое интересное опущено - а как в этих вариантах видятся структуры фактов?
А мыслей можно нагуглить по slowly changing dimensions
...
Рейтинг: 0 / 0
22.10.2007, 13:06
    #34884592
jason29
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Воспрос по струкуре БД с поддержкой версионности записей
ModelRСамое интересное опущено - а как в этих вариантах видятся структуры фактов?
А мыслей можно нагуглить по slowly changing dimensions

Спасибо за замечание, очень важный и интересный момент.
...
Рейтинг: 0 / 0
22.10.2007, 14:50
    #34885049
guest_20040621
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Воспрос по струкуре БД с поддержкой версионности записей
> задача построения надстройки (далее DSS) над существующей OLTP базой данных

На Вашем месте я бы не стал браться за решение этой задачи. Любое решение будет по определению кривым.
...
Рейтинг: 0 / 0
22.10.2007, 18:51
    #34886088
А6дулла
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Воспрос по струкуре БД с поддержкой версионности записей
авторguest_20040621

просьба описать "прямое"
...
Рейтинг: 0 / 0
22.10.2007, 19:25
    #34886135
guest_20040621
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Воспрос по струкуре БД с поддержкой версионности записей
> просьба описать "прямое"

Попробуйте сформулировать требования к базе данных, чтобы добавление версионности было простым (с учетом "...ВСЕ свойства объекта, кроме уникального идентификатора, нужно теоретически считать изменяемыми..."). Это к тому, чтобы понимать особенности темпоральной структуры данных.

"Прямым" решением в данном случае будет новая структура данных, а не надстройка к существующей.
...
Рейтинг: 0 / 0
23.10.2007, 06:46
    #34886611
jason29
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Воспрос по струкуре БД с поддержкой версионности записей
guest_20040621> просьба описать "прямое"

Попробуйте сформулировать требования к базе данных, чтобы добавление версионности было простым (с учетом "...ВСЕ свойства объекта, кроме уникального идентификатора, нужно теоретически считать изменяемыми..."). Это к тому, чтобы понимать особенности темпоральной структуры данных.

"Прямым" решением в данном случае будет новая структура данных, а не надстройка к существующей.

К сожалению, далеко не всегда получается прибегнуть к прямым решениям :( Если по нормальному писать структуру с нуля, нужно вносить ряд изменений в DAL уровень приложний, которые работают с этими данными. Проблема в том, что в моём случае эти приложения представляют собой забугорный "черный" ящик, иными словами, доступа к исходникам нет и не будет. Сменить за пару месяцев корпоративную систему в финансовой организации, где работает под тысячу человек, тоже не представляется возможным по ряду, думаю всем понятным, причин.
...
Рейтинг: 0 / 0
23.10.2007, 06:56
    #34886617
jason29
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Воспрос по струкуре БД с поддержкой версионности записей
[quot guest_20040621]> просьба описать "прямое"

Пункт ТЗ "...ВСЕ свойства объекта, кроме уникального идентификатора, нужно теоретически считать изменяемыми..." объясняется тем, что ИТ отдел данной компании может производить простые корректировки данных на уровне SQL согласно одобренным запросам. Хотя это происходит редко, все же имеет место быть. Сама OLTP+аппликационная часть работают достаточно стабильно уже более двух лет.
...
Рейтинг: 0 / 0
23.10.2007, 12:08
    #34887281
assa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Воспрос по струкуре БД с поддержкой версионности записей
jason29У кого какие мысли,когда то смотрел близкое к в1. (и посейчас пользуется). Отличия: вместо таблицы типо Clients у меня таблица типо ClientsPK (client_id (PK), clientsVersionId ) ( с парой парных индексов). И, соответственно, поле "Deleted" в "основной" таблице версий - отсутствует за ненадобностью. И у меня нет DateEnd, а есть просто триггерный штамп DateStart (т.е. версия-запись вообще никогда не апдейтится). При желании быстро вязаться на версию того периода - вероятно DateEnd таки нужна. Но это приводит к обновляемости версии как таковой. Роль же текущей таблицы выполняет вью - джойн таблицы ПК и таблицы версий. Целостность "живых данных" развязывается через "таблицы ПК" (чтобы в "живых" подчиненках не было связей на "удаленные" записи).
...
Рейтинг: 0 / 0
26.10.2007, 05:11
    #34896170
Aqwerty
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Воспрос по струкуре БД с поддержкой версионности записей
Следует учесть проблемы производительности, которые возникнут при любом из этих вариантов, т.к. в запросах неминуемо будут присутствовать выражения вида "startDate < ReportEndDate AND ReportStartDate < EndDate", где StartDate, EndDate - соответствующие столбцы таблицы, а ReportStart, ReportEndDate - период, за который будет формироваться отчет.
Подобные выражения не оптимизируются индексами, поэтому будет полностью читаться индекс по ProductId, ClientId и т.д. и затем для каждой записи проверяться данное условие. В итоге если мы ВСЕ таблицы не будем хранить отсортированными или группированными по уникальному неизменяемому идентификатору соответствующей сущности (ClientId, ProductId,...), то мы получим кучу чтений вразброс, что не самым лучшим образом скажется на производительности. В некоторых случаях мы получим полное сканирование таблицы, что может и будет быстрее, но если данных будет много, то это все равно будет медленно.
Если мы хотим быстро получать ответы на свои запросы (DSS!?), то следует проектировать структуру БД так, чтобы предикаты запросов содержали равенства и не более 2 неравенств, записываемых в виде BETWEEN'а (т.е. low<x<high, например, Текущая дата < EndDate AND Текущая дата >= StartDate).
В данном случае это фактически означает повышение уровня детализации, т.е. скорее всего отказ от времени и создание записей с актуальным состоянием на каждый день вне зависимости от наличия изменений. Тогда можно будет получать быстрые ответы.
...
Рейтинг: 0 / 0
26.10.2007, 09:50
    #34896377
ModelR
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Воспрос по струкуре БД с поддержкой версионности записей
AqwertyЕсли мы хотим быстро получать ответы на свои запросы (DSS!?), то следует проектировать структуру БД так, чтобы предикаты запросов содержали равенства и не более 2 неравенств, записываемых в виде BETWEEN'а (т.е. low<x<high, например, Текущая дата < EndDate AND Текущая дата >= StartDate).
В данном случае это фактически означает повышение уровня детализации, т.е. скорее всего отказ от времени и создание записей с актуальным состоянием на каждый день вне зависимости от наличия изменений. Тогда можно будет получать быстрые ответы.Плз поясните.
В таком случае в данных StartDate == EndDate == Date и в запросе просто Текущая дата = Date ?
...
Рейтинг: 0 / 0
26.10.2007, 11:23
    #34896747
assa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Воспрос по струкуре БД с поддержкой версионности записей
Aqwertyв запросах неминуемо будут присутствовать выражения вида "startDate < ReportEndDate AND ReportStartDate < EndDate", где StartDate, EndDate - соответствующие столбцы таблицы, а ReportStart, ReportEndDate - период, за который будет формироваться отчет.
Подобные выражения не оптимизируются индексами???
а что, такой индекс тут не сработает:

CREATE INDEX idx_табла_StartDateDESC_EndDateASC (StartDate DESC, EndDate ASC);
...
Рейтинг: 0 / 0
26.10.2007, 17:55
    #34898415
Aqwerty
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Воспрос по струкуре БД с поддержкой версионности записей
assa Aqwertyв запросах неминуемо будут присутствовать выражения вида "startDate < ReportEndDate AND ReportStartDate < EndDate", где StartDate, EndDate - соответствующие столбцы таблицы, а ReportStart, ReportEndDate - период, за который будет формироваться отчет.
Подобные выражения не оптимизируются индексами???
а что, такой индекс тут не сработает:

CREATE INDEX idx_табла_StartDateDESC_EndDateASC (StartDate DESC, EndDate ASC);
А как он должен сработать? Может СУБД и будет его использовать, причем это даст выигрышь в производительности, но все равно по нему придется делать полное сканирование.
Ведь чтобы эффективно использовать индекс надо иметь возможность встать на первую строку, соответствующую нижней границе диапазона и дальше идти по индексу пока не будет достигнута верхняя граница диапазона сканирования.
Вот для примера пусть у нас есть в БД следующие периоды:
StartDate - EndDate
01.01.2007 - 01.02.2007
01.02.2007 - 05.02.2007
05.02.2007 - 15.04.2007
15.04.2007 - 01.06.2007

Соответственно в приведенном Вами индексе они будут расположены так:
#1 15.04.2007 - 01.06.2007
#2 05.02.2007 - 15.04.2007
#3 01.02.2007 - 05.02.2007
#4 01.01.2007 - 01.02.2007

Выбираем данные за период с 01.03.2007 до 01.04.2007, т.е. пишем в WHERE следующее: StartDate < '01.04.2007' AND EndDate > '01.03.2007'
Следовательно мы начинаем сканировать индекс со строки #2. Но далее все строки удовлетворяют нашему условию StartDate < '01.04.2007', соответственно СУБД будет просматривать их все и проверять второе условие.
Ну а на практике это фактически полный просмотр индекса. Учитывая что в запросе будут и другие условия, для проверки которых нужно будет обращаться к таблице, то СУБД будет делать беспорядочные чтения блоков таблицы просматривая индекс. Если все нужные строки будут в хранится в одних и тех же блоках, то это еще куда не шло, но если они будут (а они будут если специально ничего не предпринимать) хранится вразброс, то СУБД будет просто заваливать запросами на чтение дисковый массив.
Тут проблема в том, что невозможно отсортировать данные так, чтобы искать пересечения диапазона.
Если я не ошибаюсь, то компонент Oracle Spatial для обработки пространственных данных подобную задачу решает следующим образом - ему надо быстро находить участки (полигоны), пересекающиеся с заданным участком. Грубо говоря: пользователь просит найти все земельные участки, ограниченные определенным радиусом с центром в заданной точке. Так вот, Spatial использует индекс. Что он делает - он делит заданный в качестве условия поиска участок на грубо говоря прямоугольники определенных размеров ("квадраты"). В индексе у него хранится соответствие реальных участков и "квадратов", в которых они находятся. Таким образом по индексу он быстро отфильтровывает нужные участки (грубый поиск), а потом полным перебором отфильтровывает данные для результата (точный поиск). Это я к тому, что здесь ситуация аналогичная, только в Spatial она двухмерная или трехмерная, а здесь одномерная, но проще от этого не становится.

To ModelR:
я имею в виду, что если периоды сделать не просто непересекающимися, но и равными по длине, например, в день или в месяц + обеспечить наличие записей для всех периодов от периода создания записи до периода удаления вне зависимости от наличия изменений в периоде, то тогда дата конца будет не нужна и в запросах можно будет писать tbl.PeriodDate >= ReportStartDate AND tbl.PeriodDate < ReportEndDate и вот тогда можно и индекс эффективно использовать.
...
Рейтинг: 0 / 0
29.10.2007, 10:56
    #34900743
TiG
TiG
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Воспрос по струкуре БД с поддержкой версионности записей
Aqwerty
Естественно здесь, как и в любом конкретном случае надо проводить эксперименты, но при правильной подборке и структуре индексов выборки по диапазонам дат вполне эффективны. Откуда вы взяли "фактически полный просмотр индекса" непонятно. Да это будет index range scan, даже для неизменяющихся идентификаторов, но не более того. Если данные не меняются очень часто, то обычно в отчетный диапазон редко для каких записей будет попадать много актуальных версий, чаще - немного либо вообще одна. Более того, в подобных запросах всегда существует основная сущность, для которой выбираются все версии за отчетный период. Все остальные - актуальные на некоторую базовую дату основной сущности. Т.е. типа
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
select ...
from loans l, clients c, products p
where
  l.start_date <= :end_date and l.stop_date >= :start_date
  and c.id = l.client_id
  and l.start_date between c.start_date and c.stop_date
  and p.id = l.client_id
  and l.start_date between p.start_date and p.stop_date
При наличии индексов clients (id, stop_date, start_date) и products (id, stop_date, start_date) выборки из них вполне эффективны.
Естественно это будет немного медленнее, немного более сложные запросы, чем то что существует сейчас. Но это цена которую надо платить за поддержку версионности. Денормализация схемы для ускорения, предрасчитанные итоги или джойны тоже ведь не бесплатны - только там надо платить усложнением модели и дисковым пространством. В любом случае выбирать оптимальное решение для вашего случая - вам ;)
...
Рейтинг: 0 / 0
29.10.2007, 15:49
    #34902015
SQL*Plus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Воспрос по струкуре БД с поддержкой версионности записей
...
Рейтинг: 0 / 0
29.10.2007, 18:07
    #34902744
assa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Воспрос по струкуре БД с поддержкой версионности записей
Aqwerty но все равно по нему придется делать полное сканирование....
Ведь чтобы эффективно использовать индекс надо иметь возможность встать на первую строку, соответствующую нижней границе диапазона и дальше идти по индексу пока не будет достигнута верхняя граница диапазона сканирования.
соответственно СУБД будет просматривать их все и проверять второе условие...

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

далее, для всего диапазона (индексов) надо будет конечно поднять записи. (и проверить их по другим условиям). А вы хотели этого не делать?

Еще раз: никакого _полного_ сканирования индекса не нужно. нужен только диапазон от верхней до нижней границы.
...
Рейтинг: 0 / 0
01.11.2007, 03:52
    #34909034
Aqwerty
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Воспрос по струкуре БД с поддержкой версионности записей
assaгм многабукв и все неверные. Вам сразу по индексу можно возвратить как нижнюю, так и верхнюю границу. ничего при этом просматривать не надо.

далее, для всего диапазона (индексов) надо будет конечно поднять записи. (и проверить их по другим условиям). А вы хотели этого не делать?

Еще раз: никакого _полного_ сканирования индекса не нужно. нужен только диапазон от верхней до нижней границы.
какую верхнюю? какую нижнюю? перечитайте тему.
речь идет о поиске пересекающихся периодов, а не поиске всех дат в заданном периоде.
я же написал как примерно в таких случаях создает индекс Spatial. Вот выдержка из документации по Oracle Spatial:

Oracle® Spatial User's Guide and Reference 10g Release 1 (10.1) Part Number B10826-011.7.1 R-Tree Indexing
A spatial R-tree index can index spatial data of up to four dimensions. An R-tree index approximates each geometry by a single rectangle that minimally encloses the geometry (called the minimum bounding rectangle, or MBR), as shown in Figure 1-3.

For a layer of geometries, an R-tree index consists of a hierarchical index on the MBRs of the geometries in the layer, as shown in Figure 1-4.

задача с периодами - абсолютно аналогичная, только одномерная. Ну и если периоды непересекающиеся, то что-то немного упрощается.
Спрашивается, если все так хорошо и существует эффективный способ индексации, позволяющий решать данную задачу просто B-Tree-индексом, то зачем в Oracle Spatial городить такие сложности?

И объясните на примере как Вы собираетесь читать из индекса только нужные строки (а не весь индекс), если у Вас условие выглядит так: StartDate < '01.04.2007' AND EndDate > '01.03.2007' и есть индекс по (StartDate, EndDate)?
Вы как минимум должны прочитать все записи до 01.04.2007, что в большинстве случаев будет равносильно чтению всего индекса, поскольку обычно больше отчетов запускается за последние (ближайшие) периоды, чем за какие-то далекие.
...
Рейтинг: 0 / 0
01.11.2007, 04:34
    #34909051
Aqwerty
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Воспрос по струкуре БД с поддержкой версионности записей
TiGОткуда вы взяли "фактически полный просмотр индекса" непонятно. Да это будет index range scan, даже для неизменяющихся идентификаторов, но не более того. Если данные не меняются очень часто, то обычно в отчетный диапазон редко для каких записей будет попадать много актуальных версий, чаще - немного либо вообще одна.
А просмотреть range scan'ом половину индекса - это не есть фактически полный просмотр индекса?
TiG
При наличии индексов clients (id, stop_date, start_date) и products (id, stop_date, start_date) выборки из них вполне эффективны.
Естественно это будет немного медленнее, немного более сложные запросы, чем то что существует сейчас. Но это цена которую надо платить за поддержку версионности. Денормализация схемы для ускорения, предрасчитанные итоги или джойны тоже ведь не бесплатны - только там надо платить усложнением модели и дисковым пространством. В любом случае выбирать оптимальное решение для вашего случая - вам ;)
Приведенные Вами индексы оптимальны только в крайней случае - когда Вы делаете запросы за последние периоды. Если же делать запросы за самые старые периоды, то нужны индексы clients (id, start_date, stop_date) и products (id, start_date, stop_date), иначе по Вашим индексам надо будет просмотреть весь индекс, т.к. первое же условие stop_date > :BeginDate будет всегда истинным.
А если запросы делаются за периоды, находящиеся в посередине, то что один, что другой индесы потребуют чтения их половины. Что фактически же равносильно полному сканированию или вообще отказу от этого индекса. Утверждать наверняка без конкретного примера невозможно, но есть достаточно высокая вероятность того, что оптимизатор решить вообще индекс не использовать. Естественно, если делать запросы за вырожденный период [BeginDate;BeginDate), то вообще все хорошо становится. Но в общем случае невозможно гарантировать какую-то стабильную скорость ответа, она очень сильно будет зависеть не просто от длительности периода, но и от его месторасположения.
Я согласен, что обычно большая часть отчетов делается за последние периоды, однако все же следует учитывать и более старые периоды. К тому же если у Вас есть некоторая величина, например, потребление воды, газа, электроэнергии, количество осадков и т.п., о которой можно говорить, что это потребление непрерывно и есть необходимость найти величину этого потребления за указанный период при том, что реальные данные могут содержать любые периоды, то просто так просуммировать данные нельзя, нужно брать часть значения пропорционально периоду (выражение вида: value / (EndDate - StartDate) * (LEAST(EndDate, EndReportDate) - GREATEST(StartDate, StartReportDate)) ). Вот тут возникает еще целый пласт проблем.

В итоге я думаю, что все же следует идти по пути построения хранилища на базе схемы звезда/снежинка, поскольку в противном случае есть опасность нарваться на множество труднорешаемых проблем, в частности, проблему с производительностью.
...
Рейтинг: 0 / 0
01.11.2007, 10:54
    #34909510
TiG
TiG
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Воспрос по струкуре БД с поддержкой версионности записей
Aqwerty TiGОткуда вы взяли "фактически полный просмотр индекса" непонятно. Да это будет index range scan, даже для неизменяющихся идентификаторов, но не более того. Если данные не меняются очень часто, то обычно в отчетный диапазон редко для каких записей будет попадать много актуальных версий, чаще - немного либо вообще одна.
А просмотреть range scan'ом половину индекса - это не есть фактически полный просмотр индекса? TiG
При наличии индексов clients (id, stop_date, start_date) и products (id, stop_date, start_date) выборки из них вполне эффективны.
Естественно это будет немного медленнее, немного более сложные запросы, чем то что существует сейчас. Но это цена которую надо платить за поддержку версионности. Денормализация схемы для ускорения, предрасчитанные итоги или джойны тоже ведь не бесплатны - только там надо платить усложнением модели и дисковым пространством. В любом случае выбирать оптимальное решение для вашего случая - вам ;)
Приведенные Вами индексы оптимальны только в крайней случае - когда Вы делаете запросы за последние периоды. Если же делать запросы за самые старые периоды, то нужны индексы clients (id, start_date, stop_date) и products (id, start_date, stop_date), иначе по Вашим индексам надо будет просмотреть весь индекс, т.к. первое же условие stop_date > :BeginDate будет всегда истинным.
А если запросы делаются за периоды, находящиеся в посередине, то что один, что другой индесы потребуют чтения их половины. Что фактически же равносильно полному сканированию или вообще отказу от этого индекса. Утверждать наверняка без конкретного примера невозможно, но есть достаточно высокая вероятность того, что оптимизатор решить вообще индекс не использовать. Естественно, если делать запросы за вырожденный период [BeginDate;BeginDate), то вообще все хорошо становится. Но в общем случае невозможно гарантировать какую-то стабильную скорость ответа, она очень сильно будет зависеть не просто от длительности периода, но и от его месторасположения.
Я согласен, что обычно большая часть отчетов делается за последние периоды, однако все же следует учитывать и более старые периоды. К тому же если у Вас есть некоторая величина, например, потребление воды, газа, электроэнергии, количество осадков и т.п., о которой можно говорить, что это потребление непрерывно и есть необходимость найти величину этого потребления за указанный период при том, что реальные данные могут содержать любые периоды, то просто так просуммировать данные нельзя, нужно брать часть значения пропорционально периоду (выражение вида: value / (EndDate - StartDate) * (LEAST(EndDate, EndReportDate) - GREATEST(StartDate, StartReportDate)) ). Вот тут возникает еще целый пласт проблем.

В итоге я думаю, что все же следует идти по пути построения хранилища на базе схемы звезда/снежинка, поскольку в противном случае есть опасность нарваться на множество труднорешаемых проблем, в частности, проблему с производительностью.
У вас явно проблемы с пониманием что из себя представляют индексы, и когда и как они используются. В данном случае если вы делаете выборку по id - никакого "просмотра половины индекса" не будет (если конечно у вас на один единственный id на всю таблицу ;))), пофиг ему какие там даты, старые или новые, ничего от этого не меняется. Если отбор только по датам - есессно вам нужен индекс где даты будут ведущими столбцами. И никакой "сильной зависимости от месторасположения" не будет. С чего вы это взяли, вы вообще представляете как физически строятся древовидные индексы ?
В зависимости от размера/высоты индекса и кардинальности ведущих колонок у вас уже на первом уровне могут быть полные (вот где собака порылась!) ключи, что позволяет уже на первом уровне отсекать ветви содержащие не подходящие по всему списку колонок строки. Потому что поймите, если у вас ведущая колонка в индексе имеет всего 2 разных равновероятных значения (индекс хреновый конечно, но для примера сойдет), вторая колонка почти уникальна, а сама таблица содержит 10 миллионов строк, и индекс предположим получился 2-х уровневый, то какой смысл на 1ом уровне хранить только значения одной ведущей колонки, понятно ведь что он не селективный совершенно, и действительно будет приводить к "просмотру половины индекса". Поэтому в таком индексе уже на первом уровне будут храниться в качестве границ диапазонов ключей листовых блоков полные ключи и, соответственно, уже при скане блоков первого уровня индекса будет эффективно выделяться только нужный диапазон ключей с учетом значений второй колонки.
Короче решение о необходимости построения отдельного хранилища данных принимать следует явно не из посыла о "сканировании половины индекса". В первую очередь надо оценивать каков будет характер большинства отчетов, какую доп.нагрузку будет создавать на OLTP составляющую, насколько оперативные данные нужны в отчетной системе, каковы вообще будут требования к ней.
...
Рейтинг: 0 / 0
01.11.2007, 16:21
    #34910855
assa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Воспрос по струкуре БД с поддержкой версионности записей
Aqwerty<многабукф.>
И объясните на примере как Вы собираетесь читать из индекса только нужные строки (а не весь индекс), если у Вас условие выглядит так: StartDate < '01.04.2007' AND EndDate > '01.03.2007' и есть индекс по (StartDate, EndDate)?
<...>
поскольку обычно больше отчетов запускается за последние (ближайшие) периоды
<...>
гм. как бы вам помягше разъяснить. вот, скажем, у вас два поля, для понятности интовые
startInt и endInt
вы (поскольку Desk вы в индексе не разглядели, переведем на язык явной инверсии) собираетесть найти
нечто (startInt<10 и endInt>12)
или, что то же самое: (-startInt) > -10) и (endInt>12)
надеюсь, что неворуженным глазом видно, что надо читать не весь индекс ( -startInt , endInt) а его хвост от точки (-10,12). Если хвост не мал по сравнению с общим числом записей - да выгоднее будет читать всю таблицу (поскольку в условии выборки попадет большая часть таблицы). Если же мал ("за последний период") - то только хвост.

Причем тут геометрия? (кажется вы не заметили, что все дело в одномерности задачи периодов . (для двумерной задачи действительно возникнут проблемы) Или вы упустили целое условие из WHERE задачи, когда сформулировали ее в тута Т.е. проблемы возникают в случае SatrtIN BETWEEN ... AND EndIN BETWEEN ... т.к. никакой двойной индекс не вырезает одного сплошного куска под эти условия, а придется перебирать кучу сегментов. Я же говорил именно и только о _вашей_ постановке задачи
...
Рейтинг: 0 / 0
01.11.2007, 16:35
    #34910903
assa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Воспрос по струкуре БД с поддержкой версионности записей
assaкажется заврался. простите засранца. задача таки двумерная, а не одномерная, (как вы говорите). - т.е. условие разбивается на гребенку сегментов индекса)

"был пьян, вел себя недостойно звания..."
...
Рейтинг: 0 / 0
01.11.2007, 17:34
    #34911112
SQL*Plus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Воспрос по струкуре БД с поддержкой версионности записей
Jason29 , вы посмотрели что пишут в своей книге Энсор и Стивенсон?
Вам этот вариант не подходит?
SQL*Plus Дейв Энсор, Йен Стивенсон. Oracle. Проектирование баз данных.
...
Рейтинг: 0 / 0
18.11.2007, 12:13
    #34947267
Aqwerty
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Воспрос по струкуре БД с поддержкой версионности записей
assa assaкажется заврался. простите засранца. задача таки двумерная, а не одномерная, (как вы говорите). - т.е. условие разбивается на гребенку сегментов индекса)

"был пьян, вел себя недостойно звания..."
ну вот. а то сразу - все неверно, все неверно
...
Рейтинг: 0 / 0
19.11.2007, 18:23
    #34949962
ModelR
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Воспрос по струкуре БД с поддержкой версионности записей
Систематизация схем версионности.
Регистрация на сайте бесплатная.
...
Рейтинг: 0 / 0
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Воспрос по струкуре БД с поддержкой версионности записей / 24 сообщений из 24, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]