Você parece estar interessado em:
-- a and b are related by the association of interest
Foo(a, b)
-- foo(a, b) but not foo(a2, b) for some a2 <> a
Boring(a, b)
unique(b)
FK (a, b) references Foo
-- foo(a, b) and foo(a2, b) for some a2 <> a
Rare(a, b)
FK (a, b) references foo
Se você deseja consultas para ser desimpedido, basta definir Foo. Você pode consultá-lo para Rare.
Rare = select * from Foo f join Foo f2
where f.a <> f2.a and f.b = f2.b
Qualquer outro design sofre de complexidade de atualização para manter o banco de dados consistente.
Você tem alguma preocupação difusa sobre Rare ser muito menor que Foo. Mas qual é o seu requisito Existem apenas n em um milhão de discos Foo sendo muitos:muitos pelos quais você escolheria algum outro design?
O próximo nível de complexidade é ter Foo e Rare. As atualizações precisam manter a equação acima verdadeira.
Parece extremamente improvável que haja um benefício em reduzir a redundância de 2 ou 3 em um milhão de Foo + Rare por ter apenas Boring + Rare e reconstruir Foo a partir deles. Mas pode ser benéfico definir um índice único (b) para Boring que irá sustentar que a b nele tem apenas um a. Quando você precisa de Foo:
Foo = select * from Boring union select * from Rare
Mas suas atualizações devem manter isso
not exists (select * from Boring b join Rare r where b.b = r.b)