Menggunakan MongoDB dan PostgreSQL bersama-sama


25

Proyek saya saat ini pada dasarnya adalah menjalankan sistem manajemen dokumen pabrik.

Konon, ada beberapa kerutan (surprise, surprise). Sementara beberapa kerutan cukup spesifik untuk proyek ini, saya percaya ada beberapa pengamatan umum dan pertanyaan yang muncul yang tidak memiliki jawaban kanonik (yang bisa saya temukan), dan yang berlaku untuk domain masalah yang lebih luas . Ada banyak hal di sini dan saya tidak yakin itu cocok untuk format Tanya Jawab StackExchange, tetapi saya pikir itu a) pertanyaan yang dapat dijawab dan b) tidak spesifik sehingga dapat bermanfaat bagi masyarakat. Beberapa pertimbangan saya khusus untuk saya, tetapi saya pikir pertanyaan itu bisa berguna bagi siapa saja yang dihadapkan dengan memutuskan SQL vs NoSQL vs keduanya.

Latar belakang:

Aplikasi web yang kami bangun berisi data yang jelas bersifat relasional dan juga data yang berorientasi dokumen. Kami ingin memiliki kue kami dan memakannya juga.

TL; DR: Saya pikir # 5 di bawah ini lulus uji bau. Apakah kamu? Adakah yang punya pengalaman dengan integrasi SQL dan NOSQL dalam satu aplikasi? Saya mencoba membuat daftar semua pendekatan yang mungkin untuk kelas masalah ini di bawah. Apakah saya melewatkan alternatif yang menjanjikan?

Kompleksitas:

  • Ada banyak kelas dokumen yang berbeda. Persyaratan sudah meminta puluhan dokumen yang berbeda. Jumlah ini hanya akan naik. Kasus terbaik yang mungkin terjadi adalah di mana kita dapat memanfaatkan bahasa spesifik domain sederhana, pembuatan kode, dan skema yang fleksibel sehingga pakar domain dapat menangani penambahan kelas dokumen baru tanpa intervensi dari DBA atau programmer. (Catatan: sudah sadar kita hidup di luar Aturan Kesepuluh Greenspun )
  • Integritas penulisan sukses sebelumnya adalah persyaratan utama proyek. Data akan menjadi bisnis yang kritis. Semantik penuh ACID tentang menulis dapat dikorbankan asalkan hal-hal yang berhasil ditulis tetap berhasil.
  • Dokumen-dokumen itu sendiri kompleks. Dokumen prototipe dalam kasus khusus kami akan membutuhkan penyimpanan 150+ bagian data yang berbeda per instance dokumen. Kasus patologis bisa menjadi urutan besarnya lebih buruk, tetapi jelas bukan dua.
  • Satu kelas dokumen adalah target bergerak subjek untuk pembaruan pada suatu titik waktu.
  • Kami menyukai barang gratis yang kami dapatkan dari Django ketika kami mengaitkannya ke database relasional. Kami ingin menyimpan barang gratis tanpa harus melompat mundur dua versi Django untuk menggunakan garpu Django-nonrel. Dumping ORM sepenuhnya lebih baik daripada menurunkan ke 1.3.

Pada dasarnya, ini adalah campuran data relasional (hal-hal aplikasi web khas Anda seperti pengguna, grup, dll., Serta dokumen metadata yang kami perlukan untuk dapat mengiris dan memotong dengan pertanyaan kompleks secara realtime) dan mendokumentasikan data (mis. ratusan bidang yang kami tidak tertarik untuk bergabung atau bertanya dengan - satu-satunya kasus penggunaan kami untuk data akan untuk menunjukkan dokumen tunggal ke mana ia dimasukkan).

Saya ingin melakukan pemeriksaan kewarasan (jika Anda memeriksa riwayat posting saya, saya cukup eksplisit tentang fakta bahwa saya bukan DBA) pada metode pilihan saya serta menghitung semua opsi yang saya temui untuk penyelesaian orang lain. masalah serupa secara luas yang melibatkan data relasional dan non-relasional.

