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 / 17309
Accepted
Olivier Pons
Olivier Pons
Asked: 2012-05-01 06:32:12 +0800 CST2012-05-01 06:32:12 +0800 CST 2012-05-01 06:32:12 +0800 CST

Projeto de banco de dados: como lidar com o problema de "arquivo"?

  • 772

Tenho certeza de que muitos aplicativos, aplicativos críticos, bancos e assim por diante fazem isso diariamente.

A ideia por trás de tudo isso é:

  • todas as linhas devem ter um histórico
  • todos os links devem permanecer coerentes
  • deve ser fácil fazer solicitações para obter colunas "atuais"
  • os clientes que compraram coisas obsoletas ainda devem ver o que compraram, mesmo que este produto não faça mais parte do catálogo

e assim por diante.

Aqui está o que eu quero fazer e explicarei os problemas que estou enfrentando.

Todas as minhas tabelas terão essas colunas:

  • id
  • id_origin
  • date of creation
  • start date of validity
  • start end of validity

E aqui estão as ideias para operações CRUD:

  • create = inserir nova linha com id_origin= id, date of creation=now, start date of validity=now, end date of validity=null (= significa que é o registro ativo atual)
  • atualizar =
    • read = ler todos os registros com end date of validity==null
    • atualize o registro "atual" end date of validity=nulo com end date of validity=agora
    • crie um novo com os novos valores e end date of validity=null (= significa que é o registro ativo atual)
  • delete = atualize o registro "atual" end date of validity=null com end date of validity=agora

Então aqui está o meu problema: com associações muitos-para-muitos. Vamos dar um exemplo com valores:

  • Tabela A (id = 1, id_origin = 1, início=agora, fim=nulo)
  • Tabela A_B (início=agora, fim=nulo, id_A = 1, id_B = 48)
  • Tabela B (id = 48, id_origin = 48, início=agora, fim=nulo)

Agora eu quero atualizar a tabela A, registro id=1

  • Eu marco id de registro=1 com end=agora
  • Eu insiro um novo valor na tabela A e... caramba, perdi minha relação A_B , a menos que eu duplique a relação também... isso terminaria em uma tabela:

  • Tabela A (id = 1, id_origin = 1, início=agora, fim=agora+8mn)

  • Tabela A (id = 2, id_origin = 1, start=now+8mn, end=null)
  • Tabela A_B (início=agora, fim=nulo, id_A = 1, id_B = 48)
  • Tabela A_B (início=agora, fim=nulo, id_A = 2, id_B = 48)
  • Tabela B (id = 48, id_origin = 48, início=agora, fim=nulo)

E... bem, eu tenho outro problema: a relação A_B: devo marcar (id_A = 1, id_B = 48) como obsoleto ou não (A - id=1 é obsoleto, mas não B - 48)?

Como lidar com isso?

Tenho que projetar isso em grande escala: produtos, parceiros e assim por diante.

Qual é a sua experiência sobre isso? Como você faria (como você fez)?

-- Editar

Eu encontrei este artigo muito interessante , mas não lida adequadamente com "obsolescência em cascata" (= o que estou perguntando na verdade)

database-design
  • 4 4 respostas
  • 3864 Views

