Saya baru mengenal MongoDB - berasal dari latar belakang basis data relasional. Saya ingin merancang struktur pertanyaan dengan beberapa komentar, tetapi saya tidak tahu hubungan mana yang digunakan untuk komentar: embed
atau reference
?
Sebuah pertanyaan dengan beberapa komentar, seperti stackoverflow , akan memiliki struktur seperti ini:
Question
title = 'aaa'
content = bbb'
comments = ???
Pada awalnya, saya ingin menggunakan komentar yang diembed (saya pikir embed
direkomendasikan di MongoDB), seperti ini:
Question
title = 'aaa'
content = 'bbb'
comments = [ { content = 'xxx', createdAt = 'yyy'},
{ content = 'xxx', createdAt = 'yyy'},
{ content = 'xxx', createdAt = 'yyy'} ]
Jelas, tetapi saya khawatir tentang kasus ini: Jika saya ingin mengedit komentar yang ditentukan, bagaimana cara saya mendapatkan konten dan pertanyaannya? Tidak ada _id
untuk membiarkan saya menemukan satu, atau question_ref
membiarkan saya menemukan pertanyaannya. (Saya sangat pemula, bahwa saya tidak tahu apakah ada cara untuk melakukan ini tanpa _id
dan question_ref
.)
Apakah saya harus menggunakan ref
bukan embed
? Lalu saya harus membuat koleksi baru untuk komentar?
Jawaban:
Ini lebih merupakan seni daripada sains. The Mongo Dokumentasi Skema adalah referensi yang baik, tapi di sini ada beberapa hal yang perlu dipertimbangkan:
Masukkan sebanyak mungkin
Kegembiraan dari basis data dokumen adalah ia menghilangkan banyak Joins. Insting pertama Anda adalah menempatkan sebanyak mungkin dalam satu dokumen. Karena dokumen MongoDB memiliki struktur, dan karena Anda dapat secara efisien meminta dalam struktur itu (ini berarti Anda dapat mengambil bagian dari dokumen yang Anda butuhkan, sehingga ukuran dokumen tidak perlu terlalu mengkhawatirkan Anda), tidak perlu segera menormalkan data seperti Anda lakukan dalam SQL. Khususnya setiap data yang tidak berguna selain dari dokumen induknya harus menjadi bagian dari dokumen yang sama.
Pisahkan data yang dapat dirujuk dari beberapa tempat ke dalam koleksinya sendiri.
Ini bukan masalah "ruang penyimpanan" karena ini adalah masalah "konsistensi data". Jika banyak catatan akan merujuk ke data yang sama, itu lebih efisien dan lebih sedikit kesalahan untuk memperbarui satu catatan dan menyimpan referensi di tempat lain.
Pertimbangan ukuran dokumen
MongoDB memaksakan batas ukuran 4MB (16MB dengan 1,8) pada satu dokumen. Dalam dunia GB data ini terdengar kecil, tetapi juga 30 ribu tweets atau 250 jawaban Stack Overflow atau 20 foto yang berkedip. Di sisi lain, ini jauh lebih banyak informasi daripada yang mungkin ingin disajikan pada satu waktu di halaman web biasa. Pertama pertimbangkan apa yang akan membuat pertanyaan Anda lebih mudah. Dalam banyak kasus kekhawatiran tentang ukuran dokumen akan menjadi optimasi prematur.
Struktur data yang kompleks:
MongoDB dapat menyimpan struktur data bersarang dalam yang sewenang-wenang, tetapi tidak dapat mencarinya secara efisien. Jika data Anda membentuk pohon, hutan atau grafik, Anda secara efektif perlu menyimpan setiap node dan ujung-ujungnya dalam dokumen terpisah. (Perhatikan bahwa ada penyimpanan data yang dirancang khusus untuk jenis data yang harus dipertimbangkan juga)
Itu juga telah ditunjukkan daripada tidak mungkin untuk mengembalikan subset elemen dalam dokumen. Jika Anda perlu mengambil dan memilih beberapa bit dari setiap dokumen, akan lebih mudah untuk memisahkannya.
Konsistensi Data
MongoDB membuat trade off antara efisiensi dan konsistensi. Aturannya adalah perubahan pada satu dokumen selalu bersifat atomik, sementara pembaruan untuk banyak dokumen tidak boleh dianggap sebagai atom. Juga tidak ada cara untuk "mengunci" catatan di server (Anda dapat membangun ini ke dalam logika klien menggunakan misalnya bidang "kunci"). Saat Anda merancang skema Anda, pertimbangkan bagaimana Anda akan menjaga data Anda konsisten. Secara umum, semakin banyak yang Anda simpan dalam dokumen, semakin baik.
Untuk apa yang Anda gambarkan, saya akan menyematkan komentar, dan memberikan setiap kolom komentar id dengan ObjectID. ObjectID memiliki cap waktu yang tertanam di dalamnya sehingga Anda dapat menggunakannya alih-alih dibuat kapan saja.
sumber
Secara umum, embed baik jika Anda memiliki hubungan satu-ke-satu atau satu-ke-banyak, dan referensi baik jika Anda memiliki banyak-ke-banyak hubungan.
sumber
Anda dapat meminta berdasarkan sub-dokumen:
db.question.find({'comments.content' : 'xxx'})
.Ini akan mengembalikan seluruh dokumen Pertanyaan. Untuk mengedit komentar yang ditentukan, Anda kemudian harus menemukan komentar pada klien, melakukan edit dan menyimpannya kembali ke DB.
Secara umum, jika dokumen Anda berisi array objek, Anda akan menemukan bahwa sub-objek tersebut perlu dimodifikasi sisi klien.
sumber
Yah, saya agak terlambat tetapi masih ingin berbagi cara pembuatan skema saya.
Saya memiliki skema untuk semua yang dapat dijelaskan dengan sebuah kata, seperti yang Anda lakukan di OOP klasik.
MISALNYA
Setiap skema dapat disimpan sebagai Dokumen atau Subdokumen, jadi saya menyatakan ini untuk setiap skema.
Dokumen:
Dokumen:
sumber
Saya menemukan presentasi kecil ini sambil meneliti pertanyaan ini sendiri. Saya terkejut melihat betapa baiknya itu ditata, baik info dan presentasi itu.
http://openmymind.net/Multiple-Collections-Versus-Embedded-Documents
Itu dirangkum:
sumber
a lot
? 3? 10? 100? Apalarge
? 1 KB? 1MB? 3 bidang? 20 bidang? Apasmaller
/fewer
?Saya tahu ini cukup lama tetapi jika Anda mencari jawaban untuk pertanyaan OP tentang cara mengembalikan hanya komentar yang ditentukan, Anda dapat menggunakan operator $ (permintaan) seperti ini:
sumber
Ya, kita dapat menggunakan referensi dalam dokumen. Untuk mengisi dokumen lain seperti sql saya bergabung. Dalam mongo db mereka tidak harus bergabung untuk memetakan satu ke banyak dokumen hubungan. Sebaliknya, kita dapat menggunakan populate untuk memenuhi skenario kita ..
Populasi adalah proses untuk secara otomatis mengganti jalur yang ditentukan dalam dokumen dengan dokumen dari koleksi lain. Kami dapat mengisi satu dokumen, beberapa dokumen, objek polos, beberapa objek polos, atau semua objek yang dikembalikan dari kueri. Mari kita lihat beberapa contoh.
Lebih baik Anda bisa mendapatkan informasi lebih lanjut silakan kunjungi: http://mongoosejs.com/docs/populate.html
sumber
Sebenarnya, saya cukup ingin tahu mengapa tidak ada yang berbicara tentang spesifikasi UML. Aturan praktisnya adalah bahwa jika Anda memiliki agregasi, maka Anda harus menggunakan referensi. Tetapi jika itu adalah komposisi, maka kopling lebih kuat, dan Anda harus menggunakan dokumen yang disematkan.
Dan Anda akan segera mengerti mengapa itu logis. Jika suatu objek dapat ada secara independen dari induknya, maka Anda akan ingin mengaksesnya meskipun induknya tidak ada. Karena Anda tidak dapat menanamkannya di induk yang tidak ada, Anda harus membuatnya langsung dalam struktur data itu sendiri. Dan jika orangtua ada, cukup tautkan bersama-sama dengan menambahkan referensi objek pada induk.
Tidak benar-benar tahu apa perbedaan antara kedua hubungan itu? Berikut ini tautan yang menjelaskannya: Agregasi vs Komposisi dalam UML
sumber
Saya membuat quizz ini sebagai referensi untuk mengetahui apakah Anda harus menggunakan satu atau yang lain
http://indie-rok.github.io/embedded-vs-reference-mongo-db
sumber
Jika Anda melacak jumlah komentar dan indeks komentar yang ingin Anda ubah, Anda dapat menggunakan operator titik ( contoh SO ).
Anda bisa melakukan f.ex.
(sebagai cara lain untuk mengedit komentar di dalam pertanyaan)
sumber