Какова наилучшая практика для представления временных интервалов в хранилище данных? - PullRequest
9 голосов
/ 24 ноября 2010

В частности, я имею дело с типом 2 Медленно изменяющееся измерение и должен представлять временной интервал, для которого была активна конкретная запись, т. Е. Для каждой записи у меня есть StartDate и EndDate . Мой вопрос заключается в том, использовать ли закрытое ( [StartDate, EndDate] ) или полуоткрытое ( [StartDate, EndDate) ) интервал, чтобы представить это, то есть, включать ли последнюю дату в интервал или нет. В качестве конкретного примера, скажем, запись 1 была активной с 1 по 5 день, а с 6 дня запись 2 стала активной. Должен ли я сделать EndDate для записи 1 равным 5 или 6?

Недавно я пришел к мысли о том, что полуоткрытые интервалы лучше всего основаны, в частности, на Дейкстра: почему нумерация должна начинаться с нуля , а также на соглашениях для нарезки массивов и Функция range () в Python. Применяя это в контексте хранилища данных, я вижу преимущества соглашения о полуоткрытом интервале:

  • EndDate-StartDate указывает время, когда запись была активной
  • Проверка: StartDate следующей записи будет равняться EndDate предыдущей записи, которую легко проверить.
  • Future Proofing: если позже я решу изменить гранулярность с ежедневной на более короткую, тогда дата переключения будет оставаться точной. Если я использую закрытый интервал и сохраняю конечную дату с отметкой времени в полночь, мне придется скорректировать эти записи, чтобы учесть это.

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

Заранее спасибо за любые идеи или комментарии.

Ответы [ 3 ]

10 голосов
/ 24 ноября 2010

Я видел как закрытую, так и полуоткрытую версии в использовании. Я предпочитаю полуоткрытый по причинам, которые вы указали.

