AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 345620
Accepted
Thomas Hunter II
Thomas Hunter II
Asked: 2025-03-07 12:55:37 +0800 CST2025-03-07 12:55:37 +0800 CST 2025-03-07 12:55:37 +0800 CST

Aplicando uma única linha estrangeira "especial" com várias linhas regulares

  • 772

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_versioncoluna 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 activecoluna 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 documentvalor 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.

postgresql
  • 2 2 respostas
  • 56 Views

2 respostas

  • Voted
  1. Thomas Hunter II
    2025-03-07T12:55:37+08:002025-03-07T12:55:37+08:00

    Acontece que isso pode ser implementado usando um índice parcial. Neste caso, usamos a coluna booleana active na tabela de versões do documento.

    CREATE UNIQUE INDEX one_active_document_version
      ON document_version (document, active) WHERE active;
    

    Leia WHERE activecomo WHERE active = truee 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.

    • 3
  2. Best Answer
    Laurenz Albe
    2025-03-07T16:54:53+08:002025-03-07T16:54:53+08:00

    Sugiro que você use a chave estrangeira documentse a defina como NOT 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— como DEFERRABLE INITIALLY DEFERRED, para que a verificação de integridade seja adiada para o fim da transação. Então você pode fazer:

    BEGIN;
    
    -- won't throw an error, because the check is deferred
    INSERT INTO document_versions (document, name)
       VALUES (0, 'some name');
    
    -- uses the last sequence-generated value in this session
    INSERT INTO documents (name, active_version)
       VALUES ('some name', currval('document_versions_id_seq'));
    
    UPDATE document_versions
    SET document = currval('documents_id_seq')
    WHERE id = currval('document_versions_id_seq');
    
    -- now all foreign keys are fulfilled, and no error is thrown
    COMMIT;
    
    • 1

relate perguntas

  • Posso ativar o PITR depois que o banco de dados foi usado

  • Práticas recomendadas para executar a replicação atrasada do deslocamento de tempo

  • Os procedimentos armazenados impedem a injeção de SQL?

  • Sequências Biológicas do UniProt no PostgreSQL

  • Qual é a diferença entre a replicação do PostgreSQL 9.0 e o Slony-I?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve