Toplam değerlerin hesaplanmasında vs saklama


96

Toplam değerlerin ne zaman depolanacağını ve ne zaman anında hesaplanacağını belirleyen kurallar veya kurallar var mı?

Örneğin, kullanıcıların oylayabilecekleri widget'larım olduğunu varsayalım (aşağıdaki şemaya bakın). Ne zaman bir widget göstersem, Ratingstablodaki ortalama kullanıcı derecelendirmesini hesaplayabilirim . Alternatif olarak, ortalama puanı Widgetmasaya koyabilirim . Bu, widget'ı her görüntülediğimde reytingi hesaplamaktan kurtarmamı sağlayacaktı, ancak daha sonra bir kullanıcı widget'ı derecelendirdiğinde ortalama notu yeniden hesaplamak zorunda kalacağım.

Ratings       Widgets
---------     -------
widget_id     widget_id
user_id       name              
rating        avg_rating  <--- The column in question

Yanıtlar:


58

Değişir. Önceden hesaplama yapan toplam değerler, yazma işlemine daha büyük bir yük getirmekte, türetmek daha zor olmaktadır.

Sık sık türetilmiş bir değere erişiyorsanız, ön hesaplama geçerli bir normalleştirme aşamasıdır. Ancak, bu örnekte Materyalleştirilmiş Görünüm (ana tablolara tetikle bağlanmış, diske yazılmış bir görünüm) kullanmanızı öneririm. Materyalize görünüm, sıkça sorulan ancak sıkıcı-türetilmiş verileri depolamak için tasarlanmıştır ve çok sayıda yazma ve düşük okuma sayısı için kullanışlıdır.

Yüksek yazma, yüksek okuma senaryosunda, arka planda, somutlaştırılmış bir görünümün etkilerini taklit eden, ancak gerçek zamanlıdan daha az bir görevi yerine getirmeyi düşünün. Bu, yazma ve okuma performansını korurken "yeterince iyi" bir ortalama sunar.

Hiçbir koşulda, türetilmiş sütuna "normal" bir sütun gibi davranmanız gerekmez: Pencere Öğeleri "görünümünde" sunulan verilerin tablonun herhangi bir yerinde mevcut olduğundan emin olun; Bu soru ayrıca güçlü bir veritabanına (ve veritabanı sürümüne) özgüdür, bu nedenle toplam boyutunun (uygun dizinlerle) normal boyutta bir veri kümesine ve materyalize görünüme karşı performans testini öneririm.


Bu tartışmayı Materyalleşmiş görüşler konusunda çok faydalı buldum . Oracle'a uyarlanmıştır, ancak genel olarak anlaşılabilir. Benim gibi bir MySQL geçmişinden gelenler için, bir MySQL görünümü Materyalleştirilmiş görünümden farklı, sanal ve diske kaydetmiyor (verdiğim bağlantıda bahsedildiği gibi).
Siddhartha

upvoted! Kesin soruyu sormak üzereydi, SMA, EMA, WMA, RSI vb. gibi göstergeleri depolamalıyım ve ağır hesaplamalar içermeli, şu anda manuel olarak yenilediğim bir tablo hazırlıyorum, bu göstergeler her zaman% 100 değişiyor yeni veriler geliyor, onları korumak için iyi bir strateji nedir, herkes sola ve sağa
bakmaya

11

Temel sayıların ne sıklıkla değiştirildiği / güncellendiğine bağlı olarak değerleri ne sıklıkta hesaplamanız / göstermeniz gerekir.

Bu nedenle, günde yalnızca bir kez değişecek bir değeri görüntüleyen günlük hit sayısı 10 k olan bir web siteniz varsa, bunu temel değerler değiştiğinde (bir veritabanı tetikleyicisi olabilir, ne olursa olsun) hesaplardım.

