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 data
tabel berisi begitu banyak baris (~ 10 juta), meskipun memiliki indeks id
dan 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.
sumber
Jawaban:
Anda harus berpikir tentang mempartisi tabel karena alasan besar.
Semua indeks yang Anda miliki di atas meja raksasa, bahkan hanya satu indeks, dapat menghasilkan banyak beban CPU dan I / O disk hanya untuk melakukan pemeliharaan indeks saat menjalankan INSERT, UPDATE, dan HAPUS.
Saya menulis posting sebelumnya pada 7 Oktober 2011 tentang mengapa Pemisahan Tabel akan sangat membantu. Ini satu kutipan dari postingan saya yang lalu:
Anda dapat membaca seluruh posting saya nanti tentang ini.
Untuk memotong langsung ke pengejaran, Anda perlu meneliti dan mencari tahu data apa yang jarang digunakan dalam tabel 10GB Anda. Data itu harus ditempatkan dalam tabel arsip yang mudah diakses jika Anda membutuhkan pertanyaan adhoc untuk sifat historis. Memigrasi arsip itu dari 10GB, diikuti oleh
OPTIMIZE TABLE
pada tabel 10GB, dapat menghasilkan Set Kerja yang lebih cepat untuk menjalankan SELECT, INSERT, UPDATE, dan HAPUS. Bahkan DDL akan berjalan lebih cepat pada Perangkat Kerja 2GB daripada tabel 10GB.UPDATE 2012-02-24 16:19 EDT
Dua hal yang perlu dipertimbangkan
Berikut adalah dua posting yang saya buat tentang cara menggunakannya:
Ini adalah postingan tambahan yang saya buat di atas meja dengan banyak kolom
Terlalu banyak kolom di MySQL
sumber
Menarik ... Jika semua sensor menghasilkan jenis data yang sama, masuk akal untuk menempatkan semuanya di tabel yang sama, tetapi dengan jumlah data itu, saya dapat melihat mengapa Anda khawatir tentang kinerja.
Apakah 90 hari jumlah waktu yang biasa Anda menghasilkan grafik? Jika demikian, Anda dapat memiliki dua tabel: tabel data sensor utama yang menyimpan data dari 90 (atau sedikit lebih jika Anda menginginkan beberapa kelonggaran) hari yang lalu hingga hari ini, dan semua yang lebih tua dari yang ada dalam tabel arsip. Itu bisa membantu mengurangi ukuran tabel dari mana laporan mulai dihasilkan, dan mudah-mudahan sebagian besar data 10 GB Anda akan ada di tabel arsip, dan bukan di tabel utama. Pekerjaan pengarsipan dapat dijadwalkan untuk berjalan setiap malam.
Mungkin juga mempertimbangkan membangun database pelaporan terpisah yang menyimpan data dalam struktur yang lebih baik untuk menghasilkan laporan dari (tabel yang dirancang untuk lebih mencocokkan dengan apa yang Anda query, dan mungkin pra-kalkulasi dan nilai agregat yang seharusnya memerlukan waktu lama untuk menghasilkan, jika mungkin), dan mengisi kembali dari basis data utama secara teratur (seperti setiap malam). Tentu saja, jika Anda membutuhkan laporan yang dihasilkan dari data terbaru, ini mungkin tidak berfungsi dengan baik.
sumber