Prática recomendada ou padrões de design para recuperação de dados para relatórios e painéis em um aplicativo rico em domínio

44

Primeiro, quero dizer que essa parece ser uma pergunta / área negligenciada; portanto, se essa pergunta precisar ser aprimorada, ajude-me a fazer desta uma ótima pergunta que possa beneficiar outras pessoas! Estou procurando conselhos e ajuda de pessoas que implementaram soluções que resolvem esse problema, não apenas idéias para tentar.

Na minha experiência, existem dois lados de um aplicativo - o lado "tarefa", que é amplamente orientado por domínio e é onde os usuários interagem amplamente com o modelo de domínio (o "mecanismo" do aplicativo) e o lado de relatório, onde os usuários obtenha dados com base no que acontece no lado da tarefa.

No lado da tarefa, fica claro que um aplicativo com um modelo de domínio avançado deve ter lógica de negócios no modelo de domínio e o banco de dados deve ser usado principalmente para persistência. Separação de preocupações, todo livro é escrito sobre isso, sabemos o que fazer, incrível.

E o lado dos relatórios? Os data warehouses são aceitáveis ​​ou são de design ruim porque incorporam a lógica de negócios no banco de dados e nos próprios dados? Para agregar os dados do banco de dados nos dados do data warehouse, você deve ter aplicado a lógica e as regras de negócios aos dados, e essa lógica e as regras não vieram do seu modelo de domínio, vieram dos seus processos de agregação de dados. Isso está errado?

Trabalho em grandes aplicações financeiras e de gerenciamento de projetos, onde a lógica de negócios é extensa. Ao relatar esses dados, muitas vezes terei MUITAS agregações para extrair as informações necessárias para o relatório / painel, e as agregações possuem muita lógica de negócios. Por uma questão de desempenho, tenho feito isso com tabelas e procedimentos armazenados altamente agregados.

Como exemplo, digamos que um relatório / painel seja necessário para mostrar uma lista de projetos ativos (imagine 10.000 projetos). Cada projeto precisará de um conjunto de métricas mostradas, por exemplo:

  1. orçamento total
  2. esforço até hoje
  3. taxa de queimadura
  4. data de esgotamento do orçamento na taxa de queima atual
  5. etc.

Cada um deles envolve muita lógica de negócios. E não estou falando apenas de multiplicar números ou de alguma lógica simples. Estou falando de, para obter o orçamento, você deve aplicar uma tabela de preços com 500 taxas diferentes, uma para o tempo de cada funcionário (em alguns projetos, outros têm um multiplicador), aplicar despesas e qualquer marcação apropriada etc. lógica é extensa. Foram necessários muitos ajustes de agregação e consulta para obter esses dados em um período de tempo razoável para o cliente.

Isso deve ser executado primeiro no domínio? E o desempenho? Mesmo com consultas SQL diretas, mal estou obtendo esses dados com rapidez suficiente para que o cliente seja exibido em um período de tempo razoável. Não consigo imaginar tentar obter esses dados para o cliente com rapidez suficiente se estiver reidratando todos esses objetos de domínio, misturando, combinando e agregando seus dados na camada do aplicativo ou tentando agregar os dados no aplicativo.

Nesses casos, parece que o SQL é bom em processar dados e por que não usá-los? Mas então você tem lógica de negócios fora do seu modelo de domínio. Qualquer alteração na lógica de negócios precisará ser alterada no modelo de domínio e nos esquemas de agregação de relatórios.

Estou realmente sem saber como projetar a parte de relatórios / painel de qualquer aplicativo com relação ao design orientado a domínio e boas práticas.

Eu adicionei a tag MVC porque MVC é o sabor do dia e estou usando-a no meu design atual, mas não consigo descobrir como os dados do relatório se encaixam nesse tipo de aplicativo.

Estou procurando qualquer ajuda nesta área - livros, padrões de design, palavras-chave para o google, artigos, qualquer coisa. Não consigo encontrar nenhuma informação sobre este tópico.

EDITAR E OUTRO EXEMPLO

Outro exemplo perfeito que encontrei hoje. O cliente deseja um relatório para a equipe de vendas do cliente. Eles querem o que parece ser uma métrica simples:

Para cada vendedor, quais são as vendas anuais até o momento?

