Um dos itens no Effective Java de Joshua Bloch é a noção de que as classes devem permitir a mutação de instâncias o mínimo possível e, de preferência, de maneira alguma.
Muitas vezes, os dados de um objeto são mantidos em um banco de dados de alguma forma. Isso me levou a pensar na idéia de imutabilidade em um banco de dados, especialmente nas tabelas que representam uma única entidade em um sistema maior.
Algo com o qual tenho experimentado recentemente é a ideia de tentar minimizar as atualizações que faço nas linhas da tabela que representam esses objetos e tentar executar inserções o máximo possível.
Um exemplo concreto de algo que eu estava experimentando recentemente. Se eu souber que posso anexar um registro com dados adicionais posteriormente, criarei outra tabela para representá-lo, como as duas definições de tabela a seguir:
create table myObj (id integer, ...other_data... not null);
create table myObjSuppliment (id integer, myObjId integer, ...more_data... not null);
Espero que seja óbvio que esses nomes não sejam verbais, mas apenas para demonstrar a ideia.
Essa é uma abordagem razoável para a modelagem de persistência de dados? Vale a pena tentar limitar as atualizações executadas em uma tabela, especialmente para preencher nulos para dados que podem não existir quando o registro é criado originalmente? Há momentos em que uma abordagem como essa pode causar dor intensa mais tarde?
fonte
UPDATE
). Como os registros médicos do médico.Respostas:
O principal objetivo da imutabilidade é garantir que não haja instantes no tempo em que os dados na memória estejam em um estado inválido. (A outra é porque as notações matemáticas são principalmente estáticas e, portanto, as coisas imutáveis são mais fáceis de conceituar e modelar matematicamente.) Na memória, se outro encadeamento tentar ler ou gravar dados enquanto estiver sendo trabalhado, ele poderá ficar corrompido ou ele próprio pode estar em um estado corrupto. Se você tiver várias operações de atribuição nos campos de um objeto, em um aplicativo multithread, outro encadeamento poderá tentar trabalhar com ele em algum momento intermediário - o que pode ser ruim.
A imutabilidade corrige isso escrevendo primeiro todas as alterações em um novo local na memória e depois executando a atribuição final como uma etapa rápida de reescrever o ponteiro para o objeto para apontar para o novo objeto - que em todas as CPUs é um átomo Operação.
Os bancos de dados fazem a mesma coisa usando transações atômicas : quando você inicia uma transação, ele grava todas as novas atualizações em um novo local no disco. Quando você termina a transação, ele muda o ponteiro do disco para onde estão as novas atualizações - o que ocorre em um breve instante durante o qual outros processos não podem tocá-lo.
Isso também é exatamente o mesmo que sua ideia de criar novas tabelas, exceto mais automática e mais flexível.
Portanto, para responder sua pergunta, sim, a imutabilidade é boa nos bancos de dados, mas não, você não precisa criar tabelas separadas apenas para esse fim; você pode apenas usar os comandos de transação atômica disponíveis para o seu sistema de banco de dados.
fonte
Depende dos benefícios que você espera obter da imutabilidade. A resposta de Rei Miyasaka abordou uma (evitar estados intermediários inválidos), mas aqui está outra.
A mutação às vezes é chamada de atualização destrutiva : quando você modifica um objeto, o estado antigo é perdido (a menos que você tome medidas adicionais para preservá-lo explicitamente de alguma forma). Por outro lado, com dados imutáveis, é trivial representar simultaneamente o estado antes e depois de alguma operação ou representar vários estados sucessores. Imagine tentar implementar uma pesquisa abrangente, modificando um único objeto de estado.
Isso provavelmente aparece no mundo do banco de dados com mais frequência como dados temporais . Digamos no mês passado que você estava no plano Básico, mas no dia 16 você mudou para o plano Premium. Se simplesmente substituirmos algum campo que indica em qual plano você está, podemos ter dificuldades em acertar o faturamento. Também podemos perder a capacidade de analisar tendências. (Ei, veja o que essa campanha publicitária local fez!)
É o que me vem à cabeça quando você diz "imutabilidade no design do banco de dados", de qualquer maneira.
fonte
Customer
tabela apenas para lembrar que o usuário alterou o plano não traz nada, exceto enorme desvantagem de desempenho, seleções mais lentas ao longo do tempo, mineração de dados mais complicada (em comparação com logs) e mais espaço desperdiçado.Se você estiver interessado nos benefícios que pode obter da imutabilidade em um banco de dados, ou pelo menos em um banco de dados que ofereça a ilusão de imutabilidade, verifique Datomic.
Datomic é um banco de dados inventado por Rich Hickey em aliança com a Think Relevance, existem muitos vídeos nos quais eles explicam a arquitetura, os objetivos e o modelo de dados. Pesquise infoq, um em particular é intitulado Datomic, Database como um valor . Em confreaks, você pode encontrar uma palestra que Rich Hickey fez na conferência euroclojure em 2012. confreaks.com/videos/2077-euroclojure2012-day-2-keynote-the-datomic-architecture-and-data-model
Há uma conversa no vimeo.com/53162418 que é mais orientada para o desenvolvimento.
Aqui está outra de stuart halloway em.pscdn.net/008/00102/videoplatform/kv/121105techconf_close.html
Agora, como as informações são armazenadas como fatos no tempo:
O banco de dados é um valor e um parâmetro para o mecanismo de consulta, o QE gerencia a conexão e o cache. Como você pode ver o banco de dados como um valor e a estrutura de dados imutável na memória, é possível mesclá-lo com outra estrutura de dados feita com valores "no futuro" e transmiti-la ao QE e à consulta com valores futuros, sem alterar o banco de dados real .
Existe um projeto de código aberto da Rich Hickey, chamado codeq , que pode ser encontrado no github Datomic / codeq, que estende o modelo git e armazena referências a objetos git em um banco de dados livre de datomic e faz consultas ao seu código. pode ver um exemplo de como usar datomic.
Você pode pensar em datômico como um ACID NoSQL, com dados que você pode modelar tabelas ou documentos ou lojas Kv ou gráficos.
fonte
A idéia de evitar atualizações e preferir inserções é um dos pensamentos por trás da criação de seu armazenamento de dados como uma Fonte de Eventos, uma ideia que você encontrará frequentemente usada junto com o CQRS. Em um modelo de origem de eventos, não há atualização: um agregado é representado como a sequência de sua "transformação" (eventos) e, como resultado, o armazenamento é apenas anexado.
Este site contém discussões interessantes sobre CQRS e fornecimento de eventos, se você estiver curioso sobre isso!
fonte
Isso mantém uma relação muito próxima com o que é conhecido como "Dimensões de alteração lenta" no mundo do data warehousing e as tabelas "Temporal" ou "Bi-Temporal" em outros domínios.
A construção básica é:
As vantagens desse esquema são que você pode recriar o "estado" de sua entidade lógica a qualquer momento, ter um histórico de sua entidade ao longo do tempo e minimizar a contenção se sua "entidade lógica" for muito usada.
As desvantagens são que você armazena muito mais dados e precisa manter mais índices (pelo menos em Chave lógica + ValidFrom + ValidTo). Um índice na Chave Lógica + Versão Mais Recente acelera bastante a maioria das consultas. Também complica seu SQL!
Se vale a pena fazer isso, a menos que você realmente precise manter um histórico e tenha um requisito para recriar o estado de suas entidades em um determinado momento, depende de você.
fonte
Outro motivo possível para ter um banco de dados imutável seria oferecer suporte ao melhor processamento paralelo. As atualizações que estão fora de ordem podem atrapalhar os dados permanentemente; portanto, é necessário bloquear para impedir isso, destruindo o desempenho paralelo. Muitas inserções de eventos podem ocorrer em qualquer ordem, e o estado estará no mínimo correto , desde que todos os eventos sejam processados. No entanto isso é tão difícil de trabalhar na prática, comparado a fazer atualizações de banco de dados que você teria que realmente precisa de um monte de paralelismo considerar fazer as coisas desta maneira - eu estou não recomendá-lo.
fonte
Disclaimer: Eu sou praticamente um novato no DB: p
Dito isto, essa abordagem de saturação de dados tem um impacto imediato no desempenho:
dependendo de seus requisitos, você pode aceitar isso ou não, mas certamente é um ponto a considerar.
fonte
Não vejo como seu esquema possa ser chamado de "imutável".
O que acontece quando um valor armazenado na tabela suplementar é alterado? Parece que você precisaria executar uma atualização nessa tabela.
Para que um banco de dados seja realmente imutável, ele precisará ser mantido apenas por "INSERTS". Para isso, você precisa de algum método para identificar a linha "atual". Isso quase sempre acaba sendo terrivelmente ineficiente. Você precisa copiar todos os valores inalterados anteriores ou juntar o estado atual de vários registros ao consultar. A seleção da linha atual geralmente precisa de um SQL horrivelmente bagunçado como (
where updTime = (SELECT max(updTime) from myTab where id = ?
).Esse problema surge muito no DataWarehousing, no qual você precisa manter um histórico dos dados ao longo do tempo e poder selecionar o estado para qualquer ponto no tempo. A solução é geralmente tabelas "dimensionais". No entanto, enquanto eles resolvem o problema da DW "quem era o representante de vendas em janeiro passado". Eles não fornecem nenhuma das vantagens que as classes imutáveis do Javas oferecem.
Em uma nota mais filosófica; existem bancos de dados para armazenar "estado" (saldo bancário, consumo de eletricidade, pontos de brownie no StackOverflow etc. etc.). Tentar criar um banco de dados "sem estado" parece um exercício inútil.
fonte
WHERE id = {} ORDER BY updTime DESC LIMIT 1
geralmente não é muito ineficiente.