Atualizando várias entidades de uma vez usando o padrão do mapeador de dados

5

Tenho estudado padrões de arquitetura e design de software nas últimas semanas e, por uma semana, não consigo parar de pensar nos problemas de desempenho que acompanham a flexibilidade do padrão de mapeamento de dados. No livro escrito por Martin Fowler, ele dá um exemplo do padrão com alguns métodos find e apenas um método delete, um método update e um método insert. Então, quando ele precisa atualizar vários objetos, ele faz várias "viagens" para o banco de dados. Comecei a ler sobre o padrão Unit Of Work no mesmo livro, mas parece que por sua implementação ele não resolveu esse problema.

Existe uma solução que resolva esses problemas sem perder muita flexibilidade?

    
por Lucas Piske 17.07.2016 / 02:38
fonte

2 respostas

3

Eugene Philipov executou um benchmark em vários INSERT s em uma consulta e descobriu que eles são realmente mais rápidos do que executar muitas inserções sequenciais uma após a outra. Isso realmente não foi uma surpresa porque INSERT é uma operação muito simples.

Para atualizações, o motivo pelo qual você faria várias viagens a um banco de dados é porque o código é simplesmente mais fácil de entender pelo programador. A menos que seja considerado completamente necessário, a queda no desempenho não será substancial.

A situação de atualizações que se comportam de maneira diferente das inserções é causada pela cláusula CASE/WHEN que deve estar presente quando você deseja atualizar atributos de várias linhas com valores diferentes. Por causa disso, o banco de dados não apenas realiza pesquisa e atualização, mas também precisa decidir qual valor deve ser realmente usado como um substituto para o atual.

Você, como programador, sempre tem a opção de escrever um método que atualizaria um atributo de várias linhas com o mesmo valor. Em um nível de banco de dados, isso é muito simples de ser feito, você fornece uma visão de que linhas devem ser afetadas (provavelmente usando a cláusula IN ), então você fornece a substituição e está pronto. Nenhuma decisão sobre o nível do banco de dados, como sempre, apenas um simples procedimento de busca e substituição.

Eu disse que atualizar várias linhas com valores diferentes não tem o mesmo desempenho que vários INSERT , mas ainda assim, será um pouco mais rápido do que fazer várias viagens ao banco de dados, porque isso custa recursos (principalmente tempo - para conectar ao banco de dados) e executar cada consulta). Mas, a menos que você esteja falando sobre milhões de linhas de atualização em massa, não acho que precisa se preocupar.

Você mencionou Martin Fowler em seu exemplo faz várias viagens ao banco de dados. No livro, ele mostra um exemplo da ação de inserção, em que cada registro é processado individualmente. Mesmo assim, o próprio Martin Fowler diz o seguinte:

To avoid multiple database calls, you can leave all your updates to the end. To do this you need to keep track of all the objects that have changed. You can use variables in your code for this, but they soon become unmanageable once you have more than a few. Variables often work fine with a Transaction Script (110), but they can be very difficult with a Domain Model (116).

Rather than keep objects in variables you can give each object a dirty flag that you set when the object changes. Then you need to find all the dirty objects at the end of your transaction and write them out.


Source: Martin Fowler, P of EAA

A parte importante da citação é: você pode deixar todas as suas atualizações no final . Note como ele não diz que você deve fazê-lo, porque na maioria dos casos simplesmente não é necessário. Pela minha experiência, a operação em massa (operação que significa INSERT , UPDATE e / ou DELETE ) hack não resolve completamente seu problema de desempenho. Se você tem um, é mais provável que conserte isso melhorando sua arquitetura, introduzindo o cache, talvez usando tecnologias diferentes e outros enfeites.

Acho que você está preocupado com a otimização prematura . Sim, é incrível ter uma visão de um sistema que é muito rápido, mas é ainda melhor ter um sistema pronto para que você possa realmente usá-lo.

Então, enquanto o Sr. Fowler não fornece um exemplo real de atualizações em massa, é completamente possível se / quando necessário. Ele provavelmente optou por não mostrar um exemplo disso, porque a abordagem sequencial regular geralmente funciona. Essa é minha suposição. Sua razão por trás de não colocá-lo no livro pode ser diferente, mas para isso você precisa perguntar diretamente a ele.

    
por 17.07.2016 / 12:50
fonte
0

Tenha em mente que, se for uma rede entre o seu programa e o banco de dados, é muito fácil escrever código que se torne vinculado a E / S.

Além disso, se você estiver processando transações, poderá ter que fazer várias viagens ao banco de dados, dependendo do mecanismo usado para rastrear as transações.

    
por 22.07.2016 / 19:39
fonte