Şu anda nispeten büyük miktarda veri için bir depolama şeması uygulamakla görevlendirildim. Verilere öncelikle geçerli bir data point
değ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
/ sum
değ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 INSERT
ifade edilen ifadeler olacaktır . Her dataPointId
zaman 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 INSERT
ifadeleri (~ 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
, max
ve sum
son 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 dataPointId
ve 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ındanKüme
DataPointValueHistory
göre timeStamp -> dataPointId -> valueId
3) Son olarak, yukarıda belirtildiği gibi, DataPointValueHistory
tabloyu 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.