Устранение избыточных отношений при моделировании отношений Заголовок / Деталь? - PullRequest
0 голосов
/ 01 марта 2010

У меня есть модель, которая выглядит примерно так:

Model

Одна учетная запись имеет много филиалов, и каждая выписка создается для одной учетной записи. Модель является избыточной, потому что Account (идентификатор AccountID в заголовке) может быть выведен из BranchID для транзакции (выписка всегда будет иметь одну или несколько транзакций).

Следует ли удалить AccountID из StatementHeader или этот уровень избыточности в порядке? Или есть лучшее решение?

Ответы [ 3 ]

0 голосов
/ 03 марта 2010

Поскольку утверждение является историческим и обычно доступно только для чтения, некоторая избыточность вполне подходит.Я согласен с Ричардом Харрисоном и перенесу [AccountID] и [StatementDate] в таблицу [Statement];Я полагаю, что вы говорите, что в учетной записи есть много филиалов, поэтому вы будете создавать выписку для учетной записи.

Хранение всех этих данных в одном месте уменьшит количество соединений и ускорит создание отчетов.для этой базы данных.

0 голосов
/ 03 марта 2010

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

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

create or replace trigger statement_has_unique_account
before insert or update on Statement
referencing old as old new as new
for each row
declare
  m integer;
  n integer;
begin
  select b.AccountID
  into m
  from Branch b 
  where b.ID = new.BranchID;

  select s.AccountID
  into n
  from StatementHeader s
  where s.ID = new.StatementID;

  if m <> n then
    raise_application_error(-1000, 'No way!');
  end if;
end;

Без AccountID в StatementHeader вам придется написать сравнение со всеми другими AccountIDs из всех других операторов, которые имеют тот же StatementID, что приведет к более сложной последовательности операторов.

Так что я бы оставил AccountID в качестве внешнего ключа в StatementHeader и принудительно применял бизнес-правило с помощью триггера.

0 голосов
/ 01 марта 2010

Если у вас есть StatementHeader, тогда он должен иметь AccountID для сохранения ссылочной целостности.

Однако может быть лучше полностью удалить StatementHeader и переместить StatementDate в запись Statement. Это сделает вещи чище и поможет модели лучше описать, что вы хотите.

...