Solusi yang Diusulkan:

1. Satu tabel per kelas dokumen

Setiap kelas dokumen mendapatkan tabelnya sendiri, dengan kolom untuk semua metadata dan data.

Keuntungan:

  • Model data SQL standar sedang dimainkan.
  • Data relasional ditangani dengan cara terbaik. Kami akan mendenormalisasi nanti jika perlu.
  • Antarmuka bawaan Django admin nyaman dengan mengintrospeksi tabel-tabel ini dan ORM dapat hidup bahagia dengan 100% data di luar kotak.

Kekurangan:

  • Mimpi buruk pemeliharaan. Lusinan (ratusan?) Tabel dengan (puluhan?) Ribuan kolom.
  • Logika tingkat aplikasi bertanggung jawab untuk memutuskan dengan tepat ke tabel mana harus ditulis. Menjadikan nama tabel sebagai parameter untuk kueri berbau.
  • Pada dasarnya semua perubahan logika bisnis akan membutuhkan perubahan skema.
  • Kasus patologis mungkin memerlukan striping data untuk formulir tunggal di beberapa tabel (lihat: Berapa jumlah maksimum kolom dalam tabel PostgreSQL? ).
  • Kita mungkin perlu mencari DBA yang nyata, jujur ​​kepada Tuhan yang pasti akan membenci hidup kita.

2. pemodelan EAV

Hanya ada tabel bidang. Pemodelan Entity-Attribute-Value sudah dipahami dengan baik. Saya sudah memasukkannya untuk kelengkapan. Saya tidak berpikir ada proyek baru yang dimulai pada 2013 akan pergi dengan pendekatan EAV sengaja.

Keuntungan:

  • Mudah dimodelkan.

Kekurangan:

  • Lebih sulit untuk dicari.
  • Lapisan DB tidak lagi memiliki representasi lurus ke depan untuk apa yang merupakan satu objek tingkat aplikasi.
  • Kami akan kehilangan pemeriksaan kendala tingkat DB.
  • Jumlah baris di satu meja akan tumbuh 100-1000 kali lebih cepat. Kemungkinan titik sakit di masa depan, kinerja-bijaksana.
  • Pengindeksan terbatas mungkin.
  • Skema DB tidak masuk akal sejauh menyangkut ORM. Baterai termasuk hal-hal aplikasi web dipertahankan tetapi model data khusus akan membutuhkan permintaan khusus.

3. Gunakan bidang PostgreSQL hstore atau json

Salah satu dari jenis bidang ini akan melakukan trik untuk menyimpan data schemaless dalam konteks DB relasional. Satu-satunya alasan saya tidak langsung beralih ke solusi ini adalah itu relatif baru (diperkenalkan pada versi 8.4 jadi bukan yang baru), saya memiliki nol paparan sebelumnya untuk itu dan saya curiga. Menurut saya itu salah karena alasan yang persis sama. Saya merasa tidak nyaman dengan memasukkan semua data saya yang bagus dan mudah dinormalisasi ke dalam bahasa Mongo - walaupun Mongo dapat menangani referensi antar dokumen.

Keuntungan:

  • Kami mendapatkan manfaat dari Django ORM dan manajemen sesi dan autor bawaan.
  • Semuanya tetap dalam satu backend yang sebelumnya kita gunakan pada proyek lain berhasil.

Kekurangan:

  • Tidak ada pengalaman dengan ini, secara pribadi.
  • Itu tidak terlihat seperti fitur yang sangat digunakan. Sepertinya mereka direkomendasikan sedikit kepada orang-orang yang mencari solusi NOSQL tapi saya tidak melihat banyak bukti bahwa mereka sedang dipilih. Ini membuat saya berpikir saya pasti kehilangan sesuatu.
  • Semua nilai yang disimpan adalah string. Kehilangan pemeriksaan kendala tingkat DB.
  • Data di hstore tidak akan pernah ditampilkan kepada pengguna kecuali mereka secara khusus melihat dokumen, tetapi metadata yang disimpan dalam kolom yang lebih standar adalah. Kami akan mengalahkan metadata itu dan saya khawatir hstores yang agak besar yang akan kami buat mungkin akan datang dengan kelemahan kinerja.

