база данных: обобщение данных, срок действия которых истек - PullRequest
0 голосов
/ 23 октября 2010

Я изо всех сил пытаюсь найти эффективное и гибкое представление для моих данных.У нас есть отношения многие ко многим между двумя сущностями, которые имеют произвольные времена жизни.Давайте назовем их Voter и Candidate.У каждого отношения есть измерение, которое мы хотели бы обобщить различными способами.Они имеют временную метку и гарантированно находятся в пределах жизненного цикла двух связанных объектов.Допустим, мерой является рейтинг одобрения, или просто Rating.

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

Наше текущее решение состоит в том, чтобы составлять список действительных избирателей и кандидатов на каждый день, а затем составлять таблицу «многие ко многим», в которой записывается последняя действительная мера.

Каким будет ваше решение?

Example diagram

Это позволяет мне сделать один запрос для получения ежедневной сводки:

   select 
       avg(rating), valid_date, candidate_SSN, candidate_DOB
   from 
       daily_rating natural join rating
   group by
       valid_date, candidate_SSN, candidate_DOB

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

Ответы [ 2 ]

1 голос
/ 25 октября 2010

Да, это очень неэффективно и расточительно.Это просто набор файлов, не сопоставимый с набором «таблиц» или «базы данных»;его расширение и усовершенствование усугубят дублирование и неэффективность.Дублирование является антитезой базы данных.С точки зрения базы данных, есть гораздо более эффективные и более простые способы реализовать это.

Предположение

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

  1. Избиратель - это Персона;Кандидат - избиратель;(Кандидат = подмножество избирателей)

  2. Кампания связана с Кандидатом (не с избирательной кампанией).

  3. Опрос - это опросответа избирателей на выступление кандидата, начиная с установленной даты, продолжительностью в несколько дней и заканчивая в установленную дату.

  4. Существует много мер, таких как ApprovalRating, которыеопрошены в каждом опросе.

  5. Меры таких опросов всех избирателей агрегированы на уровне опроса.

Ограничение

  1. Требование истечения неясно, поэтому я не предполагаю, что я реализовал это.Если модель не обеспечивает это для вас (если это не очевидно сразу), предоставьте детали, и я добавлю к модели.Текущая модель предоставляет возможность исключения / включения для того, что, как я понимаю, является требованием к истечению срока действия.

  2. У Poll :: Measure недостаточно информации для полной реализации;Мне нужны дополнительные детали.Представление является примитивным и неограниченным в этой области.

  3. Аналогично, любое отношение или ограничение Poll :: Campaign («существует много опросов на кампанию, и они всегда связаны с кампанией»)не был реализован.

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

Представление

Модель данных опроса кампании

  1. Это просто реляционная (нормализованная; без дублирования) база данных, чисто IDEF1X, с учетом того, что дочерние таблицы будут огромными: миграция узких суррогатных ключей в дочерние таблицы, избегая миграции широких ключей.

  2. Обеспечивает возможность «хранилища данных» как есть.На самом деле, если в одном запросе не указывается какое-либо требование BI или DSS, это происходит только из-за отсутствия у вас подробностей;Пожалуйста, предоставьте, и я с радостью поменяю это.(Обратите внимание, что ваш элемент «один запрос» на самом деле является «одним файлом»; объединения являются пешеходными в реляционной базе данных.)

  3. Такие ключи, как% Code, имеют 2-, 3-,и максимум 4 символа.Такие ключи так же быстры, как и целочисленные ключи, и очень полезны (имеет смысл) при просмотре таблиц (без необходимости присоединения к родительскому элементу).

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

Мы реализуем управление версиями в БД совсем иначе, чем в DW, ибез ограничений.Пожалуйста, укажите, требуется ли вам версия (например) Кандидата, и я предоставлю.

Последнее, требование Null не является необычным.Это обслуживается здесь.Опять же, если вы думаете, что это не так ...

1 голос
/ 23 октября 2010

Я использовал здесь технику хранения данных, поэтому имена таблиц dim и fact.

alt text

dimDate называется такизмерение даты, одна строка на дату.

dimCandidate содержит все данные кандидата, новые и старые записи.В терминах хранилища данных это называется измерением типа 2.Один кандидат может иметь несколько строк в этой таблице, только одна из них имеет r_status = 'current'.

Поля

, r_valid_from date
, r_valid_to   date
, r_version    integer -- (1, 2, 3,..)
, r_status     varchar(10) -- (expired, current)

описывают статус записи (строки).Каждый раз, когда изменяется статус кандидата, вставляется новая строка и изменяются r_valid_to и r_status предыдущей строки.

CandidateFullName является бизнес-ключом (натуральным) и должен однозначно идентифицировать кандидата.Ни один из двух кандидатов не может иметь одинаковые CandidateFullName.Обратите внимание, что CandidateKey уникально идентифицирует строку в таблице, а CandidateFullName уникально идентифицирует кандидата.

dimVoter содержит данные об избирателях, новые и старые записи - точно так же, как dimCandidate .

dimCampaign описывает детали кампании, это так называемое измерение типа один, не содержит исторических данных.

factRating имеет показатель Rating.

Обычно этого будет достаточно, но естьтребование интерполировать недостающие данные за день;для этого вводится сводная таблица aggDailyRating .В конце дня запланированное задание собирает рейтинги за день.Эта работа заботится о требованиях интерполяции данных.Таким образом, таблица агрегирования имеет одну строку для каждой комбинации date-(valid) candidate-campaign.Обратите внимание, что избиратель не включен в комбинацию, данные агрегированы по всем избирателям.

alt text

Любые отчеты составляются в сводной таблице, например

--
-- monthy rating for years 2009-2010
-- for candidate john_smith_256
--
select
     CalendarYear
   , MonthNumber  
   , avg(DailyRating) as AverageRating
from aggDailyRating as f
join dimDate        as d on d.DateKey      = f.DateKey
join dimCandidate   as c on c.CandidateKey = f.CandidateKey
where CandidateFullName = 'john_smith_256'
  and CalendarYear between 2009 and 2010
group by CalendarYear, MonthNumber
order by CalendarYear desc, MonthNumber desc ;
...