4 respostas

  • Voted
  1. Best Answer
    user9582
    2012-05-01T06:45:47+08:002012-05-01T06:45:47+08:00

    Não está claro para mim se esses requisitos são para fins de auditoria ou apenas uma simples referência histórica, como CRM e carrinhos de compras.

    De qualquer forma, considere ter uma tabela main e main_archive para cada área principal onde isso é necessário. "Main" terá apenas entradas atuais/ativas, enquanto "main_archive" terá uma cópia de tudo que for para main. Inserir/atualizar em main_archive pode ser um gatilho de inserir/atualizar em main. As exclusões em main_archive podem ser executadas por um período de tempo mais longo, se alguma vez.

    Para os problemas referenciais, como o Cliente X comprou o Produto Y, a maneira mais fácil de resolver sua preocupação referencial de cust_archive -> product_archive é nunca excluir entradas de product_archive. Geralmente, o churn deve ser muito menor nessa tabela, então o tamanho não deve ser uma preocupação tão ruim.

    HTH.

    • 4
  2. Scott Whitlock
    2012-05-01T06:40:55+08:002012-05-01T06:40:55+08:00

    Isso tem alguma sobreposição com a programação funcional; especificamente o conceito de imutabilidade.

    Você tem uma mesa chamada PRODUCTe outra chamada PRODUCTVERSIONou similar. Quando você altera um produto, não faz uma atualização, apenas insere uma nova PRODUCTVERSIONlinha. Para obter o mais recente, você pode indexar a tabela por número de versão (desc), registro de data e hora (desc) ou pode ter um sinalizador ( LatestVersion).

    Agora, se você tiver algo que faça referência a um produto, poderá decidir para qual tabela ele aponta. Aponta para a PRODUCTentidade (refere-se sempre a este produto) ou para a PRODUCTVERSIONentidade (refere-se apenas a esta versão do produto)?

    Fica complicado. E se você tiver fotos do produto? Eles precisam apontar para a tabela de versão, porque podem ser alterados, mas em muitos casos não o farão e você não deseja duplicar dados desnecessariamente. Isso significa que você precisa de uma PICTUREtabela e um PRODUCTVERSIONPICTURErelacionamento muitos-para-muitos.

    • 2
  3. Olivier Pons
    2012-05-04T00:39:30+08:002012-05-04T00:39:30+08:00

    Eu implementei todas as coisas daqui com 4 campos que estão em todas as minhas tabelas:

    • Eu iria
    • data_criação
    • date_validity_start
    • date_validity_end

    Cada vez que um registro precisa ser modificado, eu o duplico, marco o registro duplicado como "antigo" = date_validity_end=NOW()e o atual como bom date_validity_start=NOW()e date_validity_end=NULL.

    O truque é sobre as relações muitos para muitos e um para muitos: funciona sem tocá-las! É tudo sobre as consultas que são mais complexas: para consultar um registro em uma data precisa (= não agora), tenho para cada junção e para a tabela principal, para adicionar essas restrições:

    WHERE (
      (date_validity_start<=:dateparam AND date_validity_end IS NULL)
      OR
      (date_validity_start<=:dateparam AND date_validity_start>=:dateparam)
    )
    

    Assim, com produtos e atributos (relação muitos para muitos):

    SELECT p.*,a.*
    
    FROM products p
    
    JOIN products_attributes pa
    ON pa.id_product = p.id
    AND (
      (pa.date_validity_start<=:dateparam AND pa.date_validity_end IS NULL)
      OR
      (pa.date_validity_start<=:dateparam AND pa.date_validity_start>=:dateparam)
    )
    
    JOIN attributes a
    ON a.id = pa.id_attribute
    AND (
      (a.date_validity_start<=:dateparam AND a.date_validity_end IS NULL)
      OR
      (a.date_validity_start<=:dateparam AND a.date_validity_start>=:dateparam)
    )
    
    WHERE (
      (p.date_validity_start<=:dateparam AND p.date_validity_end IS NULL)
      OR
      (p.date_validity_start<=:dateparam AND p.date_validity_start>=:dateparam)
    )
    
    • 1
  4. Dimondwoof
    2012-05-03T12:37:21+08:002012-05-03T12:37:21+08:00

    Que tal agora? Parece simples e bastante eficaz para o que fiz no passado. Em sua tabela de "histórico", use um PK diferente. Portanto, seu campo "CustomerID" é o PK em sua tabela Customer, mas na tabela "history", seu PK é "NewCustomerID". "CustomerID" se torna apenas outro campo somente leitura. Isso deixa "CustomerID" inalterado no histórico e todos os seus relacionamentos permanecem intactos.

    • 0

relate perguntas

  • Os índices filtrados podem ajudar a melhorar as consultas baseadas em uma hora inserida ou isso deve ser evitado?

  • Qual é a diferença entre os tipos de dados MySQL VARCHAR e TEXT?

  • É melhor armazenar os valores calculados ou recalculá-los a pedido? [duplicado]

  • Armazenar vs calcular valores agregados

  • Quais são algumas maneiras de implementar um relacionamento muitos-para-muitos em um data warehouse?

Sidebar

Stats

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

    Como ver a lista de bancos de dados no Oracle?

    • 8 respostas
  • Marko Smith

    Quão grande deve ser o mysql innodb_buffer_pool_size?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    restaurar a tabela do arquivo .frm e .ibd?

    • 10 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

    Como selecionar a primeira linha de cada grupo?

    • 6 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
    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
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +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
  • Martin Hope
    bernd_k Quando devo usar uma restrição exclusiva em vez de um índice exclusivo? 2011-01-05 02:32:27 +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