4. Pergi penuh berorientasi dokumen

Buat semua dokumen hal-hal (dalam pengertian MongoDB). Buat satu koleksi jenis Documentdan panggil satu hari. Bawa semua data periferal (termasuk data pada akun pengguna, grup, dll) ke dalam mongo juga. Solusi ini jelas lebih baik daripada pemodelan EAV tetapi rasanya salah bagi saya karena alasan yang sama # 3 merasa salah - mereka berdua merasa seperti menggunakan palu sebagai obeng juga.

Keuntungan:

  • Tidak perlu memodelkan data di muka. Memiliki satu koleksi dengan dokumen jenis Documentdan menyebutnya sehari.
  • Dikenal karakteristik penskalaan yang baik, koleksi harus tumbuh untuk mencakup jutaan atau bahkan milyaran dokumen.
  • Format JSON (BSON) intuitif untuk pengembang.
  • Seperti yang saya pahami (yang hanya samar-samar pada saat ini), dengan menjadi paranoid berkenaan dengan tingkat kepedulian menulis, bahkan sebuah instance dapat memberikan keamanan data yang cukup kuat jika terjadi apa saja dan semuanya hingga crash hard drive.

Kekurangan:

  • ORM berada di luar jendela untuk bagasi Django. Gratis yang pergi keluar jendela dengan itu: kerangka kerja auth, kerangka sesi, antarmuka admin, pasti banyak hal lainnya.
  • Harus menggunakan kemampuan referensi mongo (yang membutuhkan beberapa kueri) atau mendenormalkan data. Kami tidak hanya kehilangan gratis yang kami dapatkan dari Django, kami juga kehilangan gratis seperti BERGABUNG yang kami terima begitu saja di PostgreSQL.
  • Keamanan data. Ketika seseorang membaca tentang MongoDB, sepertinya selalu ada setidaknya satu orang yang merujuk pada bagaimana hal itu akan dan kehilangan data Anda. Mereka tidak pernah mengutip kejadian tertentu dan itu semua mungkin hanya omong kosong atau hanya terkait dengan api default lama dan lupa menulis-keprihatinan tetapi masih membuat saya khawatir. Kami tentu saja akan menggunakan strategi cadangan yang cukup paranoid dalam hal apapun (jika data rusak secara diam-diam itu bisa jadi tidak penting tentu saja ..).

5. PostgreSQL dan MongoDB

Data relasional masuk dalam database relasional dan data dokumen masuk ke database berorientasi dokumen. The documentstabel pada database relasional berisi semua data yang kita mungkin perlu indeks atau slice dan dadu pada serta MongoDB ObjectId yang kita akan gunakan ketika kita perlu permintaan untuk nilai yang sebenarnya dari kolom di dokumen. Kami tidak akan dapat menggunakan ORM atau admin internal untuk nilai-nilai dokumen itu sendiri, tetapi itu bukan kerugian besar karena seluruh aplikasi pada dasarnya adalah antarmuka admin untuk dokumen dan kami mungkin harus sesuaikan bagian tertentu dari ORM ke tingkat yang tidak dapat diterima untuk membuatnya berfungsi seperti yang kita butuhkan.

Keuntungan:

  • Setiap backend hanya melakukan apa yang baik.
  • Referensi antara model dipertahankan tanpa memerlukan beberapa pertanyaan.
  • Kami bisa menjaga baterai yang diberikan Django kepada kami sejauh menyangkut pengguna, sesi, dll.
  • Hanya perlu satu documentstabel tidak peduli berapa banyak kelas dokumen yang berbeda dibuat.
  • Data dokumen yang lebih jarang ditanyakan sangat dipisahkan dari metadata yang jauh lebih sering ditanyakan.

Kekurangan:

  • Mengambil data dokumen akan membutuhkan 2 kueri berurutan, pertama melawan SQL DB dan kemudian melawan MongoDB (meskipun ini tidak lebih buruk daripada jika data yang sama telah disimpan dalam bahasa Mongo dan tidak didenormalkan)
  • Menulis tidak lagi menjadi atom. Tulisan terhadap satu dokumen Mongo dijamin atomik dan PG jelas dapat membuat jaminan atomisitas tetapi memastikan atomisitas penulisan di keduanya akan membutuhkan logika aplikasi, tidak diragukan lagi dengan penalti kinerja dan kompleksitas.
  • Dua backends = dua bahasa permintaan = dua program yang berbeda dengan persyaratan admin yang berbeda = dua database berlomba-lomba mencari memori.

Saya akan pergi untuk kolom dengan JSONtipe data. Jangan takut menggunakan fitur baru di Postgres - tim Postgres tidak merilis fitur yang tidak stabil. Dan 9,2 bukankah itu benar-benar baru). Plus, Anda dapat menggunakan fitur JSON baru di 9.3 begitu ada. Jika Anda selalu sepenuhnya memproses dokumen dalam kode aplikasi Anda (daripada menggunakan SQL), Anda juga bisa menyimpan JSON dalam textkolom biasa .
a_horse_with_no_name

Kepada para penjawab potensial: jangan ragu untuk memberikan jawaban! Namun, karena pertanyaan ini bertahan cukup lama tanpa jawaban "sempurna", saya bermaksud menjawab pertanyaan dengan postmortem lengkap pengalaman setelah kami menerapkan dan beralih ke produksi. Mungkin satu tahun di masa depan, tapi jangan khawatir - OP akan memberikan. Saya berharap itulah yang paling bermanfaat bagi mereka yang mendukung / meningkatkan pertanyaan tertentu: verifikasi bahwa itu berhasil atau penjelasan tentang hambatan apa yang menewaskan opsi berdampingan.
chucksmash

2
@chucksmash. Apakah Anda memilih # 5? Bagaimana Anda bisa menerapkan kedua dbs? Alat apa yang Anda gunakan? Jika tidak, mengapa?
xpanta

@chucksmash Masih menunggu umpan balik yang Anda janjikan.
Bhashit Parikh