Mas isso é complicado. Cada vendedor participou de várias oportunidades de vendas. Alguns ganharam, outros não. Em cada oportunidade de vendas, há vários vendedores aos quais é atribuída uma porcentagem de crédito para a venda, de acordo com sua função e participação. Então, agora, imagine passar pelo domínio para isso ... a quantidade de reidratação do objeto que você precisaria fazer para extrair esses dados do banco de dados para cada vendedor:

Obtenha todo o SalesPeople->
Para cada um obtenha o seu SalesOpportunities->
Para cada um obtenha a sua porcentagem da venda e calcule o valor das Vendas
e adicione o valor total das SalesOpportunityVendas.

E essa é uma métrica. Ou você pode escrever uma consulta SQL que pode fazer isso de maneira rápida e eficiente e ajustá-la para ser rápida.

EDIT 2 - Padrão CQRS

Eu li sobre o Padrão CQRS e, embora intrigante, até Martin Fowler diz que não foi testado. Então, como esse problema foi resolvido no passado. Isso deve ter sido enfrentado por todos em algum momento ou outro. O que é uma abordagem estabelecida ou desgastada, com um histórico de sucesso?

Editar 3 - Sistemas / Ferramentas de Relatório

Outra coisa a considerar neste contexto são as ferramentas de relatório. O Reporting Services / Crystal Reports, o Analysis Services e o Cognoscenti, etc. esperam dados do SQL / banco de dados. Eu duvido que seus dados cheguem aos seus negócios mais tarde. E, no entanto, eles e outras pessoas como eles são parte vital dos relatórios em muitos sistemas grandes. Como os dados para esses dados são manipulados adequadamente, onde existe uma lógica comercial na fonte de dados para esses sistemas e possivelmente nos próprios relatórios?

Richard
fonte
3
Desculpe, não tive a intenção. O mod me disse para repassar aqui, mas, aparentemente, foi capaz de migrar a mesma pergunta, então eu peguei duas. Me desculpe por isso.
Richard
Estou confuso. Ninguém fez isso? Ninguém enfrenta esse problema?
Richard
A sua 'separação de interesses' não é um pouco teórica? Você poderia dizer que o lado do relatório também possui regras de negócios, portanto não pode evitar colocar a lógica de negócios em toda a cadeia. Qualquer que seja a ferramenta de BI usada, você terá que criar resultados intermediários, desde as tarefas de entrada até o estágio de relatório (definindo objetos agregados e assim por diante). Então, tudo se resume à questão de onde processar o quê. Talvez você possa abordar o problema com uma metáfora de pirâmide (com a parte superior cortada) ou funil.
precisa saber é o seguinte
@ JanDoggen Esse é exatamente o meu ponto. A ferramenta de BI precisará ter lógica BL nele. Agora estou duplicando o BL que está no rico domínio do meu produto de software. Tudo bem?
Richard

Respostas:

16

Essa é uma resposta muito simples, mas vamos direto ao cerne da questão:

Em termos de DDD, talvez pense em relatar como um Contexto Limitado? Portanto, sim, tudo bem se o domínio de relatório contiver lógica de negócios, assim como o domínio transacional terá lógica de negócios transacional.

Quanto à questão de, digamos, procedimentos armazenados SQL versus modelo de domínio no código do aplicativo, os mesmos prós e contras se aplicam ao sistema de relatórios e ao sistema transacional.

Como vejo que você adicionou uma recompensa à pergunta, li a pergunta novamente e notei que você estava solicitando recursos específicos sobre isso, então pensei em começar sugerindo que você analise outras perguntas sobre o estouro de pilha, e encontrei este https://stackoverflow.com/questions/11554231/how-does-domain-driven-design-handle-reporting

A essência geral disso é usar o CQRS como um padrão para o seu sistema, que é consistente com o DDD, e confiar nas responsabilidades do lado da consulta como uma maneira de realizar a geração de relatórios, mas não tenho certeza de que seja uma resposta útil em seu caso.

Também encontrei este http://www.martinfowler.com/bliki/ReportingDatabase.html , que encontrei vinculado aqui: http://groups.yahoo.com/neo/groups/domaindrivendesign/conversations/topics/2261

Aqui está um artigo interessante da ACM sobre o assunto: http://dl.acm.org/citation.cfm?id=2064685, mas está por trás de um paywall, então não consigo lê-lo (não é um membro da ACM :().

Também há esta resposta aqui em uma pergunta semelhante: https://stackoverflow.com/questions/3380431/cqrs-ddd-synching-reporting-database

e este: http://snape.me/2013/05/03/applying-domain-driven-design-to-data-warehouses/

Espero que isto ajude!

RibaldEddie
fonte
Oi @RibaldEddie. Obrigado pela resposta. Não me parece nada fácil. Então você está dizendo que não há problema em tratar os procedimentos armazenados como a camada de domínio para o Contexto vinculado a relatórios?
Richard
Se você tem um bom motivo para fazer isso na sua situação, tudo bem. Pessoalmente, não tenho certeza se usaria o SP em qualquer caso, exceto, talvez, para alguma validação ou limpeza de dados, caso contrário, tenderia a evitar isso em todos os casos.
precisa saber é o seguinte
4

Meu entendimento da sua pergunta é o seguinte: O aplicativo para tarefas diárias foi

Exibir >> Controlador >> Modelo (BL) >> Banco de Dados (Dados)

Pedido para fins de relatório

Exibir >> Controlador >> Modelo >> Banco de Dados (Dados + BL)

Portanto, a alteração no BL para ' aplicativo de tarefa ' também levará à alteração no ' relatório ' de BL. Esse é o seu verdadeiro problema, certo? Bem, tudo bem fazer alterações duas vezes, essa dor que você precisa tomar de qualquer maneira. O motivo é que os BLs são separados por suas respectivas preocupações. Um é para buscar dados e outro para agregar dados. Além disso, seu BL original e o BL agregado serão gravados em diferentes tecnologias ou idiomas ( C # / java e SQL proc ). Não há como escapar.

Vamos dar outro exemplo não relacionado a relatórios especificamente. Suponha que uma empresa XXX rastreie e-mails de todos os usuários para interpretação e venda essas informações para empresas de marketing. Agora ele terá um BL para interpretação e um BL para agregar dados para empresas de marketing. As preocupações são diferentes para ambos os BLs. Amanhã, se o BL mudar de tal forma que os e-mails provenientes de Cuba devam ser ignorados, a lógica comercial será alterada nos dois lados.

theinsaneone
fonte
3

Os relatórios são um contexto limitado ou um subdomínio, para falar livremente. Ele resolve uma necessidade comercial de coletar / agregar dados e processá-los para obter inteligência de negócios.

Como você implementa esse subdomínio provavelmente será um equilíbrio entre a maneira (mais) arquiteturalmente correta de fazer isso e o que sua infraestrutura permitirá. Eu gosto de começar pelo lado anterior e avançar para o segundo apenas quando necessário.

Provavelmente, você pode dividir isso em dois problemas principais que está solucionando:

  1. Agregando ou armazenando dados. Isso deve processar alguma fonte de dados e combinar as informações de forma que sejam armazenadas em outra fonte de dados.

  2. Consultando a fonte de dados agregada para fornecer inteligência de negócios.

Nenhum desses problemas faz referência a qualquer banco de dados ou mecanismo de armazenamento específico. Sua camada de domínio deve apenas lidar com interfaces, implementadas na camada de infraestrutura por vários adaptadores de armazenamento.

Você pode ter vários trabalhadores ou algum trabalho agendado, dividido em algumas partes móveis:

  • Algo para consultar
  • Algo a agregar
  • Algo para guardar

Espero que você possa ver alguns dos CQRS brilharem por lá.

No lado dos relatórios, ele só precisa fazer consultas, mas nunca diretamente no banco de dados. Acesse suas interfaces e sua camada de domínio aqui. Esse não é o mesmo domínio do problema que suas tarefas principais, mas ainda deve haver alguma lógica aqui que você deseja aderir.

Assim que você mergulha diretamente no banco de dados, você depende mais dele e, eventualmente, pode interferir nas necessidades de dados do aplicativo original.

Além disso, pelo menos para mim, eu definitivamente prefiro escrever testes e desenvolver código em vez de consultas ou procedimentos armazenados. Também gosto de não me prender em ferramentas específicas até que seja absolutamente necessário.

Adrian Schneider
fonte
2

É comum separar armazenamentos de dados operacionais / transacionais dos relatórios. O último pode ter requisitos para manter os dados por motivos legais (por exemplo, sete anos de dados financeiros para auditoria financeira) e você não deseja tudo isso em seu armazenamento de dados transacionais.

Assim, você particionará seus dados transacionais por algum tempo (semanal, mensal, trimestral, anual) e moverá as partições antigas para o repositório de dados de relatórios / histórico via ETL. Pode ou não ser um data warehouse com um esquema e dimensões em estrela. Você usaria ferramentas de relatório de data warehousing para fazer consultas ad hoc, roll-ups e tarefas em lote para gerar relatórios periódicos.

Eu não recomendaria relatar seu armazenamento de dados transacionais.

Se você preferir continuar, aqui estão mais pensamentos:

  1. "Melhor" é subjetivo e o que funciona.
  2. Eu compraria um produto de relatório em vez de escrevê-lo pessoalmente.
  3. Se você estiver usando um banco de dados relacional, o SQL é o único jogo na cidade.
  4. Os procedimentos armazenados dependem se você possui as habilidades necessárias para escrevê-los.

Software de gerenciamento de projetos que você usa internamente? Eu compraria antes de construir. Algo como o Rally e o Microsoft Project.

duffymo
fonte
Obrigado @duffymo. Esses dados não são armazenados apenas por motivos legais. São toneladas e toneladas de dados que são usados ​​e relatados regularmente. A empresa vive e morre de acordo com os relatórios e painéis. Afinal, é um software de gerenciamento de projetos. Qual é a melhor maneira de fornecer esses relatórios e painéis com os dados? Agregando e retirando com SQL? Não há problema em que a lógica comercial esteja nos Procedimentos da Loja para isso? Todas as minhas perguntas ainda não foram respondidas!
Richard
Você tem uma resposta - data warehouse. Parece que não era o que você queria ouvir. Veja acima para edições.
duffymo
Portanto, é bom duplicar a lógica de negócios que está no domínio no dts e no data warehouse? Além disso, depois de extrair esses dados, eu uso algum tipo de modelo de domínio? Ou apenas retire os dados com procedimentos armazenados e exiba na exibição? Para abordar seus pontos acima: Não consigo comprar um produto de relatório ... a razão pela qual estou escrevendo isso é que a empresa tem necessidades específicas não atendidas por nenhum produto de relatório. Estou usando um banco de dados relacional e tenho muito boas habilidades em SQL. Mas não quero usar como padrão o que sou bom, quero fazer o que é bom design.
Richard
Re: compre antes de construir - você não pode forçar uma empresa a moldar seus negócios para o software quando eles desejam que o software seja construído para se adequar aos seus negócios. O Rally e o MS Project não atendem às necessidades de gerenciamento de projetos de todos. Em absoluto.
Richard
Não pode forçar, é claro. Mas todas as empresas decidem o que é do interesse delas. Se você não está vendendo software de gerenciamento de projetos, é de seu interesse avaliar se é melhor comprá-lo. Assim como o software de contabilidade. Quem, em sã consciência, escreveria uma contabilidade geral do zero?
duffymo
2

Primeiro, alguma terminologia, o que você chama de lado da tarefa é conhecido como Transacional e o lado de Relatórios é Analytics.

Você já mencionou o CQRS, que é uma ótima abordagem, mas há pouca aplicação prática documentada da abordagem.

O que foi amplamente testado é complementar o processamento Transacional com um mecanismo de processamento analítico. Isso às vezes é chamado de Data Warehousing ou Data Cubes. O maior problema em relação à análise é que tentar executar consultas nos dados transacionais em tempo real é ineficiente, na melhor das hipóteses, porque é realmente possível otimizar um banco de dados apenas para leitura ou gravação. Para transações, você deseja altas velocidades de gravação para evitar atrasos no processamento / execução. Para relatórios, você deseja altas velocidades de leitura para que decisões possam ser tomadas.

Como explicar esses problemas? A abordagem mais simples de entender é usar um esquema nivelado para seus relatórios e ETL (extrair carga de transformação) para transferir dados do esquema transacional normalizado para o esquema analítico desnormalizado. O ETL é executado regularmente por meio de um agente e pré-carrega a tabela de análise para que esteja pronta para uma leitura rápida do seu mecanismo de relatório.

Um ótimo livro para acelerar o armazenamento de dados é o Data Warehouse Toolkit, de Ralph Kimball. Para uma abordagem mais prática. Faça o download da avaliação do SQL Server e escolha o kit de ferramentas do Microsoft Data Warehouse, que aborda a discussão geral do primeiro livro, mas mostra como aplicar os conceitos usando o SQL Server.

Existem vários livros vinculados dessas páginas que fornecem mais detalhes sobre ETL, Star Schema Design, BI, painéis e outros tópicos para ajudá-lo.

A maneira mais rápida de ir de onde você está para onde você quer estar é contratar um especialista em BI e protegê-lo enquanto ele implementa o que você precisa.

Michael Brown
fonte
Olá Mike. Eu estou muito familiarizado com datawarehousing e BI, já o faço há 15 anos. Minha pergunta trata de como lidar com isso em um contexto de design controlado por domínio. Os datawarehouses estão ok? Ou eles são uma adulteração da camada de negócios do seu domínio? Se a resposta for criar um data warehouse e extrair os dados de lá, há muita literatura e conselhos por aí. Mas você está duplicando a lógica comercial fora do seu domínio. Tudo bem? Essa é a minha pergunta.
Richard
Como mencionei endereços CQRS que precisam muito bem, separando o repositório no lado Comando (transacional) e Consulta (relatório). Mas, mesmo sem as outras características do CQRS, o data warehouse e o etl são clientes do seu domínio, mas não o modificam. Portanto, o BL ainda está contido no domínio.
Michael Brown
1
Eles não modificam o domínio ... então todos os processos ETL e transformações de dados para criar os dados para o data warehouse precisam passar pelo seu domínio? Caso contrário, seu BL será duplicado em toda a lógica de seus processos ETL.
Richard
1
Sim, eu diria que um ETL IDEALMENTE deve usar o domínio diretamente. Isso permitiria evitar ferramentas quebradiças que precisam ser reescritas a cada alteração interna no banco de dados.
Michael Brown
2

A recuperação de grandes quantidades de informações em redes de área ampla, incluindo a Internet, é problemática devido a problemas decorrentes da latência da resposta, falta de acesso direto à memória dos dados que servem os recursos e tolerância a falhas.

Esta pergunta descreve um padrão de design para resolver os problemas de manipulação de resultados de consultas que retornam grandes quantidades de dados. Normalmente, essas consultas são feitas por um processo do cliente em uma rede de área ampla (ou Internet), com uma ou mais camadas intermediárias, para um banco de dados relacional que reside em um servidor remoto.

A solução envolve a implementação de uma combinação de estratégias de recuperação de dados, incluindo o uso de iteradores para percorrer conjuntos de dados e fornecer um nível apropriado de abstração para o cliente, buffer duplo de subconjuntos de dados, recuperação de dados multiencadeados e divisão de consultas.

MyXEDNotes
fonte
Não tenho certeza de como isso se relaciona com a minha pergunta ou como obteve 3 votos tão rápido. Você também quis incluir um link aqui?
Richard
2
Parece que a recompensa foi concedida automaticamente a esta resposta. Esta resposta parece sem sentido para mim e eu não teria concedido a isso a recompensa.
Richard
2

E o lado dos relatórios? Os data warehouses são aceitáveis ​​ou são de design ruim porque incorporam a lógica de negócios no banco de dados e nos próprios dados?

Eu não acho que você esteja falando sobre lógica de negócios, isso é mais lógica de relatórios. O que os usuários fazem com as informações nesta tela, é simplesmente para atualizações de status? Seu modelo de domínio é usado para modelar operações transacionais, os relatórios são uma preocupação diferente. Puxar os dados do SQL Server ou colocá-los em um data warehouse é bom para cenários de relatórios.

Seu modelo de domínio deve aplicar os invariantes do seu domínio, como um membro do projeto não pode reservar para o mesmo projeto ao mesmo tempo ou pode reservar apenas x número de horas por semana. Ou você não pode reservar para este projeto, pois ele está completo, etc. O estado do seu modelo de domínio (os dados) pode ser copiado para geração de relatórios separadamente.

Para melhorar o desempenho da consulta, você pode usar uma exibição materializada. Quando uma operação é confirmada com relação ao seu modelo (por exemplo, reserve 4 horas desse tempo para o projeto x) e for bem-sucedida, pode ocorrer um evento que você pode armazenar em um banco de dados de relatórios e fazer os cálculos necessários para o seu relatório. Em seguida, será muito rápido consultá-lo.

Mantenha seus contextos de transação e relatório separados, um banco de dados relacional foi construído para relatar que um modelo de domínio não era.

EDITAR

Postagem útil do blog sobre o assunto http://se-thinking.blogspot.se/2012/08/how-to-handle-reporting-with-domain.html

Scott Millett
fonte
2

Passaram quatro anos e acabei de encontrar essa pergunta novamente e tenho o que é, para mim, a resposta.

Dependendo do aplicativo e das necessidades específicas, o banco de dados do domínio / transação e os relatórios podem ser "sistemas" ou "mecanismos" separados ou podem ser atendidos por um sistema. No entanto, eles devem ser logicamente separados - o que significa que eles usam diferentes meios de recuperar e fornecer dados para a interface do usuário.

Eu prefiro que eles sejam fisicamente separados (além de serem logicamente separados), mas muitas vezes você os inicia juntos (fisicamente) e, à medida que o aplicativo amadurece, você os separa.

De qualquer forma, novamente, eles devem ser logicamente diferentes. Não há problema em duplicar a lógica comercial no sistema de relatórios. O importante é que o sistema de relatórios obtenha a mesma resposta que o sistema de domínio - mas é provável que chegue lá por diferentes meios. Por exemplo, seu sistema de domínio terá uma tonelada de regras de negócios muito rígidas implementadas no código processual (provável). O sistema de relatório pode implementar essas mesmas regras quando lê os dados, mas o faria via código baseado em SET (por exemplo, SQL).

Aqui está como uma evolução da arquitetura do seu aplicativo pode parecer realista à medida que evolui:

Nível 1 - Domínio e sistemas de relatório separados logicamente, mas ainda na mesma base de código e banco de dados

Nível 1 - Domínio logicamente separado e sistemas de relatório, mas ainda na mesma base de código

Nível 2 - Sistemas de relatórios e domínios separados logicamente, mas agora separam bancos de dados, com sincronização.

Nível 2 - Domínio logicamente separado e sistemas de relatórios, mas bancos de dados separados agora

Nível 3 - Domínio e sistemas de relatórios separados lógica e fisicamente e separar bancos de dados com sincronização.

Nível 3 - Domínio e sistemas de relatórios separados lógica e fisicamente e separar bancos de dados com sincronização.

A idéia principal é que o relatório e o domínio tenham necessidades radicalmente diferentes. Diferentes perfis de dados (frequência de leituras versus gravações e atualizações), diferentes requisitos de desempenho, etc. Portanto, eles precisam ser implementados de maneira diferente e isso exige alguma duplicação da lógica de negócios.

Cabe a sua empresa criar uma maneira de manter a lógica de negócios do domínio e dos sistemas de relatórios atualizados entre si.

Richard
fonte
1

é necessário um relatório / painel para mostrar uma lista de projetos ativos

O estado de cada projeto deve ser armazenado como informações estáticas, calculadas e bem formatadas no banco de dados e quaisquer simulações devem ser tratadas no cliente como WebApp.

data de esgotamento do orçamento na taxa de queima atual

esse tipo de projeção não deve ser executado sob demanda. O gerenciamento dessas informações mediante solicitação, como realizar cálculos de recursos, taxa, tarefas, marcos etc., resultará em um uso extensivo da camada de cálculo, sem a reutilização desses resultados para chamadas futuras.

Imaginando um ambiente distribuído ( nuvem pública ou privada ), você terá enormes custos na camada de computação, baixo uso de banco de dados e total falta de cache.

Isso deve ser executado primeiro no domínio? E o desempenho?

O design do seu software deve incluir a capacidade de executar a normalização dos cálculos necessários para obter o resultado necessário durante a "entrada de dados", não durante a leitura. Essa abordagem reduz bastante o uso de recursos de computação e, acima de tudo, cria tabelas que podem ser consideradas como "somente leitura" pelo cliente. Este é o primeiro passo para criar um mecanismo de cache sólido e simples.

Portanto, uma pesquisa primeiro, antes de concluir a arquitetura do software, poderia ser o Sistema de Cache Distribuído .

(pedido: agregação)! = 1: 1

Minha consideração é, portanto (para o primeiro e o segundo exemplo), tente entender quando é adequado normalizar os dados, tendo como objetivo reduzir as agregações por solicitação do cliente. Que não pode ser 1: 1 (solicitação: agregação) se um objetivo é obter um sistema sustentável.

Distribua o cálculo no cliente

Outra questão, antes de terminar o design do software, pode ser: quanta normalização, queremos delegar o navegador do cliente?

Foi nomeado MV *, é verdade que está na moda hoje, além disso, um de seus objetivos é criar o WebApp (aplicativo de página única), que pode ser considerado o presente de muitos aplicativos complexos (e, felizmente, por faturas que pagamos ao provedor de nuvem, eles são executados no cliente).

Minha conclusão é, portanto:

  1. Compreender quantas operações são realmente necessárias para realizar a apresentação dos dados;

  2. Analise quantas delas podem ser feitas em segundo plano (e depois distribuídas por um sistema de cache, após a normalização);

  3. Compreender quantas operações podem ser executadas no cliente, obtendo a configuração dos projetos, executando-a em Views no WebApp e, assim, reduzir o cálculo realizado no backend;

marcocs
fonte
Olá Marcocs, obrigado pela sua resposta. Dois problemas que eu vejo ao fazer pré-agregações no lado do cliente é que 1. você tem MUITAS ações que podem resultar em um pré-cálculo e 2. Pode haver MUITOS pré-cálculos necessários. Coloque os dois juntos e você terá um uso muito pesado de recursos. Por exemplo ... o orçamento terá que ser recalculado quando A. qualquer taxa de cobrança no orçamento for alterada (isso pode ser acionado por várias coisas ... uma ação do usuário ou uma rolagem programada para uma nova taxa, por exemplo, o as taxas mudam no início de um novo ano fiscal) ou B. A composição do orçamento ...
richard
... altera, por exemplo, horas adicionadas ou subtraídas. Etc. A lista continua. Quanto ao número 2, as agregações necessárias ... amanhã, o cliente precisa ver agregações por região, depois deseja ver por funcionário, cidade, setor ou qualquer outro atributo maluco no projeto ou entidade relacionada. Você pré-agregará tudo isso? Nesse caso, agora você está criando um mecanismo OLAP ... Além disso, essas agregações pertencem armazenadas no objeto de projeto no domínio? Quando você apresentar os dados, quando usará um valor calculado versus o valor pré-calculado. Etc. Você fez este trabalho em um aplicativo do mundo real?
Richard
Estou interessado nessa abordagem, mas ela apresenta muitos problemas para minha mente.
Richard
Eu tenho um sistema de distribuição de lucros em funcionamento, meu problema era mostrar o status atual dos ganhos, com base nos dados gerados pelas sub-redes de agentes (incluindo saques, depósitos, jackpot, etc.). As sub-redes, eles usam seu saldo constantemente, isso aumenta / decreta os lucros do pai da rede. A distribuição dos ganhos é realizada periodicamente toda segunda-feira, o problema era mostrar em tempo real a evolução do ganho e atualizar o virtual orçamento de todas as redes.
marcocs
Para evitar agregações nas redes e distribuir todos os valores em tempo real, sempre que uma solicitação é feita, um processo de implantação temporária é executado continuamente para normalizar os ganhos das redes. Cada vez que você faz uma solicitação, os valores calculados são somados agregando o valor valores que não estão incluídos na implantação temporária (eu apenas trabalho com o item da última atualização). A tabela de transações (que obviamente é a que sofre a carga neste aplicativo), foi tratada com partições de tabela .
marcocs
1

Use cache para consulta, use domain para cache.

Há um recurso chamado "usuários principais" no stackoverflow. Você pode encontrar uma linha no topo da página dos principais usuários, que diz "Somente perguntas e respostas de outros wiki da comunidade estão incluídas nesses totais ( atualizados diariamente )". Isso indica que os dados estão armazenados em cache.

Mas por que?

Por questão de desempenho, talvez. Talvez eles tenham a mesma preocupação com a fuga de lógica de domínio ("Somente perguntas e respostas que não são do wiki da comunidade estão incluídas nesses totais" neste caso).

Quão?

Eu realmente não sei como eles fizeram isso, então aqui está apenas um palpite :)

