Tenho uma tabela de banco de dados de documentos e uma tabela de banco de dados de versões de documentos. Há uma relação de um para muitos entre documento e versão de documento. Estou procurando conselhos sobre como modelar exatamente qual versão de documento está "ativa" para um dado documento.
CREATE TABLE documents (
id serial primary key,
name varchar(250) not null
-- active_version integer REFERENCES document_versions(id) not null
);
CREATE TABLE document_versions (
id serial primary key,
document integer REFERENCES documents(id) not null,
name varchar(32) not null
-- active boolean not null default false
);
Estou procurando uma maneira de marcar qual das entradas da versão do documento está "ativa". Comentadas no esquema estão duas maneiras de fazer isso, mas não acredito que nenhuma delas seja necessariamente ideal.
No primeiro caso, a tabela de documentos tem uma referência de volta às versões do documento. Isso força exatamente uma versão do documento a estar ativa. Suponho que haja um catch-22, então não é possível realmente impor que a active_version
coluna seja not null
. O principal problema com essa abordagem, na minha opinião, é que há uma referência circular entre as duas tabelas.
A segunda maneira de fazer isso é com uma active
coluna booleana na tabela de versões do documento. Suponho que isso esteja ok, mas não tenho certeza de como fazer uma restrição para que apenas uma linha na tabela com um determinado document
valor de chave estrangeira tenha um valor ativo de true
. Também suspeito que isso poderia impor que 0 ou 1 versão ativa do documento exista, mas não impor que exatamente 1 versão ativa do documento exista.
Acontece que isso pode ser implementado usando um índice parcial. Neste caso, usamos a coluna booleana active na tabela de versões do documento.
Leia
WHERE active
comoWHERE active = true
e deve fazer um pouco mais de sentido. Basicamente, é um índice que se aplica somente a um subconjunto dos dados na tabela; neste caso, rows where active é true.Isso impõe 0 ou 1 versão do documento, mas não exatamente 1.
Sugiro que você use a chave estrangeira
documents
e a defina comoNOT NULL
.O problema percebido 22 é provavelmente a dificuldade de inserir linhas em tabelas que referenciam umas às outras. A solução para isso é definir uma das chaves estrangeiras — digamos, a de
document_versions
— comoDEFERRABLE INITIALLY DEFERRED
, para que a verificação de integridade seja adiada para o fim da transação. Então você pode fazer: