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

Pengikut - desain basis data mongodb

Saya setuju dengan gagasan umum dari jawaban lain bahwa ini adalah garis batas masalah relasional.

Kunci model data MongoDB adalah berat penulisan, tetapi itu bisa rumit untuk kasus penggunaan ini, sebagian besar karena pembukuan yang akan diperlukan jika Anda ingin menautkan pengguna ke item secara langsung (perubahan ke grup yang diikuti oleh banyak pengguna akan dikenakan sejumlah besar penulisan, dan Anda memerlukan beberapa pekerja untuk melakukan ini).

Mari kita selidiki apakah model read-heavy tidak dapat diterapkan di sini, atau apakah kita melakukan pengoptimalan prematur.

Pendekatan Baca Berat

Perhatian utama Anda adalah kasus penggunaan berikut:

masalah kinerja sebenarnya bisa jadi ketika saya ingin mendapatkan semua grup yang diikuti pengguna untuk item tertentu [...] karena dengan begitu saya harus menemukan semua grup yang diikuti pengguna, dan dari sana temukan semua item_groups dengan group_id $in dan id item.

Mari kita bedah ini:

  • Dapatkan semua grup yang diikuti pengguna

    Itu pertanyaan sederhana:db.followers.find({userId : userId}) . Kita akan membutuhkan indeks pada userId yang akan membuat runtime operasi ini O(log n), atau sangat cepat bahkan untuk n besar.

  • dari situ temukan semua item_groups dengan group_id $in dan id item

    Sekarang ini bagian yang lebih sulit. Mari kita asumsikan sejenak bahwa tidak mungkin item menjadi bagian dari sejumlah besar grup. Kemudian indeks gabungan { itemId, groupId } akan bekerja paling baik, karena kita dapat mengurangi kandidat yang ditetapkan secara dramatis melalui kriteria pertama - jika item dibagikan hanya dalam 800 grup dan pengguna mengikuti 220 grup, mongodb hanya perlu menemukan persimpangan ini, yang relatif mudah karena keduanya set kecil.

Namun, kita harus lebih dalam dari ini:

Struktur data Anda mungkin jaringan kompleks . Jaringan kompleks datang dalam banyak rasa, tetapi masuk akal untuk menganggap grafik pengikut Anda hampir bebas skala, yang juga merupakan kasus terburuk. Dalam jaringan skala bebas, jumlah node yang sangat kecil (selebriti, super bowl, Wikipedia) menarik banyak 'perhatian' (yaitu memiliki banyak koneksi), sementara jumlah node yang jauh lebih besar mengalami kesulitan mendapatkan jumlah perhatian yang sama gabungan .

Node kecil tidak perlu dikhawatirkan , kueri di atas, termasuk bolak-balik ke database berada dalam rentang 2 md di mesin pengembangan saya pada kumpulan data dengan puluhan juta koneksi dan> 5GB data. Sekarang kumpulan data tidak besar, tetapi apa pun teknologi yang Anda pilih, akan terikat RAM karena indeks harus dalam RAM dalam hal apa pun (lokalitas data dan keterpisahan dalam jaringan umumnya buruk), dan ukuran persimpangan yang disetel adalah kecil menurut definisi. Dengan kata lain:rezim ini didominasi oleh kemacetan perangkat keras.

Bagaimana dengan supernode meskipun?

Karena itu hanya tebakan dan saya sangat tertarik dengan model jaringan, saya mengambil kebebasan untuk menerapkan alat jaringan yang disederhanakan secara dramatis berdasarkan model data Anda untuk melakukan beberapa pengukuran. (Maaf dalam bahasa C#, tetapi menghasilkan jaringan yang terstruktur dengan baik cukup sulit dalam bahasa yang paling saya kuasai...).

Saat menanyakan supernode, saya mendapatkan hasil dalam kisaran puncak 7 md (itu pada 12 juta entri dalam 1,3 GB db, dengan grup terbesar memiliki 133.000 item di dalamnya dan pengguna yang mengikuti 143 grup.)

Asumsi dalam kode ini adalah bahwa jumlah grup yang diikuti oleh pengguna tidak besar, tetapi tampaknya masuk akal di sini. Jika tidak, saya akan menggunakan pendekatan yang banyak menulis.

Jangan ragu untuk bermain dengan kode. Sayangnya, ini akan membutuhkan sedikit pengoptimalan jika Anda ingin mencoba ini dengan lebih dari beberapa GB data, karena itu tidak dioptimalkan dan melakukan beberapa perhitungan yang sangat tidak efisien di sana-sini (terutama pengocokan acak berbobot beta dapat ditingkatkan ).

Dengan kata lain:Saya tidak akan khawatir tentang kinerja pendekatan read-heavy belum . Masalahnya seringkali bukan karena jumlah pengguna yang bertambah, tetapi pengguna yang menggunakan sistem dengan cara yang tidak terduga.

Pendekatan Tulis Berat

Pendekatan alternatif mungkin membalik urutan penautan:

UserItemLinker
{
 userId,
 itemId,
 groupIds[]  // for faster retrieval of the linker. It's unlikely that this grows large
}

Ini mungkin model data yang paling terukur, tetapi saya tidak akan melakukannya kecuali jika kita berbicara tentang sejumlah besar data di mana sharding adalah persyaratan utama. Perbedaan utama di sini adalah bahwa kita sekarang dapat mengelompokkan data secara efisien dengan menggunakan userId sebagai bagian dari kunci shard. Itu membantu memparalelkan kueri, melakukan shard secara efisien, dan meningkatkan lokalitas data dalam skenario multi-pusat data.

Ini dapat diuji dengan versi testbed yang lebih rumit, tetapi saya belum menemukan waktunya, dan sejujurnya, menurut saya ini berlebihan untuk sebagian besar aplikasi.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Bagaimana menemukan nilai min di mongodb

  2. MongoDB $min

  3. MongoDB $asinh

  4. Bagaimana cara mengisi sub-dokumen di luwak setelah membuatnya?

  5. Merujuk skema lain di Mongoose