3.1 milyar satır veri nasıl yönetilir?


14

Şu anda nispeten büyük miktarda veri için bir depolama şeması uygulamakla görevlendirildim. Verilere öncelikle geçerli bir data pointdeğeri belirlemek için erişilecek , ancak aynı zamanda veri eğilimi / analizi için geçmiş altı aylık geçmişi izlemem gerekiyor.

Son bir saatin min/ max/ sumdeğerini izlemek için yeni bir gereksinim eklendi .

NOT: İdeal olarak, bir MongoDB seçeneği dikkate almak istiyorum, ama önce SQL-Server seçenekleri tükendi göstermek gerekir.

Veri

Aşağıdaki tablo birincil veri kaynağını gösterir (en sık sorgulanan). Tabloda yaklaşık beş milyon satır olacak. Veri değişiklikleri ağırlıklı olarak ilk veri yükünden sonra UPDATEçok nadiren INSERTifade edilen ifadeler olacaktır . Her dataPointIdzaman seçeceğiniz gibi verileri kümelemeyi seçtim all values for a given data point.

// Simplified Table
CREATE TABLE [dbo].[DataPointValue](
    [dataPointId]  [int] NOT NULL,
    [valueId]      [int] NOT NULL,
    [timestamp]    [datetime] NOT NULL,
    [minimum]      [decimal](18, 0) NOT NULL,
    [hourMinimum]  [decimal](18, 0) NOT NULL,
    [current]      [decimal](18, 0) NOT NULL,
    [currentTrend] [decimal](18, 0) NOT NULL,
    [hourMaximum]  [decimal](18, 0) NOT NULL,
    [maximum]      [decimal](18, 0) NOT NULL

    CONSTRAINT [PK_MeterDataPointValue] PRIMARY KEY CLUSTERED ([dataPointId],[valueId])
)

İkinci tablo, yaklaşık 3,1 milyar satırda (son altı aylık verileri temsil etmektedir) önemli ölçüde daha büyüktür. Altı aydan eski veriler temizlenecektir; aksi halde kesinlikle veri INSERTifadeleri (~ 200 satır / sn, 720.000 satır / saat, haftada 17 milyon satır).

// Simplified Table
CREATE TABLE [dbo].[DataPointValueHistory](
    [dataPointId] [int]            NOT NULL,
    [valueId]     [int]            NOT NULL,
    [timestamp]   [datetime]       NOT NULL,
    [value]       [decimal](18, 0) NOT NULL,
    [delta]       [decimal](18, 0) NOT NULL

    CONSTRAINT [PK_MeterDataPointHistory] PRIMARY KEY CLUSTERED ([dataPointId], [valueId], [timestamp])

)

Beklenen şey, izlenen veri noktası değerlerinin sayısı 400 satıra / saniyeye yükseldikçe bu tablonun iki katına çıkmasıdır (bu nedenle ~ 10 milyar'a ulaşmak söz konusu değildir).

Soru (lar) (evet, birden fazla soru soruyorum ... hepsi birbiriyle yakından ilişkilidir).

Şu anda bir SQL-Server 2008 R2 Standard Edition veritabanı kullanıyorum. Tablo bölümleri (veya SQL Server ile gerekli performans düzeylerini vuramazsanız MongoDB) ile istediğiniz performans düzeyini elde edebiliyorsanız, Enterprise Edition'a yükseltme için büyük olasılıkla yapacağım. Aşağıdakilerle ilgili bilgi almak istiyorum:


1) Ben hesaplamamız gerekir düşünüldüğünde min, maxve sumson bir saat boyunca (olduğu gibi now - 60 minutes). Son verileri izlemek için en iyi yaklaşım nedir:

  • Son verileri veri hizmetinin hafızasında tutun. Her veri GÜNCELLEME ile hesaplanan min / maks / ortalama yazın.

  • Her UPDATE deyimi sırasında geçmiş tablosundan geçmiş geçmişi sorgulayın (sonraki soruyu etkiler mi?). Sorgu, bir veri noktası değeri için en son verilere erişiyor olacak ve yalnızca son milyon kayıt üzerinde mi tarama yapmalı?

  • Geçmiş tablosu aramasını önlemek için son geçmişi DataPointValue satırında saklayın. Belki sınırlandırılmış bir dize olarak saklanır ve UPDATE proc içinde işlenir?

  • Düşünmediğim diğer seçenek?


2) Çünkü DataPointValueHistory, yazıya karşı sorgular her zaman dataPointIdve bir veya daha fazla olacaktır valueId. Sorgulanan veriler genellikle son gün, hafta veya ay içindir, ancak bazı durumlarda tam altı ay boyunca olabilir.

Şu anda dataPointId / valueId / timeStamp veya timeStamp / dataPointId / valueId tarafından küme için daha mantıklı olup olmadığını denemek için örnek bir veri kümesi oluşturuyorum. Herkes bu büyüklükte bir tablo ile başa çıkmak ve kendi fikirlerini sunmaya istekli olursa, takdir edilecektir. Ben dizin parçalanma önlemek için ikinci seçenek doğru eğilerek, ancak sorgu performansı kritiktir.

  • Küme DataPointValueHistory> valueId - -> Zaman Damgası dataPointId tarafından

  • Küme DataPointValueHistorygöre timeStamp -> dataPointId -> valueId


3) Son olarak, yukarıda belirtildiği gibi, DataPointValueHistorytabloyu bölümlendirmenin mantıklı olacağını düşünüyorum . Geçmiş verilerinin en iyi şekilde nasıl bölümleneceğine dair herhangi bir öneri çok takdir edilecektir.

  • Önce zaman damgasıyla kümelenmişse, verilerin haftaya göre bölümlenmesi gerektiğini düşünüyorum (toplam 27 bölüm). En eski bölüm 27. haftadan sonra temizlenecektir.

  • Önce dataPointId tarafından kümelenmişse, verilerin kimliğin bazı modülü tarafından bölümlenmesi gerektiğini düşünüyorum?

Tablo bölümleme konusunda çok sınırlı deneyime sahip olduğum için, uzmanlığınız takdir edilecektir.


StackOverflow'daki bu sorunun sürümünü sildiniz mi?
Taryn

@bluefeet - Evet, konu dışı olarak işaretlendi ... bu yüzden SO sorusunu sildim ve burada yeniden oluşturdum (muhtemelen taşınmasını beklemeliydim).
Calgary Coder

Sorun değil, sadece soruların çapraz gönderilmediğinden emin oluyordum.
Taryn

Standart Sürüm'de, bölümlenmiş görünümleri ve birden çok temel tabloyu kullanarak verileri bölümlere ayırabilirsiniz. Bunu düşündüğünüzden emin değilim.
Jon Seigel

@Jon - Evet, manuel tablo bölümlerini dikkate aldım (bu özel seçim, mevcut bir Enterprise lisansı olup olmamasına bağlı olacaktır ... evet ise, neden kendim rol yapıyorum).
Calgary Coder

Yanıtlar:


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.