MongoDB
 sql >> Teknologi Basis Data >  >> NoSQL >> MongoDB

MongoDB (noSQL) kapan harus membagi koleksi

Seperti yang sudah ditulis, tidak ada aturan seperti bentuk normal kedua untuk SQL.

Namun, ada beberapa praktik terbaik dan jebakan umum terkait pengoptimalan untuk MongoDB yang akan saya sebutkan di sini.

Penggunaan penyematan yang berlebihan

Batas BSON

Berlawanan dengan kepercayaan populer, tidak ada yang salah dengan referensi. Asumsikan Anda memiliki perpustakaan buku, dan Anda ingin melacak persewaan. Anda bisa mulai dengan model seperti ini

{
  // We use ISBN for its uniqueness 
  _id: "9783453031456"
  title: "Schismatrix",
  author: "Bruce Sterling",
  rentals: [
    {
      name:"Markus Mahlberg,
      start:"2015-05-05T03:22:00Z",
      due:"2015-05-12T12:00:00Z"
    }
  ]
}

Meskipun ada beberapa masalah dengan model ini, yang paling penting tidak jelas – akan ada jumlah persewaan yang terbatas karena fakta bahwa dokumen BSON memiliki batas ukuran 16MB.

Masalah migrasi dokumen

Masalah lain dengan menyimpan persewaan dalam array adalah bahwa ini akan menyebabkan migrasi dokumen yang relatif sering, yang merupakan operasi yang agak mahal. Dokumen BSON tidak pernah dipartisi dan dibuat dengan beberapa ruang tambahan yang dialokasikan terlebih dahulu yang digunakan saat mereka berkembang. Ruang tambahan ini disebut padding. Ketika padding terlampaui, dokumen dipindahkan ke lokasi lain di datafiles dan ruang padding baru dialokasikan. Penambahan data yang sering menyebabkan seringnya migrasi dokumen. Oleh karena itu, praktik terbaik adalah mencegah pembaruan yang sering meningkatkan ukuran dokumen dan menggunakan referensi sebagai gantinya.

Jadi sebagai contoh, kami akan mengubah model tunggal kami dan membuat yang kedua. Pertama, model buku

{
  _id: "9783453031456",
  title:"Schismatrix",
  author: "Bruce Sterling"
}

Model kedua untuk persewaan akan terlihat seperti ini

{
  _id: new ObjectId(),
  book: "9783453031456",
  rentee: "Markus Mahlberg",
  start: ISODate("2015-05-05T03:22:00Z"),
  due: ISODate("2015-05-05T12:00:00Z"),
  returned: ISODate("2015-05-05T11:59:59.999Z")
}

Pendekatan yang sama tentu saja dapat digunakan untuk penulis atau penerima sewa.

Masalah dengan normalisasi berlebihan

Mari kita melihat kembali beberapa waktu. Seorang pengembang akan mengidentifikasi entitas yang terlibat dalam kasus bisnis, menentukan properti dan hubungan mereka, menulis kelas entitas yang sesuai, membenturkan kepalanya ke dinding selama beberapa jam untuk mendapatkan kerja triple inner-outer-atas-and-beyond JOIN yang diperlukan untuk kasus penggunaan dan semua hidup bahagia selamanya. Jadi mengapa menggunakan NoSQL secara umum dan MongoDB secara khusus? Karena tidak ada yang hidup bahagia selamanya. Pendekatan ini menskalakan secara mengerikan dan hampir secara eksklusif satu-satunya cara untuk menskalakan adalah vertikal.

Namun perbedaan utama dari NoSQL adalah Anda memodelkan data Anda sesuai dengan pertanyaan yang perlu Anda jawab.

Karena itu, mari kita lihat relasi n:m yang khas dan ambil relasi dari penulis ke buku sebagai contoh kita. Dalam SQL, Anda akan memiliki 3 tabel:dua untuk entitas Anda (buku dan penulis ) dan satu untuk relasi (Siapa penulis buku yang mana? ). Tentu saja, Anda dapat mengambil tabel tersebut dan membuat koleksi yang setara. Namun, karena tidak ada JOIN di MongoDB, Anda memerlukan tiga kueri (satu untuk entitas pertama, satu untuk relasinya, dan satu untuk entitas terkait) untuk menemukan dokumen terkait entitas. Ini tidak masuk akal, karena pendekatan tiga tabel untuk relasi n:m secara khusus diciptakan untuk mengatasi skema ketat yang diberlakukan database SQL. Karena MongoDB memiliki skema yang fleksibel, pertanyaan pertama adalah di mana menyimpan relasi, menjaga masalahnya timbul dari penggunaan yang berlebihan dari embedding dalam pikiran. Karena seorang penulis mungkin menulis beberapa buku di tahun-tahun mendatang, tetapi kepengarangan buku jarang, jika sama sekali, berubah, jawabannya sederhana:Kami menyimpan penulis sebagai referensi penulis dalam data buku

{
  _id: "9783453526723",
  title: "The Difference Engine",
  authors: ["idOfBruceSterling","idOfWilliamGibson"]
}

Dan sekarang kita dapat menemukan penulis buku itu dengan melakukan dua pertanyaan:

var book = db.books.findOne({title:"The Difference Engine"})
var authors = db.authors.find({_id: {$in: book.authors})

Saya harap hal di atas membantu Anda memutuskan kapan harus benar-benar "membagi" koleksi Anda dan mengatasi masalah yang paling umum.

Kesimpulan

Untuk pertanyaan Anda, inilah jawaban saya

  1. Seperti yang tertulis sebelumnya:Tidak , tetapi mengingat batasan teknis akan memberi Anda gambaran jika hal itu masuk akal.
  2. Tidak buruk – asalkan sesuai dengan kasus penggunaan Anda . Jika Anda memiliki kategori tertentu dan _id-nya , mudah untuk menemukan produk terkait. Saat memuat produk, Anda dapat dengan mudah mendapatkan kategori miliknya, meskipun demikian secara efisien, sebagai _id diindeks secara default.
  3. Saya belum menemukan kasus penggunaan yang tidak dapat dilakukan dengan MongoDB, meskipun beberapa hal bisa menjadi sedikit lebih rumit dengan MongoDB. Apa yang harus Anda lakukan adalah menjumlahkan kebutuhan fungsional dan non-fungsional Anda dan memeriksa apakah keuntungannya lebih besar daripada kerugiannya. Aturan praktis saya:jika salah satu "skalabilitas" atau "ketersediaan tinggi/kegagalan otomatis" ada dalam daftar persyaratan Anda, MongoDB lebih berharga daripada sekadar tampilan.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDB - $addToSet pada daftar Dokumen Tertanam

  2. Gabungkan beberapa grup dalam agregasi di mongodb

  3. Mongodb tidak update saat saya menggunakan seperti ini

  4. Mongodb - apakah masalah keandalan masih signifikan?

  5. Rentang dukungan dari waktu ke waktu analitik yang disusun