Primeiro, precisamos encontrar perguntas / respostas alvo. Uma tarefa de agendamento pode funcionar, basta buscar todos os destinos em potencial.

Segundo, vejamos apenas uma pergunta / resposta. É um wiki não comunitário? É dentro de 30 dias? É muito fácil responder com modelos de domínio. Conte os votos e armazene-os em cache, se estiver satisfeito.

Agora temos o cache, eles são a saída de derivações de domínio. A consulta é rápida e fácil, porque há apenas critérios simples a serem aplicados.

E se os resultados precisarem ser mais "em tempo real"?

Eventos podem ajudar. Em vez de acionar o cache com uma tarefa de agendamento, podemos dividir o processo em muitos subprocessos. Por exemplo, quando alguém vota na resposta do hippoom, publicamos um evento que aciona a atualização do cache dos principais usuários do hippoom. Nesse caso, podemos ver pequenas tarefas rápidas e frequentes.

O CQRS é necessário?

Nem com a abordagem de tarefas de agendamento nem com a abordagem de eventos. Mas cqrs tem uma vantagem. O cache geralmente é altamente orientado para exibição; se alguns itens não forem necessários a princípio, talvez não possamos calculá-los e armazená-los em cache. O CQRS com fornecimento de eventos ajuda a reconsiderar o cache de dados históricos ao reproduzir eventos.

