Ketika MongoDB diperkenalkan, fitur utama yang disorot adalah kemampuannya untuk menjadi "tanpa skema". Apa artinya? Artinya, seseorang dapat menyimpan dokumen JSON, masing-masing dengan struktur yang berbeda, dalam koleksi yang sama. Ini cukup keren. Tetapi masalahnya dimulai ketika Anda perlu mengambil dokumen. Bagaimana Anda mengetahui bahwa dokumen yang diambil memiliki struktur tertentu, atau apakah berisi bidang tertentu atau tidak? Anda harus mengulang semua dokumen dan mencari bidang tertentu itu. Inilah mengapa sangat berguna untuk merencanakan skema MongoDB dengan hati-hati, terutama untuk aplikasi besar.
Ketika datang ke MongoDB, tidak ada cara khusus untuk mendesain skema. Itu semua tergantung pada aplikasi Anda dan bagaimana aplikasi Anda akan menggunakan data. Namun, ada beberapa praktik umum yang dapat Anda ikuti saat mendesain skema database Anda. Di sini, saya akan membahas praktik ini dan pro dan kontranya.
Pemodelan Satu-ke-Beberapa (Penyematan)
Desain ini adalah contoh yang sangat baik untuk menyematkan dokumen. Pertimbangkan contoh kumpulan Person ini untuk mengilustrasikan pemodelan ini.
{
name: "Amy Cooper",
hometown: "Seoul",
addresses: [
{ city: 'New York', state: 'NY', cc: 'USA' },
{ city: 'Jersey City', state: 'NJ', cc: 'USA' }
]
}
Kelebihan:
- Anda bisa mendapatkan semua informasi dalam satu kueri.
Kekurangan:
- Data yang disematkan sepenuhnya bergantung pada dokumen induk. Anda tidak dapat mencari data yang disematkan secara mandiri.
- Pertimbangkan contoh di mana Anda membuat sistem pelacakan tugas menggunakan pendekatan ini. Kemudian Anda akan menyematkan semua tugas khusus untuk satu orang dalam koleksi Person. Jika Anda ingin menjalankan kueri seperti:Tunjukkan semua tugas yang memiliki batas waktu besok. Ini bisa sangat sulit, meskipun ini adalah kueri yang sederhana. Dalam hal ini, Anda harus mempertimbangkan pendekatan lain.
Pemodelan Satu-ke-Banyak (Referensi)
Dalam pemodelan jenis ini, dokumen induk akan menyimpan Id referensi (ObjectID) dari dokumen anak. Anda perlu menggunakan gabungan tingkat aplikasi (menggabungkan dua dokumen setelah mengambilnya dari DB di tingkat aplikasi) untuk mengambil dokumen, jadi tidak ada gabungan tingkat basis data. Oleh karena itu, beban pada database akan berkurang. Perhatikan contoh ini:
// Parts collection
{
_id: ObjectID(1234),
partno: '1',
name: ‘Intel 100 Ghz CPU',
qty: 100,
cost: 1000,
price: 1050
}
// Products collection
{
name: 'Computer WQ-1020',
manufacturer: 'ABC Company',
catalog_number: 1234,
parts: [
ObjectID(‘1234’), <- Ref. for Part No: 1
ObjectID('2345'),
ObjectID('3456')
]
}
Misalkan setiap produk mungkin memiliki beberapa ribu bagian yang terkait dengannya. Untuk jenis database ini, referensi adalah tipe pemodelan yang ideal. Anda meletakkan id referensi dari semua bagian terkait di bawah dokumen produk. Kemudian Anda dapat menggunakan gabungan level aplikasi untuk mendapatkan suku cadang untuk produk tertentu.
Kelebihan:
- Dalam jenis pemodelan ini, setiap bagian adalah dokumen terpisah sehingga Anda dapat menerapkan semua kueri terkait bagian pada dokumen ini. Tidak perlu bergantung pada dokumen induk.
- Sangat mudah untuk melakukan operasi CRUD (Buat, Baca, Perbarui, Tulis) pada setiap dokumen secara mandiri.
Kekurangan:
- Satu kelemahan utama dengan metode ini adalah Anda harus melakukan satu kueri tambahan untuk mendapatkan detail bagian. Sehingga Anda dapat melakukan penggabungan tingkat aplikasi dengan dokumen produk untuk mendapatkan kumpulan hasil yang diperlukan. Sehingga dapat menyebabkan penurunan kinerja DB.
Pemodelan Satu-ke-Jutaan (Referensi Induk)
Saat Anda perlu menyimpan banyak data di setiap dokumen, Anda tidak dapat menggunakan salah satu pendekatan di atas karena MongoDB memiliki batasan ukuran 16MB per dokumen. Contoh sempurna dari skenario semacam ini dapat berupa sistem pencatatan peristiwa yang mengumpulkan log dari berbagai jenis mesin dan menyimpannya dalam koleksi Log dan Mesin.
Di sini, Anda bahkan tidak dapat berpikir untuk menggunakan pendekatan Embedding yang menyimpan semua informasi log untuk mesin tertentu dalam satu dokumen. Ini karena hanya dalam beberapa jam, ukuran dokumen akan lebih dari 16 MB. Meskipun Anda hanya menyimpan id referensi dari semua dokumen log, Anda masih akan menghabiskan batas 16 MB karena beberapa mesin dapat menghasilkan jutaan pesan log dalam satu hari.
Jadi dalam hal ini, kita bisa menggunakan pendekatan parent reference. Dalam pendekatan ini, alih-alih menyimpan id referensi dokumen anak di dokumen induk, kami akan menyimpan id referensi dokumen induk di semua dokumen anak. Jadi untuk contoh kita, kita akan menyimpan ObjectID mesin dalam dokumen Log. Perhatikan contoh ini:
// Machines collection
{
_id : ObjectID('AAA'),
name : 'mydb.example.com',
ipaddr : '127.66.0.4'
}
// Logs collection
{
time : ISODate("2015-09-02T09:10:09.032Z"),
message : 'WARNING: CPU usage is critical!',
host: ObjectID('AAA') -> references Machine document
}
Misalkan Anda ingin menemukan 3000 log terbaru dari Mesin 127.66.0.4:
machine = db.machines.findOne({ipaddr : '127.66.0.4'});
msgs = db.logmsg.find({machine: machine._id}).sort({time : -1}).limit(3000).toArray()
Referensi Dua Arah
Dalam pendekatan ini, kami menyimpan referensi di kedua sisi yang berarti, referensi orang tua akan disimpan di dokumen anak dan referensi anak akan disimpan di dokumen induk. Ini membuat pencarian relatif mudah dalam pemodelan satu ke banyak. Misalnya, kita dapat mencari di dokumen induk dan tugas. Di sisi lain, pendekatan ini memerlukan dua kueri terpisah untuk memperbarui satu dokumen.
// person
{
_id: ObjectID("AAAA"),
name: "Bear",
tasks [
ObjectID("AAAD"),
ObjectID("ABCD"), -> Reference of child document
ObjectID("AAAB")
]
}
// tasks
{
_id: ObjectID("ABCD"),
description: "Read a Novel",
due_date: ISODate("2015-11-01"),
owner: ObjectID("AAAA") -> Reference of parent document
}
Kesimpulan
Pada akhirnya, itu semua tergantung pada persyaratan aplikasi Anda. Anda dapat mendesain skema MongoDB dengan cara yang paling bermanfaat untuk aplikasi Anda dan memberi Anda kinerja tinggi. Berikut adalah beberapa ringkasan pertimbangan yang dapat Anda pertimbangkan saat merancang skema Anda.
- Desain skema berdasarkan pola akses data aplikasi Anda.
- Tidak perlu menyematkan dokumen setiap saat. Gabungkan dokumen hanya jika Anda akan menggunakannya bersama.
- Pertimbangkan duplikasi data karena penyimpanan lebih murah daripada daya komputasi saat ini.
- Optimalkan skema untuk kasus penggunaan yang lebih sering.
- Array tidak boleh tumbuh di luar batas. Jika ada lebih dari beberapa ratus dokumen turunan, jangan sematkan.
- Lebih memilih gabungan tingkat aplikasi daripada gabungan tingkat basis data. Dengan pengindeksan yang tepat dan penggunaan bidang proyeksi yang tepat, Anda dapat menghemat banyak waktu.