@chucksmash OP tidak memberikan ... :(
Albert Rothman

Jawaban:


13

Beberapa pemikiran ....

Biasanya seseorang tidak ingin menyimpan informasi yang saling terkait erat dalam sistem yang berbeda. Kemungkinan hal-hal yang keluar dari sinkronisasi adalah signifikan dan sekarang alih-alih satu masalah di tangan Anda, Anda punya dua. Satu hal yang dapat Anda lakukan dengan Mongo adalah menggunakannya untuk menyalurkan data Anda atau data keluar. Preferensi saya adalah menyimpan semuanya dalam PostgreSQL sejauh hal ini dimungkinkan. Namun, saya akan mencatat bahwa melakukan hal itu benar-benar membutuhkan pengetahuan ahli tentang pemrograman PostgreSQL dan bukan untuk toko yang tidak mau mendedikasikan untuk menggunakan fitur-fitur canggih. Saya melihat serangkaian opsi yang agak berbeda dari Anda. Karena preferensi saya bukanlah sesuatu yang saya lihat dalam daftar, saya akan memberikannya kepada Anda.

Anda mungkin dapat memisahkan metadata Anda menjadi data umum, data yang diperlukan untuk kelas, dan data dokumen. Dalam hal ini Anda akan memiliki tabel katalog umum dengan informasi umum dasar ditambah satu tabel per kelas. Dalam tabel ini Anda akan memiliki bidang hstore, json, atau xml yang akan menyimpan sisa data bersama dengan kolom di mana Anda menyimpan data yang harus dibatasi secara signifikan. Ini akan mengurangi apa yang perlu Anda masukkan ke dalam tabel ini per kelas, tetapi akan memungkinkan Anda untuk meningkatkan kendala sesuka Anda. Tiga opsi memiliki masalah yang berbeda dan patut dipertimbangkan secara terpisah:

hstore relatif terbatas tetapi juga digunakan oleh banyak orang. Ini bukan hal yang sangat baru tetapi hanya merupakan penyimpanan kunci / nilai, dan tidak mampu struktur data bersarang, tidak seperti json dan xml.

json cukup baru dan tidak benar-benar melakukan banyak hal saat ini. Ini tidak berarti Anda tidak dapat melakukan banyak hal dengan itu, tetapi Anda tidak akan melakukan banyak hal di luar kotak. Jika Anda melakukannya, Anda dapat berharap untuk melakukan sejumlah besar pemrograman, mungkin dalam plv8js atau, jika Anda ingin tetap menggunakan lingkungan yang lebih lama, plperlu atau plpython. jsonlebih baik didukung di 9,3 meskipun setidaknya dalam snapshot pengembangan saat ini, jadi ketika versi itu dirilis semuanya akan menjadi lebih baik.

xml adalah yang terbaik yang didukung dari ketiganya, dengan fitur terbanyak, dan riwayat dukungan terpanjang. Kemudian lagi, itu adalah XML .....

Namun jika Anda memutuskan untuk pergi bersama-sama dengan Mongo dan PostgreSQL, perhatikan bahwa PostgreSQL mendukung 2 fase commit yang berarti Anda dapat menjalankan operasi penulisan, lalu terbitkan PREPARE TRANSACTIONdan jika ini berhasil, lakukan penulisan atom Anda dalam bahasa Mongo. Jika itu berhasil, Anda dapat melakukannya COMMITdi PostgreSQL.


1
Ini semua adalah saran bagus. Saya telah menyebutkan menggunakan hstore / json sebelumnya (dan diam-diam mendiskon xml, karena, yah, xml) tetapi saya tidak berpikir untuk menggunakannya seperti yang Anda rekomendasikan. Di atas semua ini, saran komit fase 2 Postgres adalah emas. Saya tidak tahu ini ada. Terima kasih atas saran yang bagus.
chucksmash

Komit 2 bertahap benar-benar adalah emas. Itu membuat menggunakan NoSQL bersama-sama sangat layak. Terutama jika data antara 2 DB hanya saling terkait jarang, dan mereka kebanyakan memecahkan masalah yang berbeda
haknick

0

Anda dapat mengatur mesin permintaan seperti Presto atau Dremio untuk bergabung dengan data yang berada di MongoDB dan Postgres dengan satu permintaan. Keduanya memiliki konektor untuk masing-masing database ini (lihat dokumen di sini dan di sini ) dan mengusulkan untuk, masing-masing, menjalankan "SQL on anything" dan "join anything".

Untuk menguji Presto, Anda dapat menggunakan sekelompok kecil di AWS EMR dengan Hadoop, Hive dan Presto (tambahkan rona jika Anda tidak ingin menggunakan baris perintah), itu bekerja dari kotak - pastikan untuk mengikuti petunjuk ini untuk mengatur konektornya . Sarang tidak sepenuhnya diperlukan, tetapi dengan itu, Anda dapat membuat tabel menggunakan hasil dari gabungan antara Mongo dan Postgres (lihat halaman ini untuk contoh). Ada juga versi berbayar di pasar , yang (seharusnya) sangat dioptimalkan, dan memiliki uji coba 30 hari.

Saya belum pernah menggunakan Dremio, tetapi ada juga beberapa cara mudah untuk menyebarkannya di AWS, Azure atau di lokasi. Mereka memiliki beberapa kursus online di situs web mereka , dengan akses ke "lab virtual" yang dapat Anda gunakan untuk mengikuti kelas secara gratis.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.