Algumas perguntas relacionadas:
1. https://stackoverflow.com/questions/21152958/how-to-handle-summary-report-in-cqrs 2. https://stackoverflow.com/questions/19414951/how-to-use -rich-domain-with-maciça-operações / 19416703 # 19416703

Espero que ajude :)

Yugang Zhou
fonte
0

Isenção de responsabilidade:
sou bastante inexperiente em aplicativos com modelos de domínio.
Entendo todos os conceitos e já penso há muito tempo sobre como aplicar esses conceitos aos aplicativos em que estou trabalhando (que são ricos em domínio, mas sem OO, modelos de domínio reais etc.) .
Esta questão é um dos principais problemas que eu também enfrentei. Eu tenho uma idéia de como resolver isso, mas como eu acabei de dizer ... é apenas uma ideia que eu tive.
Ainda não o implementei em um projeto real, mas não vejo uma razão para que não funcione.


Agora que deixei isso claro, eis o que eu criei - usarei seu primeiro exemplo (as métricas do projeto) para explicar:

Quando alguém edita um projeto, você está carregando e salvando-o por meio do seu modelo de domínio.
Nesse momento, você tem todas as informações carregadas para calcular todas as suas métricas (orçamento total, esforço até o momento etc.) para este projeto.

Você pode calcular isso no modelo de domínio e salvá-lo no banco de dados com o restante do modelo de domínio.
Portanto, a Projectclasse no seu modelo de domínio terá algumas propriedades como TotalBudget, EffortToDateetc., e também haverá colunas com esses nomes nas tabelas de banco de dados em que seu modelo de domínio está armazenado (nas mesmas tabelas ou em uma tabela separada ... doesn não importa) .

