Saat ini saya ditugaskan mengimplementasikan skema penyimpanan untuk jumlah data yang relatif besar. Data terutama akan diakses untuk menentukan data point
nilai saat ini , tetapi saya juga diharuskan untuk melacak sejarah enam bulan terakhir untuk tren / analisis data.
Persyaratan terbaru ditambahkan untuk melacak nilai min
/ max
/ sum
selama satu jam terakhir.
CATATAN: Idealnya, saya ingin mempertimbangkan opsi MongoDB, tetapi saya perlu menunjukkan bahwa saya telah menghabiskan opsi SQL-Server terlebih dahulu.
Data
Tabel berikut ini menunjukkan sumber data primer (paling sering ditanyakan). Tabel akan memiliki sekitar lima juta baris. Perubahan data sebagian besar akan menjadi UPDATE
pernyataan dengan pernyataan yang sangat sesekali INSERT
setelah memuat data awal. Saya telah memilih untuk mengelompokkan data dataPointId
karena Anda akan selalu memilih 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])
)
Tabel kedua terutama lebih besar di sekitar 3,1 miliar baris (mewakili data enam bulan terakhir). Data yang lebih tua dari enam bulan akan dibersihkan; jika tidak secara ketat INSERT
pernyataan data (~ 200 baris / detik, 720.000 baris / jam, 17 juta baris / minggu).
// 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])
)
Harapannya adalah bahwa tabel ini akan berlipat ganda karena jumlah nilai titik data yang dilacak meningkat menjadi 400 baris / detik (sehingga mencapai ~ 10 miliar tidak keluar dari pertanyaan).
Pertanyaannya ( ya, saya bertanya lebih dari satu ... semuanya terkait erat).
Saat ini saya menggunakan database SQL-Server 2008 R2 Standard Edition. Saya mungkin akan menjelaskan tentang peningkatan ke Enterprise Edition jika dapat memperoleh tingkat kinerja yang diinginkan dengan partisi tabel (atau MongoDB jika tidak dapat mencapai tingkat kinerja yang diperlukan dengan SQL-Server). Saya ingin masukan Anda tentang hal berikut:
1) Mengingat bahwa saya perlu menghitung min
, max
dan sum
selama satu jam terakhir (seperti dalam now - 60 minutes
). Apa pendekatan terbaik untuk melacak data terbaru:
Simpan data terbaru dalam memori layanan data. Tuliskan min / maks / rata-rata yang dihitung dengan masing-masing UPDATE data.
Permintaan riwayat terbaru dari tabel riwayat (dampak pertanyaan selanjutnya?) Selama setiap pernyataan UPDATE. Kueri akan mengakses data terbaru untuk nilai titik data dan hanya boleh memindai lebih dari satu juta catatan terakhir?
Simpan riwayat terbaru di baris DataPointValue untuk menghindari pencarian tabel riwayat? Mungkin disimpan sebagai string yang dibatasi dan diproses di dalam proc UPDATE?
Opsi lain yang belum saya pertimbangkan?
2) Untuk DataPointValueHistory
, permintaan terhadap data akan selalu oleh dataPointId
dan satu atau lebih valueId
. Data yang ditanyakan biasanya untuk hari terakhir, minggu atau bulan, tetapi mungkin untuk enam bulan penuh dalam beberapa kasus.
Saat ini saya membuat set data sampel untuk bereksperimen dengan apakah lebih masuk akal untuk mengelompokkan berdasarkan dataPointId / valueId / timeStamp atau timeStamp / dataPointId / valueId. Jika ada yang punya pengalaman berurusan dengan meja sebesar ini dan bersedia menawarkan wawasan mereka, itu akan dihargai. Saya condong ke opsi terakhir untuk menghindari fragmentasi indeks, tetapi kinerja permintaan sangat penting.
Cluster
DataPointValueHistory
berdasarkan dataPointId -> valueId -> timeStampCluster
DataPointValueHistory
berdasarkan timeStamp -> dataPointId -> valueId
3) Akhirnya, seperti yang disebutkan di atas, saya pikir akan masuk akal untuk mempartisi DataPointValueHistory
tabel. Setiap saran tentang cara terbaik mempartisi data histori akan sangat dihargai.
Jika dikelompokkan berdasarkan stempel waktu pertama, saya berpikir bahwa data harus dipartisi berdasarkan minggu (total 27 partisi). Partisi tertua akan dihapus setelah minggu ke 27.
Jika dikelompokkan oleh dataPointId pertama, saya berpikir bahwa data harus dipartisi oleh beberapa modulus id?
Karena saya memiliki pengalaman yang sangat terbatas dengan tabel partisi, keahlian Anda akan dihargai.
sumber
Jawaban:
Saya menemukan analisis ini sangat berguna ketika saya sedang meneliti membangun solusi analitik yang akan memiliki miliaran baris dalam satu tabel.
http://leiliweb.wordpress.com/2012/12/11/partitioned-table-and-index-strategies-using-sql-server-2008/
sumber