На мой взгляд, полуоткрытая версия делает понятное предполагаемое поведение и «безопаснее». Предикат (a

Установите для последней даты окончания по умолчанию наибольшую дату, поддерживаемую вашей СУБД, а не ноль.

6 голосов
/ 27 ноября 2010

Обычно я согласен с ответом Дэвида (проголосовал), поэтому я не буду повторять эту информацию.В дополнение к этому:

Вы действительно имели в виду полуоткрытый ([StartDate, EndDate])

Даже в этом "полуоткрытом" есть две ошибки.Одной из них является прямая ошибка нормализации, которая, конечно же, реализует дубликаты данных, которые вы идентифицируете в обсуждении, которые доступны как производные данные и которые должны быть удалены.

  • Для меня Half Open - это (StartDate)
  • EndDate выводится из следующей строки.
  • это лучшая практика
  • этоне часто используется, потому что (а) обычные разработчики не знают в наши дни и (б) они слишком ленивы или не знают, как кодировать необходимый простой подзапрос
  • он основан на опыте, в целомбанковские базы данных

Подробные сведения см. в этом документе:

Ссылка на недавний очень похожий вопрос и модель данных

Ответы на комментарии

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

  1. Да.Абсолютно.Любой здравомыслящий человек (который не изучает информатику из вики) должен задаться этим вопросом.Он просто не подчиняется законам физики.

  2. Можете ли вы понять, что многие люди, не понимая нормализации или баз данных (вам нужно 5NF), создают ненормализованные кучи медленных данных и их знаменитое оправдание (написано"гуру") "денормализовано для производительности"?Теперь вы знаете, что это экскременты.

  3. Те же люди, без понимания нормализации или хранилищ данных (вам нужно 6NF), (а) создать копию базы данных и (б) всевозможные странныеи замечательные структуры для «улучшения» запросов, включая (с) еще большее дублирование.И угадайте, что их оправдание?"денормализовано для производительности".

    • Это преступление, и "гуру" не лучше, они подтверждают это.

    • Я бы сказал, что эти "гуру" являются только "гуру", потому что они обеспечивают псевдонаучную основу, которая оправдывает ненаучность большинства.

    • ложная информация не дает правдивости, повторяя ее, и Бог знает, что они повторяют ее до бесконечности.

  4. Простая истина (недостаточно сложная для людейкто оправдывает хранилища данных с помощью (1) (2) (3)), так это то, что 6NF, выполненное правильно, является хранилищем данных.Я предоставляю базу данных и хранилище данных из одних и тех же данных со скоростью хранилища.Нет второй системы;нет второй платформы;нет копий;нет ETL;не хранить копии синхронизированы;нет пользователей, чтобы перейти к двум источникам.Конечно, для преодоления ограничений SQL требуется умение, понимание производительности и немного специального кода (вы не можете указать 6NF в DDL, вам нужно реализовать каталог).

    • зачем внедрятьStarSchema или SnowFlake, когда чистая нормализованная структура уже имеет полную возможность измерения фактора.
      .
  5. Даже если вы этого не сделали, если вы просто сделали традиционную вещь и ETL поместили эту базу данных в отдельную систему хранилища данных, в ней, если вы исключили дублирование, уменьшите строкуРазмеры, уменьшенные индексы, конечно, будут работать быстрее.В противном случае это противоречит законам физики: толстые люди бегут быстрее, чем худые;корова будет бегать быстрее лошади.

    • Справедливо, если у вас нет нормализованной структуры, то, пожалуйста, помогите.Таким образом, они придумали StarSchemas, SnowFlakes и всевозможные проекты Dimension-Fact.

И, пожалуйста, поймите, что только эти неквалифицированные, неопытные люди верят во все эти мифы и магию.Образованные опытные люди имеют свои с трудом заработанные истины, они не нанимают колдунов.Эти «гуру» только подтверждают, что толстый человек не выигрывает гонку из-за погоды или звезд;что-нибудь но вещь, которая решит проблему.Несколько человек завязывают свои трусики в узел, потому что я прям, я говорю толстяку сбросить вес;но настоящая причина, по которой они расстраиваются, состоит в том, что я прокалываю их заветные мифы, которые делают их оправданными, чтобы быть толстыми.Люди не любят меняться.

  • Одна вещь. Есть ли основания отклоняться .Правила не черно-белые;они не единичные правила в изоляции.Мыслящий человек должен рассмотреть их все вместе;расставить приоритеты для контекста.Вы не найдете ни всех Id iot ключей, ни нулевых Id iot ключей в моих базах данных, но каждый Id ключ был тщательно продуман и обоснован.

    • Любыми средствамииспользуйте самые короткие ключи, но используйте значимые реляционные ключи вместо суррогатов;и используйте Суррогаты, когда ключ становится слишком большим, чтобы нести его.

    • Но никогда не начинайте с Суррогатов.Это серьезно затрудняет вашу способность понимать данные;Нормализация;смоделировать данные.

      • Вот один ▶ вопрос / ответ ◀ (из многих!), Где человек застрял в процессе, не в состоянии идентифицировать даже основные сущностии отношения, потому что он вставил Id ключи на все в начале.Задача решена без обсуждения, в первой итерации.
        .
  • Ладно, другое дело.Изучите этот предмет, получите опыт и развивайте себя.Но не пытайтесь учить этому или обращать других, даже если зажегся свет, и вы жаждете.Особенно, если вы полны энтузиазма.Зачем ?Потому что, когда вы подвергаете сомнению совет колдуна, вся деревня будет линчевать вас, потому что вы нападаете на их заветные мифы, их утешение;и вам нужен мой опыт, чтобы поймать колдунов (просто проверьте его в комментариях!).Дайте ему несколько лет, получите свой настоящий с трудом завоеванный опыт, а затем приобретите его.

Если вам интересно, следуйте этому ▶ вопрос / ответ ◀ в течение нескольких дней это будет отличным примером того, как следовать методологии IDEF1X, как выявлять и использовать эти идентификаторы.

0 голосов
/ 01 декабря 2010

Ну, стандартный sql where my_field between date1 and date2 является включающим, поэтому я предпочитаю инклюзивную форму, а не то, что другой неправильный.

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

Они в основном нужны во время загрузки (здесь речь идет о SCD ​​типа 2), чтобы найти наиболее актуальный первичный ключ для соответствующего бизнес-ключа. В этот момент у вас есть что-то вроде:

select ProductKey
from dimProduct
where ProductName = 'unique_name_of_some_product'
  and rowValidTo > current_date ;

Или, если вы предпочитаете создать ключевой конвейер перед загрузкой:

insert into keys_dimProduct (ProductName, ProductKey)  -- here ProductName is PK
select ProductName, ProductKey 
from dimProduct
where rowValidTo > current_date ;

Это помогает при загрузке, потому что легко кэшировать таблицу ключей в память перед загрузкой. Например, если ProductName - это varchar (40), а ProductKey - целое число, таблица ключей составляет менее 0,5 ГБ на 10 миллионов строк, что легко кэшировать для поиска.

Другие часто встречающиеся варианты включают were rowIsCurrent = 'yes' и where rowValidTo is null.

Обычно используется одно или несколько из следующих полей:

  • rowValidFrom
  • rowValidTo
  • rowIsCurrent
  • rowVersion

в зависимости от конструктора DW и иногда используемого инструмента ETL, поскольку большинство инструментов имеют блоки загрузки SCD типа 2.

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

Предположим, я использую все поля row_.

rowValidFrom date       = 3 bytes
rowValidTo   date       = 3 bytes
rowIsCurrent varchar(3) = 5 bytes
rowVersion   integer    = 4 bytes

Это составляет 15 байтов. Кто-то может утверждать, что это 9 или даже 12 байт слишком много - ОК.

Для 10 миллионов строк это составляет 150 000 000 байтов ~ 0,14 ГБ

Я посмотрел цены на сайте Dell.

Memory ~ $38/GB
Disk   ~ $80/TB = 0.078 $/GB 

Я предполагаю рейд 5 здесь (три диска), поэтому цена диска будет составлять 0,078 $ / ГБ * 3 = 0,23 $ / ГБ

Итак, для 10 миллионов строк хранить эти 4 поля на диске стоит 0.23 $/GB * 0.14 GB = 0.032 $. Если вся таблица измерений должна быть кэширована в памяти, цена этих полей будет 38 $/GB * 0.14GB = 5.32 $ за 10 миллионов строк. Для сравнения, пиво в моем местном пабе стоит ~ 7 $.

2010 год, и я ожидаю, что у моего следующего ноутбука будет 16 ГБ памяти. Вещи и (лучшие) практики меняются со временем.

EDIT:

Делали некоторые поиски, за последние 15 лет емкость диска среднего компьютера увеличилась примерно в 1000 раз, памяти примерно в 250 раз.

...