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 / 239
Accepted
BenV
BenV
Asked: 2011-01-05 17:32:11 +0800 CST2011-01-05 17:32:11 +0800 CST 2011-01-05 17:32:11 +0800 CST

Armazenar vs calcular valores agregados

  • 772

Existem diretrizes ou regras práticas para determinar quando armazenar valores agregados e quando calculá-los em tempo real?

Por exemplo, suponha que eu tenha widgets que os usuários podem avaliar (veja o esquema abaixo). Cada vez que exponho um widget, posso calcular a classificação média do usuário na Ratingstabela. Alternativamente, eu poderia armazenar a classificação média na Widgetmesa. Isso me pouparia de ter que calcular a avaliação toda vez que eu exibir o widget, mas então eu teria que recalcular a avaliação média cada vez que um usuário avaliasse um widget.

Ratings       Widgets
---------     -------
widget_id     widget_id
user_id       name              
rating        avg_rating  <--- The column in question
mysql database-design
  • 5 5 respostas
  • 30987 Views

5 respostas

  • Voted
  1. Best Answer
    Brian Ballsun-Stanton
    2011-01-05T17:44:35+08:002011-01-05T17:44:35+08:00

    Depende. O pré-cálculo de valores agregados coloca uma carga maior nas gravações, derivá-las torna as leituras mais difíceis

    Se você estiver acessando frequentemente um valor derivado, o pré-cálculo é uma etapa de desnormalização válida. No entanto, neste caso, recomendo usar uma Visualização Materializada (uma visualização, gravada em disco, vinculada por gatilho às tabelas pai). A visualização materializada foi projetada para armazenar dados solicitados com frequência, mas tediosos para derivar, e é útil para números altos de gravações e números baixos de leituras.

    Em um cenário de alta gravação e alta leitura, considere ter uma tarefa em segundo plano que imite os efeitos de uma visualização materializada, mas em menos tempo real. Isso apresentará uma média "boa o suficiente", preservando o desempenho de gravação e leitura.

    Em nenhuma circunstância, você deve tratar a coluna derivada como uma coluna "normal": certifique-se de que os dados apresentados na "exibição" de Widgets estejam presentes em outro lugar na tabela, de modo que toda a tupla possa ser derivada por qualquer processo que você colocar. Essa questão também é fortemente específica do banco de dados (e da versão do banco de dados), portanto, recomendo testar o desempenho do agregado (com índices apropriados) em relação a um conjunto de dados de tamanho normal e a exibição materializada.

    • 63
  2. Joe
    2011-01-05T17:44:04+08:002011-01-05T17:44:04+08:00

    Com que frequência você precisa calcular/exibir os valores relativos à frequência com que os números subjacentes são alterados/atualizados.

    Portanto, se você tiver um site com 10 mil acessos diários que exibe um valor que só mudará uma vez por hora, eu o calcularia quando os valores subjacentes mudarem (pode ser um gatilho de banco de dados, qualquer que seja).

    Se você tiver uma ferramenta para ver as estatísticas, onde as estatísticas estão mudando a cada segundo, mas apenas três pessoas têm acesso, e elas só olham para ela algumas vezes por dia, é mais provável que eu calcule isso na mosca. (a menos que leve alguns minutos para calcular que ter dados obsoletos em primeiro lugar não é grande coisa ... e meu chefe me diz para apenas gerar a coisa do cron a cada hora, para que ele não tenha esperar quando ele quiser olhar para ele.)

    • 12
  3. garik
    2011-01-05T22:46:48+08:002011-01-05T22:46:48+08:00

    Use a tabela StaleWidgets como uma fila de widgets "inválidos" (a serem recalculados). Use outra tarefa de encadeamento (assíncrona) que possa recalcular esses valores. O período ou momento dos recálculos depende dos requisitos do sistema:

    • apenas lendo,
    • no final do mês,
    • para algum usuário no início do dia
    • ...
    • 4
  4. techExplorer
    2011-11-11T22:29:59+08:002011-11-11T22:29:59+08:00

    Eu sugeriria calcular em tempo real se o cálculo não for muito complicado e no caso de você ter cálculos complexos e atualizações frequentes, mas não que a leitura de frequência seja possível armazenar dados calculados e ter uma coluna extra (bool) que armazenará se o recálculo é necessário ou não . por exemplo, defina esta coluna como verdadeira sempre que o recálculo deve ser feito, mas não faça o recálculo e quando você fizer o recálculo, defina esta coluna como falsa (isto representará o valor calculado mais recente e não obsoleto).

    Dessa forma, você não precisa recalcular toda vez, você calculará apenas quando tiver que ler e o valor da coluna de recálculo for verdadeiro. Dessa forma, você economizará muito recálculo.

    • 2
  5. Adrian Martinez
    2018-12-21T03:16:55+08:002018-12-21T03:16:55+08:00

    Para o caso em particular existe uma solução diferente onde você não precisa somar todas as avaliações e dividir pelo total para encontrar a média. Em vez disso, você pode ter um outro campo que contenha o total das avaliações, portanto, cada vez que você adiciona uma classificação, calcula a nova média usando (avg_rating×total+new_rating)/total, isso é muito mais rápido do que o agregado e reduz as leituras do disco, pois você não precisa acessar todos os valores de classificação. Soluções semelhantes podem se aplicar a outros casos.

    A desvantagem disso é que não é uma transação ácida, então você pode terminar com uma classificação desatualizada. Mas ainda assim você pode resolver isso usando gatilhos no banco de dados. O outro problema é que o banco de dados não é mais normalizado, mas não tenha medo de desnormalizar dados em troca de desempenho.

    • 2

relate perguntas

  • Existem ferramentas de benchmarking do MySQL? [fechado]

  • Onde posso encontrar o log lento do mysql?

  • Como posso otimizar um mysqldump de um banco de dados grande?

  • Quando é o momento certo para usar o MariaDB em vez do MySQL e por quê?

  • Como um grupo pode rastrear alterações no esquema do banco de dados?

Sidebar

Stats

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

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

    • 4 respostas
  • Marko Smith

    Como você mostra o SQL em execução em um banco de dados Oracle?

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

    Posso ver Consultas Históricas executadas em um banco de dados SQL Server?

    • 6 respostas
  • Marko Smith

    Como uso currval() no PostgreSQL para obter o último id inserido?

    • 10 respostas
  • Marko Smith

    Como executar o psql no Mac OS X?

    • 11 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
  • Marko Smith

    Passando parâmetros de array para um procedimento armazenado

    • 12 respostas
  • Martin Hope
    Manuel Leduc Restrição exclusiva de várias colunas do PostgreSQL e valores NULL 2011-12-28 01:10:21 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Stuart Blackler Quando uma chave primária deve ser declarada sem cluster? 2011-11-11 13:31:59 +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
    BrunoLM Guid vs INT - Qual é melhor como chave primária? 2011-01-05 23:46:34 +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
  • Martin Hope
    Patrick Como posso otimizar um mysqldump de um banco de dados grande? 2011-01-04 13:13:48 +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