Obviamente, você precisa executar uma única vez para calcular o valor de todos os projetos existentes, ao começar com isso. Mas depois disso, os dados são atualizados automaticamente com os valores calculados atuais sempre que um projeto é editado por meio do modelo de domínio.

Portanto, sempre que você precisar de qualquer tipo de relatório, todos os dados necessários já estarão lá (pré-calculados) e você poderá fazer algo assim:

select ProjectName, TotalBudget, EffortToDate from Projects where TotalBudget > X

Não importa se você obtém os dados diretamente das tabelas em que o modelo de domínio está armazenado ou se de alguma forma extrai os dados em um segundo banco de dados, em um data warehouse ou o que quer que seja:

  1. Se o repositório de relatórios for diferente do repositório de dados real, você poderá copiar os dados das "tabelas de modelo de domínio"
  2. Se você consultar diretamente seu armazenamento de dados real, os dados já estarão lá e você não precisará calcular nada

Em ambos os casos, a lógica de negócios para os cálculos está em exatamente um lugar: o modelo de domínio.
Você não precisa dele em nenhum outro lugar; portanto, não é necessário duplicá-lo.

Christian Specht
fonte
Oi Christian, fico feliz em ver que não sou o único a lutar com isso. Obrigado pela sua resposta. Veja meus comentários na resposta da Marcocs para os problemas que vejo com essa abordagem. Todas as idéias sobre como lidar com isso seriam apreciadas!
Richard