Моделирование данных с уровнями детализации, некоторые из которых отсутствуют - PullRequest
1 голос
/ 20 мая 2009

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

Проблема в том, что в некоторых случаях у меня будут только общие данные; У меня могут быть «штрафы за матч» для одного матча и «штрафы за период» для другого. Так что на самом низком уровне для некоторых матчей у меня будут очень подробные данные (штрафы за гапс), а на самом высоком уровне у меня будут штрафы за матч.

Я не уверен, как смоделировать / использовать это для составления отчетов, когда у меня нет высокой детализации для некоторых записей. Я думал о чем-то вроде этого:

PenaltiesPerMatch MatchID PenaltyCount

PenaltiesPerPeriod MatchID PeriodID PenaltyCount

PenaltiesPerLap MatchID PeriodID Лапид PenaltyCount

Но меня беспокоит то, что информация более высокого уровня может быть получена из более низкого уровня. Должен ли я дублировать записи (например, заполнять запись штрафов за период данными, которые также указаны в штрафах за круг, суммированными за период?) Или вести уникальные записи (не вводить штрафы за период для данных, которые у меня уже есть в штрафах за круг, рассчитать его суммированием по периоду).

Ответы [ 3 ]

2 голосов
/ 20 мая 2009

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

Когда вы сообщаете о матчах:

  • Рассчитать суммы за матч для матчей высокой детализации
  • Используйте сумму за матч из матчей с низким уровнем детализации

Хранить данные на самом низком уровне детализации, который у вас есть; рассчитать более высокие уровни детализации.

1 голос
/ 20 мая 2009

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

Например:

CREATE TABLE PenaltyCounts
(
    penalty_count_id INT NOT NULL,
    match_id         INT NOT NULL,
    period           TINYINT NULL CHECK (period BETWEEN 1 AND 3),
    lap              SMALLINT NULL,
    penalty_count    SMALLINT NOT NULL,
    CONSTRAINT PK_PenaltyCounts PRIMARY KEY NONCLUSTERED (penalty_count_id),
    CONSTRAINT UI_PenaltyCounts UNIQUE CLUSTERED (match_id, period, lap),
    CONSTRAINT CK_lap_needs_period CHECK (lap IS NULL OR period IS NOT NULL)
)

Одна проблема с этим, для которой я пока не вижу простого решения, состоит в том, как обеспечить, чтобы они ТОЛЬКО могли вводить штрафы на одном уровне. Например, они все еще могут сделать это:

INSERT INTO PenaltyCounts (penalty_count_id, match_id, period, lap, penalty_count)
VALUES (1, 1, NULL, NULL, 5)
INSERT INTO PenaltyCounts (penalty_count_id, match_id, period, lap, penalty_count)
VALUES (2, 1, 1, NULL, 3)
INSERT INTO PenaltyCounts (penalty_count_id, match_id, period, lap, penalty_count)
VALUES (3, 1, 2, NULL, 2)

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

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

0 голосов
/ 20 мая 2009

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

Если у вас всегда был штраф за информацию о периоде, тогда вы могли бы сделать запрос, суммирующий данные.

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

...