Latar Belakang
Saya memiliki jaringan sekitar 2000 sensor, yang masing-masing memiliki sekitar 100 titik data yang kami kumpulkan dalam interval 10 menit. Titik data ini biasanya nilai int, tetapi beberapa adalah string dan float. Data ini harus disimpan selama 90 hari, lebih jika memungkinkan dan masih efisien.
Desain Basis Data
Ketika awalnya ditugaskan dengan proyek ini, saya menulis aplikasi C # yang menulis file yang dipisahkan koma untuk setiap sensor. Saat itu jumlahnya tidak banyak, ketika seseorang ingin melihat tren, kami akan membuka csv di Excel dan membuat grafik sesuai kebutuhan.
Banyak hal tumbuh dan kami beralih ke database MySQL. Saya membuat tabel untuk setiap sensor (ya saya tahu, banyak tabel!); telah bekerja dengan baik, tetapi memiliki beberapa keterbatasan. Dengan begitu banyak tabel, jelas tidak mungkin untuk menulis kueri yang akan menemukan data di antara semua sensor ketika mencari nilai tertentu.
Untuk versi berikutnya, saya beralih ke Microsoft SQL Server Express, dan memasukkan semua data sensor ke dalam satu tabel besar. Ini juga berfungsi, dan memungkinkan kami melakukan kueri untuk menemukan nilai di antara semua sensor yang menarik. Namun, saya berlari ke batas 10GB untuk versi Express, dan telah memutuskan untuk beralih kembali ke MySQL daripada berinvestasi di SQL Server Standard.
Pertanyaan
Saya senang dengan kinerja dan skalabilitas MySQL, tetapi saya tidak yakin apakah tetap menggunakan pendekatan all-data-in-one-table yang terbaik. 10GB dalam satu meja sepertinya meminta desain yang berbeda. Saya harus menyebutkan bahwa kebutuhan untuk meminta data untuk grafik masih ada, dan saya khawatir bahwa akan ada masalah kinerja untuk permintaan yang menggambarkan, misalnya, data suhu untuk satu sensor selama 90 hari penuh. (Dengan kata lain grafik harus menjadi sesuatu yang cepat untuk diproduksi, tanpa menunggu SQL untuk memilah-milah tumpukan data hanya untuk mengisolasi sensor yang menarik.)
Haruskah saya membagi tabel ini dalam beberapa cara untuk meningkatkan kinerja? Atau bukan tidak biasa memiliki meja sebesar itu?
Saya memiliki indeks pada ID Sensor dan kolom Timestamp, yang merupakan batas yang menentukan untuk setiap pertanyaan. (yaitu mendapatkan data untuk sensor X dari waktu A ke waktu B).
Saya sudah membaca sedikit tentang sharding dan partisi, tetapi tidak merasa itu sesuai untuk kasus ini.
Edit:
Berdasarkan komentar dan jawaban sejauh ini, beberapa info tambahan mungkin bermanfaat:
Bukan Penyimpanan Tidak Terbatas: Saat ini saya tidak menyimpan data selama 90 hari. Setiap hari, saya menjalankan kueri yang menghapus data yang lebih lama dari 90 hari. Jika itu menjadi penting di masa depan, saya akan menyimpan lebih banyak, tetapi untuk saat ini sudah cukup. Ini membantu menjaga ukuran dalam pemeriksaan dan kinerja tinggi (er).
Tipe Mesin: Implementasi MySQL asli menggunakan MyISAM. Saat membuat tabel saat ini untuk implementasi baru (satu tabel data bukan banyak) mereka sudah default ke InnoDB. Saya tidak percaya saya memiliki persyaratan untuk satu atau yang lain.
Normalisasi: Tentu saja ada tabel lain selain tabel pengumpulan data. Tabel dukungan ini menyimpan hal-hal seperti informasi jaringan untuk sensor, informasi masuk untuk pengguna, dll. Tidak banyak yang bisa dinormalisasi (sejauh yang saya tahu). Alasan tabel data memiliki begitu banyak kolom adalah karena ada banyak variabel dari masing-masing sensor. (Beberapa suhu, tingkat cahaya, tekanan udara, dll.) Normalisasi bagi saya berarti tidak ada data yang berlebihan atau kelompok yang berulang. (Setidaknya untuk 1NF.) Untuk sensor yang diberikan, menyimpan semua nilai pada waktu tertentu memerlukan satu baris data dan tidak ada hubungan 1: N yang terlibat di sana (yang saya lihat).
Saya dapat memecah tabel secara fungsional, membuat (misalnya) semua nilai yang berhubungan dengan suhu dalam satu tabel, dan semua nilai yang berhubungan dengan tekanan udara di meja lainnya. Meskipun ini dapat meningkatkan efisiensi bagi seseorang yang membuat kueri hanya-suhu, saya masih harus memasukkan semua data sekaligus. Namun, peningkatan efisiensi mungkin bermanfaat untuk operasi SELECT. Jelas saya akan lebih baik memecah tabel secara vertikal berdasarkan seberapa sering pengguna meminta data. Mungkin ini yang harus saya lakukan. Saya kira dalam mengajukan pertanyaan, saya mencari konfirmasi bahwa melakukan ini akan bermanfaat.
Edit 2:
Penggunaan Data: Pada akhirnya banyak data yang tidak pernah dilihat atau dibutuhkan, karena kami biasanya hanya berfokus pada item yang bermasalah. Tetapi dalam upaya menemukan masalah, kami menggunakan berbagai alat untuk mencari data dan menentukan item apa yang diperbesar.
Sebagai contoh, kami melihat korelasi antara nilai penggunaan memori (program perangkat lunak berpemilik khusus pelanggan) dan reboot / crash. Salah satu poin data yang saya kumpulkan terkait dengan penggunaan memori ini, dan saya dapat melihat data historis untuk menunjukkan bahwa perangkat menjadi tidak stabil setelah penggunaan memori tertentu terlampaui. Hari ini, untuk subset perangkat yang menjalankan perangkat lunak ini, saya memeriksa nilai ini dan mengeluarkan perintah reboot jika terlalu tinggi. Sampai ini ditemukan, saya tidak berpikir mengumpulkan data ini bernilai.
Untuk alasan ini, saya berpendapat bahwa sekitar 100 titik data dikumpulkan dan disimpan, bahkan jika nilainya dipertanyakan. Tetapi dalam penggunaan normal sehari-hari, pengguna biasanya memeriksa mungkin selusin parameter ini. Jika pengguna tertarik pada area geografis tertentu, ia dapat (menggunakan perangkat lunak) menghasilkan grafik atau spreadsheet data untuk mungkin beberapa lusin sensor. Tidak jarang melihat grafik 30 hari dengan dua atau tiga garis plot yang menunjukkan hal-hal seperti suhu, tekanan udara, dan tingkat cahaya. Melakukan ini akan menjalankan kueri yang mirip dengan ini:
SELECT sensor_id, location, data_timestamp, temp1, air1, light1
FROM data
WHERE data_timestamp >= '2012-02-01'
AND sensor_id IN (1, 2, 3);
(Dalam versi MySQL asli, di mana setiap sensor memiliki tabel sendiri, tiga pertanyaan terpisah akan dikeluarkan, tetapi hasilnya digabungkan dalam perangkat lunak untuk membuat grafik.)
Karena datatabel berisi begitu banyak baris (~ 10 juta), meskipun memiliki indeks iddan data_timestamp, kinerja terutama lebih buruk daripada skenario multi-tabel (4.500 baris dikembalikan dalam 9 detik dibandingkan dengan kurang dari satu detik dengan contoh ini). Kemampuan untuk menemukan sensor mana yang memenuhi kriteria tertentu praktis nol dalam skema multi-tabel, dan dengan demikian alasan untuk pindah ke satu tabel.
Jenis kueri ini dapat dilakukan oleh banyak pengguna secara berurutan karena mereka memilih kelompok data yang berbeda dan membandingkan grafik dari setiap hasil. Sangat frustasi untuk menunggu hampir 10 detik per grafik atau spreadsheet.
Data dibuang setelah 90 hari. Itu bisa diarsipkan tetapi saat ini tidak menjadi persyaratan.
Semoga informasi ini membantu menunjukkan dengan lebih memadai bagaimana data digunakan setelah pengumpulan dan penyimpanan.