Abaixo está uma versão muito resumida de um projeto no qual estou trabalhando.
CREATE TABLE cidr_block (
id serial not null unique,
block_def cidr primary key,
dhcp_server_id int not null references computer_system (id),
...
);
CREATE TABLE ip_addr (
computer_id int not null references computer_system (id),
mac_addr macaddr not null unique,
ip_addr inet not null unique,
);
Este é um banco de dados de configuração de rede. Agora, espera-se que a maioria, mas não todos, os registros ip_addr.ip_addr estejam em blocos cidr_block.block_def. Outros, que podem ser interfaces vpn vinculadas externamente a locais de clientes, podem não ser. Não há uma maneira simples e declarativa de garantir uma fkey para as linhas aplicáveis entre as duas tabelas. Então eu me pergunto:
É preferível usar gatilhos para criar links fkey quando apropriado?
É suficiente apenas entrar onde esperado? Se um computador receber um endereço IP inválido, ele simplesmente não receberá um do servidor dhcp, e saberemos disso rapidamente. (grava notificações de acionamento que acionam atualizações em servidores dhcp relevantes)
Existe outra maneira melhor?
Para responder à minha própria pergunta aqui, aqui está o que acabei fazendo:
Função ip_block(inet) para procurar o registro de bloco ip de um endereço inet.
Verifique a restrição para garantir que não retorne nulo para as classes de endereços apropriadas. Isso seria acionado na inserção ou atualização na tabela de atribuições.
Função de gatilho para verificar a tabela de atribuições de endereços em um bloco e gerar uma exceção de RI, se for encontrada.
Trigger que executa a função acima quando o block_def do bloco ip é atualizado ou o bloco ip é excluído.
Vou deixar esta resposta inaceitável por um tempo para ver se alguém tem uma abordagem melhor. No entanto, a quantidade de código para realmente fazer isso acabou sendo muito menor do que o esperado, então estou muito feliz com isso até agora.