Иногда (реальная или воспринимаемая) избыточность является следствием бизнес-правила. В этом случае бизнес-правило: «заявление, которое выдается учетной записи, должно содержать только транзакции для филиалов, принадлежащих этой конкретной учетной записи».
Чтобы обеспечить соблюдение этого правила, вы можете попытаться создать схему базы данных, которая делает невозможным ее нарушение или принудительно принудительно применяется с ограничением или триггером. И это проще с помощью 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 и принудительно применял бизнес-правило с помощью триггера.
Я бы не использовал «ID» в качестве имени первичного ключа в каждой таблице; вы в конечном итоге загружаете их в свою модель и никогда не можете быть уверены в том, что вы имеете в виду. Если вы используете суррогатные ключи, я бы предложил вам использовать одно и то же имя на всей вашей модели. У вас уже есть AccountID в качестве внешнего ключа, поэтому используйте одно и то же имя для основного. – Tony
Неопределенно соглашение об именах было установлено кем-то другим, поэтому я не могу его изменить. Я ценю ваше обоснование, хотя у меня такие же проблемы. – ilitirit
Что такое объект StatementHeader? Являются ли утверждения с одним и тем же StatementHeaderID соединены друг с другом в реальном мире или являются идентификатором AccountID и StatementDate? Последнее будет делать StatementHeader чем-то вроде календаря с SatementHeaderID в качестве маскировки даты ... – wallenborn