İstatistiklere gidip gelmek için bir aracınız varsa, istatistiklerin ikinciye göre değiştiği, ancak yalnızca üç kişi erişiminiz var ve buna günde birkaç kez bakıyorlarsa, hesaplamayı daha çok istiyorum. anında. (ilk etapta bayat veriye sahip olmanın büyük bir sorun olmadığını hesaplamak için birkaç dakika sürüyorsa ... ve patronum bana her saat cron'dan bir şey üretmemi söyledi. bakmak istediğinde beklemek.)


her 15 dakikada bir, metrik başına 1000 satırla% 100 değişen 10 ölçüm
PirateApp

1
@PirateApp ve ortalama 15dk bir pencerede kaç kez izleniyor? Ayrıca, 15 dakikalık bir pencerede ilk talepte bunu yapabilir ve daha sonra tekrar tekrar vurmaya devam eden insanlar için önbellek oluşturabilir
Joe

o bir web sitesinde olacak, bu yüzden en az 10000 kişinin yeni başlayanlar için
göreceğini sanıyorum

1
Mesele, ne kadar sıklıkla değiştiğine bağlı olarak kaç tane istek olduğu. Bu nedenle, temel verilerin değişmesinden önce 10.000 kez görülecek bir şey önceden oluşturursanız, evet, önceden oluşturun. Yalnızca bir kez veya bir kereden az görüntüleniyorsa (veriler çok hızlı değiştiğinden veya sayfa nadiren baktığından), siz yapmazsınız.
Joe,

4

StaleWidgets tablosunu "geçersiz" (yeniden hesaplanacak) widget'ların kuyruğu olarak kullanın. Bu değerleri yeniden hesaplayabilen başka bir iş parçacığı (zaman uyumsuz) görevi kullanın. Yeniden hesaplamaların süresi veya anı sistem gereksinimlerine bağlıdır:

  • sadece okudum
  • ayın sonunda
  • Günün başında bazı kullanıcılar için
  • ...

1
Peki bayat sırasına nasıl girerler?
jcolebrand

2
@jcolebrand .. bir widget için derecelendirme ekleme / silme anında (Puan tablosu). Şu anda Widget tablosundaki ortalama değer geçersiz hale geliyor, bu nedenle yalnızca bir sütuna sahip olan StaleWidgets kaydını eklemek zorundayız - widget_id. Derecelendirmeler tablosuna veya elbette varyantınıza kayıt ekleyen tetikleyici veya depolanmış proc kullanın.
Garik

2

Eğer hesaplama çok zahmetli değilse ve karmaşık hesaplamaların ve sık güncellemelerin olduğu, ancak frequnet'in hesaplanan verileri saklayabileceğiniz ve yeniden hesaplamanın gerekip gerekmediğini depolayabilecek fazladan bir sütun (bool) varsa, anında hesaplanmasını öneririm. . Örneğin, yeniden hesaplama yapılması gerektiğinde ancak yeniden hesaplama yapmamanız durumunda ve yeniden hesaplama yaptığınızda bu sütunu yanlış olarak ayarlayın (bu hesaplanan değeri en son ve eski değil) gösterecektir).

Bu şekilde her seferinde yeniden hesaplamak zorunda kalmazsınız, yalnızca okuma ve yeniden hesaplama sütun değerinin doğru olduğu durumlarda hesaplarsınız. Bu şekilde yeniden hesaplamadan tasarruf edersiniz.


2

Özellikle, tüm puanları eklemek ve ortalamayı bulmak için toplama bölmek zorunda olmadığınız farklı bir çözüm var. Bunun yerine, incelemelerin toplamını içeren başka bir alana sahip olabilirsiniz, böylece bir derecelendirme eklediğiniz her yeni ortalama (avg_rating × total + new_rating) / total kullanarak hesaplarsanız, bu toplamdan çok daha hızlıdır ve disk değerlerini azaltır tüm derecelendirme değerlerine erişmek zorunda değilsiniz. Benzer durumlar diğer durumlar için de geçerli olabilir.

Bunun dezavantajı, bir asit işlemi olmamasıdır, bu yüzden eski bir derecelendirme ile sona erebilir. Ancak yine de bunu veritabanındaki tetikleyicileri kullanarak çözebilirsiniz. Diğer bir problem ise, veritabanının artık normalize edilmemesi, ancak performans karşılığında verileri denormalize etmekten korkmamanızdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.